function save_research_request($ref)
 {
     # Save
     global $baseurl, $email_from, $applicationname, $lang;
     if (getval("delete", "") != "") {
         # Delete this request.
         sql_query("delete from research_request where ref='{$ref}' limit 1");
         return true;
     }
     # Check the status, if changed e-mail the originator
     $oldstatus = sql_value("select status value from research_request where ref='{$ref}'", 0);
     $newstatus = getvalescaped("status", 0);
     $collection = sql_value("select collection value from research_request where ref='{$ref}'", 0);
     $templatevars['url'] = $baseurl . "/?c=" . $collection;
     if ($oldstatus != $newstatus) {
         $email = sql_value("select u.email value from user u,research_request r where u.ref=r.user and r.ref='{$ref}'", "");
         $message = "";
         if ($newstatus == 1) {
             $message = $lang["researchrequestassignedmessage"];
             $subject = $lang["researchrequestassigned"];
             send_mail($email, $applicationname . ": " . $subject, $message, "", "", "emailresearchrequestassigned", $templatevars);
             # Log this
             daily_stat("Assigned research request", 0);
         }
         if ($newstatus == 2) {
             $message = $lang["researchrequestcompletemessage"] . "\n\n" . $lang["clicklinkviewcollection"] . "\n\n" . $templatevars['url'];
             $subject = $lang["researchrequestcomplete"];
             send_mail($email, $applicationname . ": " . $subject, $message, "", "", "emailresearchrequestcomplete", $templatevars);
             # Log this
             daily_stat("Processed research request", 0);
         }
     }
     sql_query("update research_request set status='" . $newstatus . "',assigned_to='" . getvalescaped("assigned_to", 0) . "' where ref='{$ref}'");
     # Copy existing collection
     if (getvalescaped("copyexisting", "") != "" && is_numeric($collection)) {
         sql_query("insert into collection_resource(collection,resource) select '{$collection}',resource from collection_resource where collection='" . getvalescaped("copyexistingref", "") . "' and resource not in (select resource from collection_resource where collection='{$collection}');");
     }
 }
function copy_resource($from, $resource_type = -1)
{
    # Create a new resource, copying all data from the resource with reference $from.
    # Note this copies only the data and not any attached file. It's very unlikely the
    # same file would be in the system twice, however users may want to clone an existing resource
    # to avoid reentering data if the resource is very similar.
    # If $resource_type if specified then the resource type for the new resource will be set to $resource_type
    # rather than simply copied from the $from resource.
    # Check that the resource exists
    if (sql_value("select count(*) value from resource where ref='{$from}'", 0) == 0) {
        return false;
    }
    # copy joined fields to the resource column
    $joins = get_resource_table_joins();
    // Filter the joined columns so we only have the ones relevant to this resource type
    $query = sprintf('
			    SELECT rtf.ref AS value
			      FROM resource_type_field AS rtf
			INNER JOIN resource AS r ON (rtf.resource_type != r.resource_type AND rtf.resource_type != 0)
			     WHERE r.ref = "%s";
		', $from);
    $irrelevant_rtype_fields = sql_array($query);
    $irrelevant_rtype_fields = array_values(array_intersect($joins, $irrelevant_rtype_fields));
    $filtered_joins = array_values(array_diff($joins, $irrelevant_rtype_fields));
    $joins_sql = "";
    foreach ($filtered_joins as $join) {
        $joins_sql .= ",field{$join} ";
    }
    $add = "";
    # Determine if the user has access to the template archive status
    $archive = sql_value("select archive value from resource where ref='{$from}'", 0);
    if (!checkperm("e" . $archive)) {
        # Find the right permission mode to use
        for ($n = -2; $n < 3; $n++) {
            if (checkperm("e" . $n)) {
                $archive = $n;
                break;
            }
        }
    }
    # First copy the resources row
    sql_query("insert into resource({$add} resource_type,creation_date,rating,archive,access,created_by {$joins_sql}) select {$add}" . ($resource_type == -1 ? "resource_type" : "'" . $resource_type . "'") . ",now(),rating,'" . $archive . "',access,created_by {$joins_sql} from resource where ref='{$from}';");
    $to = sql_insert_id();
    # Set that this resource was created by this user.
    # This needs to be done if either:
    # 1) The user does not have direct 'resource create' permissions and is therefore contributing using My Contributions directly into the active state
    # 2) The user is contributiting via My Contributions to the standard User Contributed pre-active states.
    global $userref;
    global $always_record_resource_creator;
    if (!checkperm("c") || $archive < 0 || isset($always_record_resource_creator) && $always_record_resource_creator) {
        # Update the user record
        sql_query("update resource set created_by='{$userref}' where ref='{$to}'");
        # Also add the user's username and full name to the keywords index so the resource is searchable using this name.
        global $username, $userfullname;
        add_keyword_mappings($to, $username . " " . $userfullname, -1);
    }
    # Now copy all data
    sql_query("insert into resource_data(resource,resource_type_field,value) select '{$to}',rd.resource_type_field,rd.value from resource_data rd join resource r on rd.resource=r.ref join resource_type_field rtf on rd.resource_type_field=rtf.ref and (rtf.resource_type=r.resource_type or rtf.resource_type=999 or rtf.resource_type=0) where rd.resource='{$from}'");
    # Copy relationships
    sql_query("insert into resource_related(resource,related) select '{$to}',related from resource_related where resource='{$from}'");
    # Copy access
    sql_query("insert into resource_custom_access(resource,usergroup,access) select '{$to}',usergroup,access from resource_custom_access where resource='{$from}'");
    # Set any resource defaults
    set_resource_defaults($to);
    # Autocomplete any blank fields.
    autocomplete_blank_fields($to);
    # Reindex the resource so the resource_keyword entries are created
    reindex_resource($to);
    # Copying a resource of the 'pending review' state? Notify, if configured.
    global $send_collection_to_admin;
    if ($archive == -1 && !$send_collection_to_admin) {
        notify_user_contributed_submitted(array($to));
    }
    # Log this
    daily_stat("Create resource", $to);
    resource_log($to, 'c', 0);
    hook("afternewresource", "", array($to));
    return $to;
}
예제 #3
0
        hook("preremovesearch");
        #remove saved search
        remove_saved_search($usercollection,$removesearch);
        hook("postremovesearch");
        }
	}
	
$addsmartcollection=getvalescaped("addsmartcollection",-1);
if ($addsmartcollection!=-1)
	{
	
	# add collection which autopopulates with a saved search 
	add_smart_collection();
		
	# Log this
	daily_stat("Added smart collection",0);	
	}
	
$research=getvalescaped("research","");
if ($research!="")
	{
	hook("preresearch");
	$col=get_research_request_collection($research);
	if ($col==false)
		{
		$rr=get_research_request($research);
		$name="Research: " . $rr["name"];  # Do not translate this string, the collection name is translated when displayed!
		$new=create_collection ($rr["user"],$name,1);
		set_user_collection($userref,$new);
		set_research_collection($research,$new);
		}
 function do_search($search, $restypes = "", $order_by = "relevance", $archive = 0, $fetchrows = -1, $sort = "desc", $access_override = false, $starsearch = 0, $ignore_filters = false, $return_disk_usage = false, $recent_search_daylimit = "", $go = false, $stats_logging = true)
 {
     debug("search={$search} {$go} {$fetchrows} restypes={$restypes} archive={$archive} daylimit={$recent_search_daylimit}");
     # globals needed for hooks
     global $sql, $order, $select, $sql_join, $sql_filter, $orig_order, $collections_omit_archived, $search_sql_double_pass_mode, $usergroup, $search_filter_strict, $default_sort;
     $alternativeresults = hook("alternativeresults", "", array($go));
     if ($alternativeresults) {
         return $alternativeresults;
     }
     $modifyfetchrows = hook("modifyfetchrows", "", array($fetchrows));
     if ($modifyfetchrows) {
         $fetchrows = $modifyfetchrows;
     }
     # Takes a search string $search, as provided by the user, and returns a results set
     # of matching resources.
     # If there are no matches, instead returns an array of suggested searches.
     # $restypes is optionally used to specify which resource types to search.
     # $access_override is used by smart collections, so that all all applicable resources can be judged regardless of the final access-based results
     # Check valid sort
     if (!in_array(strtolower($sort), array("asc", "desc"))) {
         $sort = "asc";
     }
     # resolve $order_by to something meaningful in sql
     $orig_order = $order_by;
     global $date_field;
     $order = array("relevance" => "score {$sort}, user_rating {$sort}, hit_count {$sort}, field{$date_field} {$sort},r.ref {$sort}", "popularity" => "user_rating {$sort},hit_count {$sort},field{$date_field} {$sort},r.ref {$sort}", "rating" => "r.rating {$sort}, user_rating {$sort}, score {$sort},r.ref {$sort}", "date" => "field{$date_field} {$sort},r.ref {$sort}", "colour" => "has_image {$sort},image_blue {$sort},image_green {$sort},image_red {$sort},field{$date_field} {$sort},r.ref {$sort}", "country" => "country {$sort},r.ref {$sort}", "title" => "title {$sort},r.ref {$sort}", "file_path" => "file_path {$sort},r.ref {$sort}", "resourceid" => "r.ref {$sort}", "resourcetype" => "resource_type {$sort},r.ref {$sort}", "titleandcountry" => "title {$sort},country {$sort}", "random" => "RAND()", "status" => "archive {$sort}");
     if (!in_array($order_by, $order) && substr($order_by, 0, 5) == "field") {
         if (!is_numeric(str_replace("field", "", $order_by))) {
             exit("Order field incorrect.");
         }
         $order[$order_by] = "{$order_by} {$sort}";
     }
     hook("modifyorderarray");
     # Recognise a quoted search, which is a search for an exact string
     global $quoted_string;
     $quoted_string = false;
     if (substr($search, 0, 1) == "\"" && substr($search, -1, 1) == "\"") {
         $quoted_string = true;
         $search = substr($search, 1, -1);
     }
     $order_by = $order[$order_by];
     $keywords = split_keywords($search);
     foreach (get_indexed_resource_type_fields() as $resource_type_field) {
         add_verbatim_keywords($keywords, $search, $resource_type_field, true);
         // add any regex matched verbatim keywords for those indexed resource type fields
     }
     $search = trim($search);
     # Dedupe keywords (not for quoted strings as the user may be looking for the same word multiple times together in this instance)
     if (!$quoted_string) {
         $keywords = array_values(array_unique($keywords));
     }
     $modified_keywords = hook('dosearchmodifykeywords', '', array($keywords));
     if ($modified_keywords) {
         $keywords = $modified_keywords;
     }
     # -- Build up filter SQL that will be used for all queries
     $sql_filter = search_filter($search, $archive, $restypes, $starsearch, $recent_search_daylimit, $access_override, $return_disk_usage);
     # Initialise variables.
     $sql = "";
     $sql_keyword_union_whichkeys = array();
     $sql_keyword_union = array();
     $sql_keyword_union_aggregation = array();
     $sql_keyword_union_criteria = array();
     $sql_keyword_union_sub_query = array();
     # If returning disk used by the resources in the search results ($return_disk_usage=true) then wrap the returned SQL in an outer query that sums disk usage.
     $sql_prefix = "";
     $sql_suffix = "";
     if ($return_disk_usage) {
         $sql_prefix = "select sum(disk_usage) total_disk_usage,count(*) total_resources from (";
         $sql_suffix = ") resourcelist";
     }
     # ------ Advanced 'custom' permissions, need to join to access table.
     $sql_join = "";
     global $k;
     if (!checkperm("v") && !$access_override) {
         global $usergroup;
         global $userref;
         # one extra join (rca2) is required for user specific permissions (enabling more intelligent watermarks in search view)
         # the original join is used to gather group access into the search query as well.
         $sql_join = " left outer join resource_custom_access rca2 on r.ref=rca2.resource and rca2.user='******'  and (rca2.user_expires is null or rca2.user_expires>now()) and rca2.access<>2  ";
         $sql_join .= " left outer join resource_custom_access rca on r.ref=rca.resource and rca.usergroup='{$usergroup}' and rca.access<>2 ";
         if ($sql_filter != "") {
             $sql_filter .= " and ";
         }
         # If rca.resource is null, then no matching custom access record was found
         # If r.access is also 3 (custom) then the user is not allowed access to this resource.
         # Note that it's normal for null to be returned if this is a resource with non custom permissions (r.access<>3).
         $sql_filter .= " not(rca.resource is null and r.access=3)";
     }
     # Join thumbs_display_fields to resource table
     $select = "r.ref, r.resource_type, r.has_image, r.is_transcoding, r.hit_count, r.creation_date, r.rating, r.user_rating, r.user_rating_count, r.user_rating_total, r.file_extension, r.preview_extension, r.image_red, r.image_green, r.image_blue, r.thumb_width, r.thumb_height, r.archive, r.access, r.colour_key, r.created_by, r.file_modified, r.file_checksum, r.request_count, r.new_hit_count, r.expiry_notification_sent, r.preview_tweaks, r.file_path ";
     $modified_select = hook("modifyselect");
     if ($modified_select) {
         $select .= $modified_select;
     }
     $modified_select2 = hook("modifyselect2");
     if ($modified_select2) {
         $select .= $modified_select2;
     }
     # Return disk usage for each resource if returning sum of disk usage.
     if ($return_disk_usage) {
         $select .= ",r.disk_usage";
     }
     # select group and user access rights if available, otherwise select null values so columns can still be used regardless
     # this makes group and user specific access available in the basic search query, which can then be passed through access functions
     # in order to eliminate many single queries.
     if (!checkperm("v") && !$access_override) {
         $select .= ",rca.access group_access,rca2.access user_access ";
     } else {
         $select .= ",null group_access, null user_access ";
     }
     # add 'joins' to select (adding them
     $joins = get_resource_table_joins();
     foreach ($joins as $datajoin) {
         $select .= ",r.field" . $datajoin . " ";
     }
     # Prepare SQL to add join table for all provided keywods
     $suggested = $keywords;
     # a suggested search
     $fullmatch = true;
     $c = 0;
     $t = "";
     $t2 = "";
     $score = "";
     $skipped_last = false;
     $keysearch = true;
     # Do not process if a numeric search is provided (resource ID)
     global $config_search_for_number, $category_tree_search_use_and;
     if ($config_search_for_number && is_numeric($search)) {
         $keysearch = false;
     }
     # Fetch a list of fields that are not available to the user - these must be omitted from the search.
     $hidden_indexed_fields = get_hidden_indexed_fields();
     # This is a performance enhancement that will discard any keyword matches for fields that are not supposed to be indexed.
     $sql_restrict_by_field_types = "";
     global $search_sql_force_field_index_check;
     if (isset($search_sql_force_field_index_check) && $search_sql_force_field_index_check && $restypes != "") {
         $sql_restrict_by_field_types = sql_value("select group_concat(ref) as value from resource_type_field where keywords_index=1 and resource_type in ({$restypes})", "");
         if ($sql_restrict_by_field_types != "") {
             $sql_restrict_by_field_types = "-1," . $sql_restrict_by_field_types;
             // -1 needed for global search
         }
     }
     if ($keysearch) {
         for ($n = 0; $n < count($keywords); $n++) {
             $keyword = $keywords[$n];
             if (substr($keyword, 0, 1) != "!" || substr($keyword, 0, 6) == "!empty") {
                 global $date_field;
                 $field = 0;
                 #echo "<li>$keyword<br/>";
                 if (strpos($keyword, ":") !== false && !$ignore_filters) {
                     $kw = explode(":", $keyword, 2);
                     global $datefieldinfo_cache;
                     if (isset($datefieldinfo_cache[$kw[0]])) {
                         $datefieldinfo = $datefieldinfo_cache[$kw[0]];
                     } else {
                         $datefieldinfo = sql_query("select ref from resource_type_field where name='" . escape_check($kw[0]) . "' and type IN (4,6,10)", 0);
                         $datefieldinfo_cache[$kw[0]] = $datefieldinfo;
                     }
                     if (count($datefieldinfo) && substr($kw[1], 0, 5) != "range") {
                         $c++;
                         $datefieldinfo = $datefieldinfo[0];
                         $datefield = $datefieldinfo["ref"];
                         if ($sql_filter != "") {
                             $sql_filter .= " and ";
                         }
                         $val = str_replace("n", "_", $kw[1]);
                         $val = str_replace("|", "-", $val);
                         $sql_filter .= "rd" . $c . ".value like '" . $val . "%' ";
                         $sql_join .= " join resource_data rd" . $c . " on rd" . $c . ".resource=r.ref and rd" . $c . ".resource_type_field='" . $datefield . "'";
                     } elseif ($kw[0] == "day") {
                         if ($sql_filter != "") {
                             $sql_filter .= " and ";
                         }
                         $sql_filter .= "r.field{$date_field} like '____-__-" . $kw[1] . "%' ";
                     } elseif ($kw[0] == "month") {
                         if ($sql_filter != "") {
                             $sql_filter .= " and ";
                         }
                         $sql_filter .= "r.field{$date_field} like '____-" . $kw[1] . "%' ";
                     } elseif ($kw[0] == "year") {
                         if ($sql_filter != "") {
                             $sql_filter .= " and ";
                         }
                         $sql_filter .= "r.field{$date_field} like '" . $kw[1] . "%' ";
                     } elseif ($kw[0] == "startdate") {
                         if ($sql_filter != "") {
                             $sql_filter .= " and ";
                         }
                         $sql_filter .= "r.field{$date_field} >= '" . $kw[1] . "' ";
                     } elseif ($kw[0] == "enddate") {
                         if ($sql_filter != "") {
                             $sql_filter .= " and ";
                         }
                         $sql_filter .= "r.field{$date_field} <= '" . $kw[1] . " 23:59:59' ";
                     } elseif (count($datefieldinfo) && substr($kw[1], 0, 5) == "range") {
                         $c++;
                         $rangefield = $datefieldinfo[0]["ref"];
                         $daterange = false;
                         $rangestring = substr($kw[1], 5);
                         if (strpos($rangestring, "start") !== FALSE) {
                             $rangestart = str_replace(" ", "-", $rangestring);
                             if ($sql_filter != "") {
                                 $sql_filter .= " and ";
                             }
                             $sql_filter .= "rd" . $c . ".value >= '" . substr($rangestart, strpos($rangestart, "start") + 5, 10) . "'";
                         }
                         if (strpos($kw[1], "end") !== FALSE) {
                             $rangeend = str_replace(" ", "-", $rangestring);
                             if ($sql_filter != "") {
                                 $sql_filter .= " and ";
                             }
                             $sql_filter .= "rd" . $c . ".value <= '" . substr($rangeend, strpos($rangeend, "end") + 3, 10) . " 23:59:59'";
                         }
                         $sql_join .= " join resource_data rd" . $c . " on rd" . $c . ".resource=r.ref and rd" . $c . ".resource_type_field='" . $rangefield . "'";
                     } elseif (!hook('customsearchkeywordfilter', null, array($kw))) {
                         $ckeywords = explode(";", $kw[1]);
                         # Fetch field info
                         global $fieldinfo_cache;
                         if (isset($fieldinfo_cache[$kw[0]])) {
                             $fieldinfo = $fieldinfo_cache[$kw[0]];
                         } else {
                             $fieldinfo = sql_query("select ref,type from resource_type_field where name='" . escape_check($kw[0]) . "'", 0);
                             $fieldinfo_cache[$kw[0]] = $fieldinfo;
                         }
                         if (count($fieldinfo) == 0) {
                             debug("Field short name not found.");
                             return false;
                         }
                         # Create an array of matching field IDs.
                         $fields = array();
                         foreach ($fieldinfo as $fi) {
                             if (in_array($fi["ref"], $hidden_indexed_fields)) {
                                 # Attempt to directly search field that the user does not have access to.
                                 return false;
                             }
                             # Add to search array
                             $fields[] = $fi["ref"];
                         }
                         # Special handling for dates
                         if ($fieldinfo[0]["type"] == 4 || $fieldinfo[0]["type"] == 6 || $fieldinfo[0]["type"] == 10) {
                             $ckeywords = array(str_replace(" ", "-", $kw[1]));
                         }
                         #special SQL generation for category trees to use AND instead of OR
                         if ($fieldinfo[0]["type"] == 7 && $category_tree_search_use_and) {
                             for ($m = 0; $m < count($ckeywords); $m++) {
                                 $keyref = resolve_keyword($ckeywords[$m]);
                                 if (!($keyref === false)) {
                                     $c++;
                                     # Add related keywords
                                     $related = get_related_keywords($keyref);
                                     $relatedsql = "";
                                     for ($r = 0; $r < count($related); $r++) {
                                         $relatedsql .= " or k" . $c . ".keyword='" . $related[$r] . "'";
                                     }
                                     # Form join
                                     $sql_join .= " join resource_keyword k" . $c . " on k" . $c . ".resource=r.ref and k" . $c . ".resource_type_field in ('" . join("','", $fields) . "') and (k" . $c . ".keyword='{$keyref}' {$relatedsql})";
                                     if ($score != "") {
                                         $score .= "+";
                                     }
                                     $score .= "k" . $c . ".hit_count";
                                     # Log this
                                     if ($stats_logging) {
                                         daily_stat("Keyword usage", $keyref);
                                     }
                                 }
                             }
                         } else {
                             $c++;
                             # work through all options in an OR approach for multiple selects on the same field
                             $searchkeys = array();
                             for ($m = 0; $m < count($ckeywords); $m++) {
                                 $keyref = resolve_keyword($ckeywords[$m]);
                                 if ($keyref === false) {
                                     $keyref = -1;
                                 }
                                 $searchkeys[] = $keyref;
                                 # Also add related.
                                 $related = get_related_keywords($keyref);
                                 for ($o = 0; $o < count($related); $o++) {
                                     $searchkeys[] = $related[$o];
                                 }
                                 # Log this
                                 if ($stats_logging) {
                                     daily_stat("Keyword usage", $keyref);
                                 }
                             }
                             $union = "select resource,";
                             for ($p = 1; $p <= count($keywords); $p++) {
                                 if ($p == $c) {
                                     $union .= "true";
                                 } else {
                                     $union .= "false";
                                 }
                                 $union .= " as keyword_" . $p . "_found,";
                             }
                             $union .= "hit_count as score from resource_keyword k" . $c . " where (k" . $c . ".keyword='{$keyref}' or k" . $c . ".keyword in ('" . join("','", $searchkeys) . "')) and k" . $c . ".resource_type_field in ('" . join("','", $fields) . "')";
                             if (!empty($sql_exclude_fields)) {
                                 $union .= " and k" . $c . ".resource_type_field not in (" . $sql_exclude_fields . ")";
                             }
                             if (count($hidden_indexed_fields) > 0) {
                                 $union .= " and k" . $c . ".resource_type_field not in ('" . join("','", $hidden_indexed_fields) . "')";
                             }
                             $sql_keyword_union_aggregation[] = "bit_or(keyword_" . $c . "_found) as keyword_" . $c . "_found";
                             $sql_keyword_union_criteria[] = "h.keyword_" . $c . "_found";
                             $sql_keyword_union[] = $union;
                         }
                     }
                 } else {
                     # Normal keyword (not tied to a field) - searches all fields that the user has access to
                     # If ignoring field specifications then remove them.
                     if (strpos($keyword, ":") !== false && $ignore_filters) {
                         $s = explode(":", $keyword);
                         $keyword = $s[1];
                     }
                     # Omit resources containing this keyword?
                     $omit = false;
                     if (substr($keyword, 0, 1) == "-") {
                         $omit = true;
                         $keyword = substr($keyword, 1);
                     }
                     # Search for resources with an empty field, ex: !empty18  or  !emptycaption
                     $empty = false;
                     if (substr($keyword, 0, 6) == "!empty") {
                         $nodatafield = str_replace("!empty", "", $keyword);
                         if (!is_numeric($nodatafield)) {
                             $nodatafield = sql_value("select ref value from resource_type_field where name='" . escape_check($nodatafield) . "'", "");
                         }
                         if ($nodatafield == "" || !is_numeric($nodatafield)) {
                             exit('invalid !empty search');
                         }
                         $empty = true;
                     }
                     global $noadd, $wildcard_always_applied;
                     if (in_array($keyword, $noadd)) {
                         $skipped_last = true;
                     } else {
                         # Handle wildcards
                         $wildcards = array();
                         if (strpos($keyword, "*") !== false || $wildcard_always_applied) {
                             if ($wildcard_always_applied && strpos($keyword, "*") === false) {
                                 # Suffix asterisk if none supplied and using $wildcard_always_applied mode.
                                 $keyword = $keyword . "*";
                             }
                             # Keyword contains a wildcard. Expand.
                             global $wildcard_expand_limit;
                             $wildcards = sql_array("select ref value from keyword where keyword like '" . escape_check(str_replace("*", "%", $keyword)) . "' order by hit_count desc limit " . $wildcard_expand_limit);
                         }
                         $keyref = resolve_keyword(str_replace('*', '', $keyword));
                         # Resolve keyword. Ignore any wildcards when resolving. We need wildcards to be present later but not here.
                         if ($keyref === false && !$omit && !$empty && count($wildcards) == 0) {
                             $fullmatch = false;
                             $soundex = resolve_soundex($keyword);
                             if ($soundex === false) {
                                 # No keyword match, and no keywords sound like this word. Suggest dropping this word.
                                 $suggested[$n] = "";
                             } else {
                                 # No keyword match, but there's a word that sounds like this word. Suggest this word instead.
                                 $suggested[$n] = "<i>" . $soundex . "</i>";
                             }
                         } else {
                             if ($keyref === false) {
                                 # make a new keyword
                                 $keyref = resolve_keyword(str_replace('*', '', $keyword), true);
                             }
                             # Key match, add to query.
                             $c++;
                             $relatedsql = "";
                             if (!$quoted_string) {
                                 # Add related keywords
                                 $related = get_related_keywords($keyref);
                                 # Merge wildcard expansion with related keywords
                                 $related = array_merge($related, $wildcards);
                                 if (count($related) > 0) {
                                     $relatedsql = " or k" . $c . ".keyword IN ('" . join("','", $related) . "')";
                                 }
                             }
                             # Form join
                             $sql_exclude_fields = hook("excludefieldsfromkeywordsearch");
                             if (!$omit) {
                                 # Include in query
                                 // --------------------------------------------------------------------------------
                                 // Start of normal union for resource keywords
                                 // --------------------------------------------------------------------------------
                                 // add false for keyword matches other than the current one
                                 $bit_or_condition = "";
                                 for ($p = 1; $p <= count($keywords); $p++) {
                                     if ($p == $c) {
                                         $bit_or_condition .= "true";
                                     } else {
                                         $bit_or_condition .= "false";
                                     }
                                     $bit_or_condition .= " as keyword_" . $p . "_found,";
                                 }
                                 // these restrictions apply to both !empty searches as well as normal keyword searches (i.e. both branches of next if statement)
                                 $union_restriction_clause = "";
                                 if (!empty($sql_exclude_fields)) {
                                     $union_restriction_clause .= " and k" . $c . ".resource_type_field not in (" . $sql_exclude_fields . ")";
                                 }
                                 if (count($hidden_indexed_fields) > 0) {
                                     $union_restriction_clause .= " and k" . $c . ".resource_type_field not in ('" . join("','", $hidden_indexed_fields) . "')";
                                 }
                                 if ($empty) {
                                     $rtype = sql_value("select resource_type value from resource_type_field where ref='{$nodatafield}'", 0);
                                     if ($rtype != 0) {
                                         if ($rtype == 999) {
                                             $restypesql = "and (r" . $c . ".archive=1 or r" . $c . ".archive=2) and ";
                                             if ($sql_filter != "") {
                                                 $sql_filter .= " and ";
                                             }
                                             $sql_filter .= str_replace("r" . $c . ".archive='0'", "(r" . $c . ".archive=1 or r" . $c . ".archive=2)", $sql_filter);
                                         } else {
                                             $restypesql = "and r" . $c . ".resource_type ='{$rtype}' ";
                                         }
                                     } else {
                                         $restypesql = "";
                                     }
                                     $union = "select ref as resource, {$bit_or_condition} 1 as score from resource r" . $c . " left outer join resource_data rd" . $c . " on r" . $c . ".ref=rd" . $c . ".resource and rd" . $c . ".resource_type_field='{$nodatafield}' where  (rd" . $c . ".value ='' or rd" . $c . ".value is null or rd" . $c . ".value=',') {$restypesql}  and r" . $c . ".ref>0 group by r" . $c . ".ref ";
                                     $union .= $union_restriction_clause;
                                     $sql_keyword_union[] = $union;
                                 } else {
                                     $filter_by_resource_field_type = "";
                                     if ($sql_restrict_by_field_types != "") {
                                         $filter_by_resource_field_type = "and k{$c}.resource_type_field in ({$sql_restrict_by_field_types})";
                                         // -1 needed for global search
                                     }
                                     $union = "SELECT resource, {$bit_or_condition} SUM(hit_count) AS score FROM resource_keyword k{$c}\n\t\t\t\t\t\t\t\t\tWHERE (k{$c}.keyword={$keyref} {$filter_by_resource_field_type} {$relatedsql} {$union_restriction_clause})\n\t\t\t\t\t\t\t\t\tGROUP BY resource";
                                     $sql_keyword_union[] = $union;
                                 }
                                 $sql_keyword_union_aggregation[] = "bit_or(keyword_" . $c . "_found) as keyword_" . $c . "_found";
                                 $sql_keyword_union_criteria[] = "h.keyword_" . $c . "_found";
                                 // --------------------------------------------------------------------------------
                                 # Quoted search? Also add a specific join to check that the positions add up.
                                 # The UNION / bit_or() approach doesn't support position checking hence the need for additional joins to do this.
                                 if ($quoted_string) {
                                     $sql_join .= " join resource_keyword qrk_{$c} on qrk_{$c}.resource=r.ref and qrk_{$c}.keyword='{$keyref}' ";
                                     # Exclude fields from the quoted search join also
                                     if (!empty($sql_exclude_fields)) {
                                         $sql_join .= " and qrk_" . $c . ".resource_type_field not in (" . $sql_exclude_fields . ")";
                                     }
                                     if (count($hidden_indexed_fields) > 0) {
                                         $sql_join .= " and qrk_" . $c . ".resource_type_field not in ('" . join("','", $hidden_indexed_fields) . "')";
                                     }
                                     # For keywords other than the first one, check the position is next to the previous keyword.
                                     if ($c > 1) {
                                         $last_key_offset = 1;
                                         if (isset($skipped_last) && $skipped_last) {
                                             $last_key_offset = 2;
                                         }
                                         # Support skipped keywords - if the last keyword was skipped (listed in $noadd), increase the allowed position from the previous keyword. Useful for quoted searches that contain $noadd words, e.g. "black and white" where "and" is a skipped keyword.
                                         # Also check these occurances are within the same field.
                                         $sql_join .= " and qrk_" . $c . ".position>0 and qrk_" . $c . ".position=qrk_" . ($c - 1) . ".position+" . $last_key_offset . " and qrk_" . $c . ".resource_type_field=qrk_" . ($c - 1) . ".resource_type_field";
                                     }
                                 }
                             } else {
                                 if ($omit) {
                                     # Exclude matching resources from query (omit feature)
                                     if ($sql_filter != "") {
                                         $sql_filter .= " and ";
                                     }
                                     $sql_filter .= "r.ref not in (select resource from resource_keyword where keyword='{$keyref}')";
                                     # Filter out resources that do contain the keyword.
                                 }
                             }
                             # Log this
                             if ($stats_logging) {
                                 daily_stat("Keyword usage", $keyref);
                             }
                         }
                     }
                     $skipped_last = false;
                 }
             }
         }
     }
     # Could not match on provided keywords? Attempt to return some suggestions.
     if ($fullmatch == false) {
         if ($suggested == $keywords) {
             # Nothing different to suggest.
             debug("No alternative keywords to suggest.");
             return "";
         } else {
             # Suggest alternative spellings/sound-a-likes
             $suggest = "";
             if (strpos($search, ",") === false) {
                 $suggestjoin = " ";
             } else {
                 $suggestjoin = ", ";
             }
             for ($n = 0; $n < count($suggested); $n++) {
                 if ($suggested[$n] != "") {
                     if ($suggest != "") {
                         $suggest .= $suggestjoin;
                     }
                     $suggest .= $suggested[$n];
                 }
             }
             debug("Suggesting {$suggest}");
             return $suggest;
         }
     }
     hook("additionalsqlfilter");
     hook("parametricsqlfilter", '', array($search));
     # ------ Search filtering: If search_filter is specified on the user group, then we must always apply this filter.
     global $usersearchfilter;
     $sf = explode(";", $usersearchfilter);
     if (strlen($usersearchfilter) > 0) {
         for ($n = 0; $n < count($sf); $n++) {
             $s = explode("=", $sf[$n]);
             if (count($s) != 2) {
                 exit("Search filter is not correctly configured for this user group.");
             }
             # Support for "NOT" matching. Return results only where the specified value or values are NOT set.
             $filterfield = $s[0];
             $filter_not = false;
             if (substr($filterfield, -1) == "!") {
                 $filter_not = true;
                 $filterfield = substr($filterfield, 0, -1);
                 # Strip off the exclamation mark.
             }
             # Support for multiple fields on the left hand side, pipe separated - allows OR matching across multiple fields in a basic way
             $filterfields = explode("|", escape_check($filterfield));
             # Find field(s) - multiple fields can be returned to support several fields with the same name.
             $f = sql_array("select ref value from resource_type_field where name in ('" . join("','", $filterfields) . "')");
             if (count($f) == 0) {
                 exit("Field(s) with short name '" . $filterfield . "' not found in user group search filter.");
             }
             # Find keyword(s)
             $ks = explode("|", strtolower(escape_check($s[1])));
             for ($x = 0; $x < count($ks); $x++) {
                 # Cleanse the string as keywords are stored without special characters
                 $ks[$x] = cleanse_string($ks[$x], true);
                 global $stemming;
                 if ($stemming && function_exists("GetStem")) {
                     $ks[$x] = GetStem($ks[$x]);
                 }
             }
             $modifiedsearchfilter = hook("modifysearchfilter");
             if ($modifiedsearchfilter) {
                 $ks = $modifiedsearchfilter;
             }
             $kw = sql_array("select ref value from keyword where keyword in ('" . join("','", $ks) . "')");
             if (!$filter_not) {
                 # Standard operation ('=' syntax)
                 $sql_join .= " join resource_keyword filter" . $n . " on r.ref=filter" . $n . ".resource and filter" . $n . ".resource_type_field in ('" . join("','", $f) . "') and ((filter" . $n . ".keyword in ('" . join("','", $kw) . "')) ";
                 # Option for custom access to override search filters.
                 # For this resource, if custom access has been granted for the user or group, nullify the search filter for this particular resource effectively selecting "true".
                 global $custom_access_overrides_search_filter;
                 if (!checkperm("v") && !$access_override && $custom_access_overrides_search_filter) {
                     $sql_join .= "or ((rca.access is not null and rca.access<>2) or (rca2.access is not null and rca2.access<>2))";
                 }
                 $sql_join .= ")";
                 if ($search_filter_strict > 1) {
                     $sql_join .= " join resource_data dfilter" . $n . " on r.ref=dfilter" . $n . ".resource and dfilter" . $n . ".resource_type_field in ('" . join("','", $f) . "') and (find_in_set('" . join("', dfilter" . $n . ".value) or find_in_set('", explode("|", escape_check($s[1]))) . "', dfilter" . $n . ".value))";
                 }
             } else {
                 # Inverted NOT operation ('!=' syntax)
                 if ($sql_filter != "") {
                     $sql_filter .= " and ";
                 }
                 $sql_filter .= "((r.ref not in (select resource from resource_keyword where resource_type_field in ('" . join("','", $f) . "') and keyword in ('" . join("','", $kw) . "'))) ";
                 # Filter out resources that do contain the keyword(s)
                 # Option for custom access to override search filters.
                 # For this resource, if custom access has been granted for the user or group, nullify the search filter for this particular resource effectively selecting "true".
                 global $custom_access_overrides_search_filter;
                 if (!checkperm("v") && !$access_override && $custom_access_overrides_search_filter) {
                     $sql_filter .= "or ((rca.access is not null and rca.access<>2) or (rca2.access is not null and rca2.access<>2))";
                 }
                 $sql_filter .= ")";
             }
         }
     }
     $userownfilter = hook("userownfilter");
     if ($userownfilter) {
         $sql_join .= $userownfilter;
     }
     # Handle numeric searches when $config_search_for_number=false, i.e. perform a normal search but include matches for resource ID first
     global $config_search_for_number;
     if (!$config_search_for_number && is_numeric($search)) {
         # Always show exact resource matches first.
         $order_by = "(r.ref='" . $search . "') desc," . $order_by;
     }
     # ---------------------------------------------------------------
     # Keyword union assembly.
     # Use UNIONs for keyword matching instead of the older JOIN technique - much faster
     # Assemble the new join from the stored unions
     # ---------------------------------------------------------------
     if (count($sql_keyword_union) > 0) {
         $sql_join .= " join (\n\t\tselect resource,sum(score) as score,\n\t\t" . join(", ", $sql_keyword_union_aggregation) . " from\n\t\t(" . join(" union ", $sql_keyword_union) . ") as hits group by resource) as h on h.resource=r.ref ";
         if ($sql_filter != "") {
             $sql_filter .= " and ";
         }
         $sql_filter .= join(" and ", $sql_keyword_union_criteria);
         # Use amalgamated resource_keyword hitcounts for scoring (relevance matching based on previous user activity)
         $score = "h.score";
     }
     # Can only search for resources that belong to themes
     if (checkperm("J")) {
         $sql_join = " join collection_resource jcr on jcr.resource=r.ref join collection jc on jcr.collection=jc.ref and length(jc.theme)>0 " . $sql_join;
     }
     # --------------------------------------------------------------------------------
     # Special Searches (start with an exclamation mark)
     # --------------------------------------------------------------------------------
     $special_results = search_special($search, $sql_join, $fetchrows, $sql_prefix, $sql_suffix, $order_by, $orig_order, $select, $sql_filter, $archive, $return_disk_usage);
     if ($special_results !== false) {
         return $special_results;
     }
     # -------------------------------------------------------------------------------------
     # Standard Searches
     # -------------------------------------------------------------------------------------
     # We've reached this far without returning.
     # This must be a standard (non-special) search.
     # Construct and perform the standard search query.
     #$sql="";
     if ($sql_filter != "") {
         if ($sql != "") {
             $sql .= " and ";
         }
         $sql .= $sql_filter;
     }
     # Append custom permissions
     $t .= $sql_join;
     if ($score == "") {
         $score = "r.hit_count";
     }
     # In case score hasn't been set (i.e. empty search)
     global $max_results;
     if ($t2 != "" && $sql != "") {
         $sql = " and " . $sql;
     }
     # Compile final SQL
     # Performance enhancement - set return limit to number of rows required
     if ($search_sql_double_pass_mode && $fetchrows != -1) {
         $max_results = $fetchrows;
     }
     $results_sql = $sql_prefix . "select distinct {$score} score, {$select} from resource r" . $t . "  where {$t2} {$sql} group by r.ref order by {$order_by} limit {$max_results}" . $sql_suffix;
     # Debug
     debug('$results_sql=' . $results_sql);
     # Execute query
     $result = sql_query($results_sql, false, $fetchrows);
     # Performance improvement - perform a second count-only query and pad the result array as necessary
     if ($search_sql_double_pass_mode && count($result) >= $max_results) {
         $count_sql = "select count(distinct r.ref) value from resource r" . $t . "  where {$t2} {$sql}";
         $count = sql_value($count_sql, 0);
         $result = array_pad($result, $count, 0);
     }
     debug("Search found " . count($result) . " results");
     if (count($result) > 0) {
         hook("beforereturnresults", "", array($result, $archive));
         return $result;
     }
     hook('zero_search_results');
     # (temp) - no suggestion for field-specific searching for now - TO DO: modify function below to support this
     if (strpos($search, ":") !== false) {
         return "";
     }
     # All keywords resolved OK, but there were no matches
     # Remove keywords, least used first, until we get results.
     $lsql = "";
     $omitmatch = false;
     for ($n = 0; $n < count($keywords); $n++) {
         if (substr($keywords[$n], 0, 1) == "-") {
             $omitmatch = true;
             $omit = $keywords[$n];
         }
         if ($lsql != "") {
             $lsql .= " or ";
         }
         $lsql .= "keyword='" . escape_check($keywords[$n]) . "'";
     }
     if ($omitmatch) {
         return trim_spaces(str_replace(" " . $omit . " ", " ", " " . join(" ", $keywords) . " "));
     }
     if ($lsql != "") {
         $least = sql_value("select keyword value from keyword where {$lsql} order by hit_count asc limit 1", "");
         return trim_spaces(str_replace(" " . $least . " ", " ", " " . join(" ", $keywords) . " "));
     } else {
         return array();
     }
 }
function perform_login()
{
    global $api, $scramble_key, $enable_remote_apis, $lang, $max_login_attempts_wait_minutes, $max_login_attempts_per_ip, $max_login_attempts_per_username, $global_cookies, $username, $password, $password_hash;
    if (!$api && (strlen($password) == 32 || strlen($password) == 64) && getval("userkey", "") != md5($username . $scramble_key)) {
        exit("Invalid password.");
        # Prevent MD5s being entered directly while still supporting direct entry of plain text passwords (for systems that were set up prior to MD5 password encryption was added). If a special key is sent, which is the md5 hash of the username and the secret scramble key, then allow a login using the MD5 password hash as the password. This is for the 'log in as this user' feature.
    }
    if (strlen($password) != 64) {
        # Provided password is not a hash, so generate a hash.
        //$password_hash=md5("RS" . $username . $password);
        $password_hash = hash('sha256', md5("RS" . $username . $password));
    } else {
        $password_hash = $password;
    }
    // ------- Automatic migration of md5 hashed or plain text passwords to SHA256 hashed passwords ------------
    // This is necessary because older systems being upgraded may still have passwords stored using md5 hashes or even possibly stored in plain text.
    // Updated March 2015 - select password_reset_hash to force dbstruct that will update password column varchar(100) if not already
    $accountstoupdate = sql_query("select username, password, password_reset_hash from user where length(password)<>64");
    foreach ($accountstoupdate as $account) {
        $oldpassword = $account["password"];
        if (strlen($oldpassword) != 32) {
            $oldpassword = md5("RS" . $account["username"] . $oldpassword);
        }
        // Needed if we have a really old password, or if password has been manually reset in db for some reason
        $new_password_hash = hash('sha256', $oldpassword);
        sql_query("update user set password='******' where username='******'");
    }
    $ip = get_ip();
    # This may change the $username, $password, and $password_hash
    $externalresult = hook("externalauth", "", array($username, $password));
    #Attempt external auth if configured
    # Generate a new session hash.
    $session_hash = generate_session_hash($password_hash);
    # Check the provided credentials
    $valid = sql_query("select ref,usergroup,account_expires from user where username='******' and password='******'");
    # Prepare result array
    $result = array();
    $result['valid'] = false;
    if (count($valid) >= 1) {
        # Account expiry
        $userref = $valid[0]["ref"];
        $usergroup = $valid[0]["usergroup"];
        $expires = $valid[0]["account_expires"];
        if ($expires != "" && $expires != "0000-00-00 00:00:00" && strtotime($expires) <= time()) {
            $result['error'] = $lang["accountexpired"];
            return $result;
        }
        $result['valid'] = true;
        $result['session_hash'] = $session_hash;
        $result['password_hash'] = $password_hash;
        $result['ref'] = $userref;
        # Update the user record.
        # Omit updating session has if using an API, because we don't want API usage to log users out, and there is no 'session' to remember in such a case.
        if ($api) {
            $session_hash_sql = "";
        } else {
            $session_hash_sql = "session='" . escape_check($session_hash) . "',";
        }
        sql_query("update user set {$session_hash_sql} last_active=now(),login_tries=0,lang='" . getvalescaped("language", "") . "' where ref='{$userref}'");
        # Log this
        daily_stat("User session", $userref);
        if (!$api) {
            sql_query("insert into resource_log(date,user,resource,type) values (now()," . ($userref != "" ? "'{$userref}'" : "null") . ",0,'l')");
        }
        # Blank the IP address lockout counter for this IP
        sql_query("delete from ip_lockout where ip='" . escape_check($ip) . "'");
        return $result;
    }
    # Invalid login
    if (isset($externalresult["error"])) {
        $result['error'] = $externalresult["error"];
    } else {
        $result['error'] = $lang["loginincorrect"];
    }
    hook("loginincorrect");
    # Add / increment a lockout value for this IP
    $lockouts = sql_value("select count(*) value from ip_lockout where ip='" . escape_check($ip) . "' and tries<'" . $max_login_attempts_per_ip . "'", "");
    if ($lockouts > 0) {
        # Existing row with room to move
        $tries = sql_value("select tries value from ip_lockout where ip='" . escape_check($ip) . "'", 0);
        $tries++;
        if ($tries == $max_login_attempts_per_ip) {
            # Show locked out message.
            $result['error'] = str_replace("?", $max_login_attempts_wait_minutes, $lang["max_login_attempts_exceeded"]);
        }
        # Increment
        sql_query("update ip_lockout set last_try=now(),tries=tries+1 where ip='" . escape_check($ip) . "'");
    } else {
        # New row
        sql_query("delete from ip_lockout where ip='" . escape_check($ip) . "'");
        sql_query("insert into ip_lockout (ip,tries,last_try) values ('" . escape_check($ip) . "',1,now())");
    }
    # Increment a lockout value for any matching username.
    $ulocks = sql_query("select ref,login_tries,login_last_try from user where username='******'");
    if (count($ulocks) > 0) {
        $tries = $ulocks[0]["login_tries"];
        if ($tries == "") {
            $tries = 1;
        } else {
            $tries++;
        }
        if ($tries > $max_login_attempts_per_username) {
            $tries = 1;
        }
        if ($tries == $max_login_attempts_per_username) {
            # Show locked out message.
            $result['error'] = str_replace("?", $max_login_attempts_wait_minutes, $lang["max_login_attempts_exceeded"]);
        }
        sql_query("update user set login_tries='{$tries}',login_last_try=now() where username='******'");
    }
    return $result;
}
    # If the user has just removed the collection they were using, select a new collection
    if ($usercollection == $remove && count($c) > 0) {
        # Select the first collection in the dropdown box.
        $usercollection = $c[0]["ref"];
        set_user_collection($userref, $usercollection);
    }
    refresh_collection_frame();
}
$add = getvalescaped("add", "");
if ($add != "") {
    # Add someone else's collection to your My Collections
    add_collection($userref, $add);
    set_user_collection($userref, $add);
    refresh_collection_frame();
    # Log this
    daily_stat("Add public collection", $userref);
}
$reload = getvalescaped("reload", "");
if ($reload != "") {
    # Refresh the collection frame (just edited a collection)
    refresh_collection_frame();
}
$purge = getvalescaped("purge", "");
$deleteall = getvalescaped("deleteall", "");
if ($purge != "" || $deleteall != "") {
    if ($purge != "") {
        $deletecollection = $purge;
    }
    if ($deleteall != "") {
        $deletecollection = $deleteall;
    }
예제 #7
0
     if ($alternative_file_previews_batch) {
         create_previews($alternative, false, $extension, false, false, $aref);
     }
     echo "SUCCESS";
     exit;
 }
 if ($replace == "" && $replace_resource == "") {
     # Standard upload of a new resource
     $ref = copy_resource(0 - $userref);
     # Copy from user template
     # Add to collection?
     if ($collection_add != "") {
         add_resource_to_collection($ref, $collection_add);
     }
     # Log this
     daily_stat("Resource upload", $ref);
     resource_log($ref, "u", 0);
     $status = upload_file($ref, getval("no_exif", "") != "", false, getval('autorotate', '') != '');
     echo "SUCCESS: " . $ref;
     exit;
 } elseif ($replace == "" && $replace_resource != "") {
     # Replacing an existing resource file
     $status = upload_file($replace_resource, getval("no_exif", "") != "", false, getval('autorotate', '') != '');
     echo "SUCCESS: {$replace_resource}";
     exit;
 } else {
     # Overwrite an existing resource using the number from the filename.
     # Extract the number from the filename
     $plfilename = strtolower(str_replace(" ", "_", $plfilename));
     $s = explode(".", $plfilename);
     if (count($s) == 2) {
예제 #8
0
    # When users can view resources in the 'User Contributed - Pending Review' state in the main search
    # via the $pending_review_visible_to_all option, set access to restricted.
    $access = 1;
}
# If requested, refresh the collection frame (for redirects from saves)
if (getval("refreshcollectionframe", "") != "") {
    refresh_collection_frame();
}
# Update the hitcounts for the search keywords (if search specified)
# (important we fetch directly from $_GET and not from a cookie
$usearch = @$_GET["search"];
if (strpos($usearch, "!") === false && $usearch != "") {
    update_resource_keyword_hitcount($ref, $usearch);
}
# Log this activity
daily_stat("Resource view", $ref);
if ($log_resource_views) {
    resource_log($ref, 'v', 0);
}
if ($direct_download && !$save_as) {
    // check browser to see if forcing save_as
    if (!$direct_download_allow_opera && strpos(strtolower($_SERVER["HTTP_USER_AGENT"]), "opera") !== false) {
        $save_as = true;
    }
    if (!$direct_download_allow_ie7 && strpos(strtolower($_SERVER["HTTP_USER_AGENT"]), "msie 7.") !== false) {
        $save_as = true;
    }
    if (!$direct_download_allow_ie8 && strpos(strtolower($_SERVER["HTTP_USER_AGENT"]), "msie 8.") !== false) {
        $save_as = true;
    }
}
 function do_search($search, $restypes = "", $order_by = "relevance", $archive = 0, $fetchrows = -1, $sort = "desc", $access_override = false, $starsearch = 0, $ignore_filters = false, $return_disk_usage = false, $recent_search_daylimit = "", $go = false, $stats_logging = true)
 {
     debug("search={$search} {$go} {$fetchrows} restypes={$restypes} archive={$archive} daylimit={$recent_search_daylimit}");
     # globals needed for hooks
     global $sql, $order, $select, $sql_join, $sql_filter, $orig_order, $checkbox_and, $collections_omit_archived, $search_sql_double_pass_mode, $usergroup, $search_filter_strict, $default_sort, $search_sql_optimization;
     $alternativeresults = hook("alternativeresults", "", array($go));
     if ($alternativeresults) {
         return $alternativeresults;
     }
     $modifyfetchrows = hook("modifyfetchrows", "", array($fetchrows));
     if ($modifyfetchrows) {
         $fetchrows = $modifyfetchrows;
     }
     # Takes a search string $search, as provided by the user, and returns a results set
     # of matching resources.
     # If there are no matches, instead returns an array of suggested searches.
     # $restypes is optionally used to specify which resource types to search.
     # $access_override is used by smart collections, so that all all applicable resources can be judged regardless of the final access-based results
     # Check valid sort
     if (!in_array(strtolower($sort), array("asc", "desc"))) {
         $sort = "asc";
     }
     # resolve $order_by to something meaningful in sql
     $orig_order = $order_by;
     global $date_field;
     $order = array("relevance" => "score {$sort}, user_rating {$sort}, hit_count {$sort}, field{$date_field} {$sort},r.ref {$sort}", "popularity" => "user_rating {$sort},hit_count {$sort},field{$date_field} {$sort},r.ref {$sort}", "rating" => "r.rating {$sort}, user_rating {$sort}, score {$sort},r.ref {$sort}", "date" => "field{$date_field} {$sort},r.ref {$sort}", "colour" => "has_image {$sort},image_blue {$sort},image_green {$sort},image_red {$sort},field{$date_field} {$sort},r.ref {$sort}", "country" => "country {$sort},r.ref {$sort}", "title" => "title {$sort},r.ref {$sort}", "file_path" => "file_path {$sort},r.ref {$sort}", "resourceid" => "r.ref {$sort}", "resourcetype" => "resource_type {$sort},r.ref {$sort}", "titleandcountry" => "title {$sort},country {$sort}", "random" => "RAND()", "status" => "archive {$sort}");
     if (!in_array($order_by, $order) && substr($order_by, 0, 5) == "field") {
         if (!is_numeric(str_replace("field", "", $order_by))) {
             exit("Order field incorrect.");
         }
         $order[$order_by] = "{$order_by} {$sort}";
     }
     hook("modifyorderarray");
     # Recognise a quoted search, which is a search for an exact string
     global $quoted_string;
     $quoted_string = false;
     if (substr($search, 0, 1) == "\"" && substr($search, -1, 1) == "\"") {
         $quoted_string = true;
         $search = substr($search, 1, -1);
     }
     $order_by = $order[$order_by];
     $keywords = split_keywords($search);
     foreach (get_indexed_resource_type_fields() as $resource_type_field) {
         add_verbatim_keywords($keywords, $search, $resource_type_field);
         // add any regex matched verbatim keywords for those indexed resource type fields
     }
     $search = trim($search);
     # Dedupe keywords (not for quoted strings as the user may be looking for the same word multiple times together in this instance)
     if (!$quoted_string) {
         $keywords = array_values(array_unique($keywords));
     }
     $modified_keywords = hook('dosearchmodifykeywords', '', array($keywords));
     if ($modified_keywords) {
         $keywords = $modified_keywords;
     }
     # -- Build up filter SQL that will be used for all queries
     $sql_filter = "";
     $sql_keyword_union_whichkeys = array();
     $sql_keyword_union = array();
     $sql_keyword_union_aggregation = array();
     $sql_keyword_union_criteria = array();
     $sql_keyword_union_sub_query = array();
     # append resource type filtering
     if ($restypes != "" && substr($restypes, 0, 6) != "Global") {
         if ($sql_filter != "") {
             $sql_filter .= " and ";
         }
         $restypes_x = explode(",", $restypes);
         $sql_filter .= "resource_type in ('" . join("','", $restypes_x) . "')";
     }
     if ($starsearch != "" && $starsearch != 0 && $starsearch != -1) {
         if ($sql_filter != "") {
             $sql_filter .= " and ";
         }
         $sql_filter .= "user_rating >= '{$starsearch}'";
     }
     if ($starsearch == -1) {
         if ($sql_filter != "") {
             $sql_filter .= " and ";
         }
         $sql_filter .= "user_rating = '-1'";
     }
     if ($recent_search_daylimit != "") {
         if ($sql_filter != "") {
             $sql_filter .= " and ";
         }
         $sql_filter .= "creation_date > (curdate() - interval " . $recent_search_daylimit . " DAY)";
     }
     # The ability to restrict access by the user that created the resource.
     global $resource_created_by_filter;
     if (isset($resource_created_by_filter) && count($resource_created_by_filter) > 0) {
         $created_filter = "";
         foreach ($resource_created_by_filter as $filter_user) {
             if ($filter_user == -1) {
                 global $userref;
                 $filter_user = $userref;
             }
             # '-1' can be used as an alias to the current user. I.e. they can only see their own resources in search results.
             if ($created_filter != "") {
                 $created_filter .= " or ";
             }
             $created_filter .= "created_by = '" . $filter_user . "'";
         }
         if ($created_filter != "") {
             if ($sql_filter != "") {
                 $sql_filter .= " and ";
             }
             $sql_filter .= "(" . $created_filter . ")";
         }
     }
     # Geo zone exclusion
     # A list of upper/lower long/lat bounds, defining areas that will be excluded from geo search results.
     # Areas are defined as southwest lat, southwest long, northeast lat, northeast long
     global $geo_search_restrict;
     if (count($geo_search_restrict) > 0 && substr($search, 0, 4) == "!geo") {
         foreach ($geo_search_restrict as $zone) {
             if ($sql_filter != "") {
                 $sql_filter .= " and ";
             }
             $sql_filter .= "(geo_lat is null or geo_long is null or not(geo_lat >= '" . $zone[0] . "' and geo_lat<= '" . $zone[2] . "'";
             $sql_filter .= "and geo_long >= '" . $zone[1] . "' and geo_long<= '" . $zone[3] . "'))";
         }
     }
     # If returning disk used by the resources in the search results ($return_disk_usage=true) then wrap the returned SQL in an outer query that sums disk usage.
     $sql_prefix = "";
     $sql_suffix = "";
     if ($return_disk_usage) {
         $sql_prefix = "select sum(disk_usage) total_disk_usage,count(*) total_resources from (";
         $sql_suffix = ") resourcelist";
     }
     # append resource type restrictions based on 'T' permission
     # look for all 'T' permissions and append to the SQL filter.
     global $userpermissions;
     $rtfilter = array();
     for ($n = 0; $n < count($userpermissions); $n++) {
         if (substr($userpermissions[$n], 0, 1) == "T") {
             $rt = substr($userpermissions[$n], 1);
             if (is_numeric($rt) && !$access_override) {
                 $rtfilter[] = $rt;
             }
         }
     }
     if (count($rtfilter) > 0) {
         if ($sql_filter != "") {
             $sql_filter .= " and ";
         }
         $sql_filter .= "resource_type not in (" . join(",", $rtfilter) . ")";
     }
     # append "use" access rights, do not show restricted resources unless admin
     if (!checkperm("v") && !$access_override) {
         if ($sql_filter != "") {
             $sql_filter .= " and ";
         }
         $sql_filter .= "r.access<>'2'";
     }
     # append archive searching (don't do this for collections or !listall, archived resources can still appear in these searches)
     if (!$access_override && (substr($search, 0, 8) != "!listall" && substr($search, 0, 11) != "!collection" || $collections_omit_archived && !checkperm("e2"))) {
         global $pending_review_visible_to_all, $search_all_workflow_states;
         if ($search_all_workflow_states) {
             # Nothing to append, as we're searching all states.
             hook("search_all_workflow_states_filter");
         } elseif ($archive == 0 && $pending_review_visible_to_all) {
             # If resources pending review are visible to all, when listing only active resources include
             # pending review (-1) resources too.
             if ($sql_filter != "") {
                 $sql_filter .= " and ";
             }
             $sql_filter .= "archive in('0','-1')";
         } else {
             # Append normal filtering - extended as advanced search now allows searching by archive state
             if ($sql_filter != "") {
                 $sql_filter .= " and ";
             }
             $sql_filter .= "archive = '{$archive}'";
             global $userref, $pending_submission_searchable_to_all;
             if (!$pending_submission_searchable_to_all && $archive == "-2" && !(checkperm("e-2") && checkperm("t") || checkperm("v"))) {
                 $sql_filter .= " and created_by='" . $userref . "'";
             }
             if (!$pending_review_visible_to_all && $archive == "-1" && !(checkperm("e-1") && checkperm("t") || checkperm("v"))) {
                 $sql_filter .= " and created_by='" . $userref . "'";
             }
         }
     }
     # Add code to filter out resoures in archive states that the user does not have access to due to a 'z' permission
     $filterblockstates = "";
     for ($n = -2; $n <= 3; $n++) {
         if (checkperm("z" . $n) && !$access_override) {
             if ($filterblockstates != "") {
                 $filterblockstates .= "','";
             }
             $filterblockstates .= $n;
         }
     }
     global $additional_archive_states;
     foreach ($additional_archive_states as $additional_archive_state) {
         if (checkperm("z" . $additional_archive_state)) {
             if ($filterblockstates != "") {
                 $filterblockstates .= "','";
             }
             $filterblockstates .= $additional_archive_state;
         }
     }
     if ($filterblockstates != "" && !$access_override) {
         global $uploader_view_override, $userref;
         if ($uploader_view_override) {
             if ($sql_filter != "") {
                 $sql_filter .= " and ";
             }
             $sql_filter .= "(archive not in ('{$filterblockstates}') or created_by='" . $userref . "')";
         } else {
             if ($sql_filter != "") {
                 $sql_filter .= " and ";
             }
             $sql_filter .= "archive not in ('{$filterblockstates}')";
         }
     }
     # append ref filter - never return the batch upload template (negative refs)
     if ($sql_filter != "") {
         $sql_filter .= " and ";
     }
     $sql_filter .= "r.ref>0";
     # ------ Advanced 'custom' permissions, need to join to access table.
     $sql_join = "";
     global $k;
     if (!checkperm("v") && !$access_override) {
         global $usergroup;
         global $userref;
         # one extra join (rca2) is required for user specific permissions (enabling more intelligent watermarks in search view)
         # the original join is used to gather group access into the search query as well.
         $sql_join = " left outer join resource_custom_access rca2 on r.ref=rca2.resource and rca2.user='******'  and (rca2.user_expires is null or rca2.user_expires>now()) and rca2.access<>2  ";
         $sql_join .= " left outer join resource_custom_access rca on r.ref=rca.resource and rca.usergroup='{$usergroup}' and rca.access<>2 ";
         if ($sql_filter != "") {
             $sql_filter .= " and ";
         }
         # If rca.resource is null, then no matching custom access record was found
         # If r.access is also 3 (custom) then the user is not allowed access to this resource.
         # Note that it's normal for null to be returned if this is a resource with non custom permissions (r.access<>3).
         $sql_filter .= " not(rca.resource is null and r.access=3)";
     }
     # Join thumbs_display_fields to resource table
     $select = "r.ref, r.resource_type, r.has_image, r.is_transcoding, r.hit_count, r.creation_date, r.rating, r.user_rating, r.user_rating_count, r.user_rating_total, r.file_extension, r.preview_extension, r.image_red, r.image_green, r.image_blue, r.thumb_width, r.thumb_height, r.archive, r.access, r.colour_key, r.created_by, r.file_modified, r.file_checksum, r.request_count, r.new_hit_count, r.expiry_notification_sent, r.preview_tweaks, r.file_path ";
     $modified_select = hook("modifyselect");
     if ($modified_select) {
         $select .= $modified_select;
     }
     $modified_select2 = hook("modifyselect2");
     if ($modified_select2) {
         $select .= $modified_select2;
     }
     # Return disk usage for each resource if returning sum of disk usage.
     if ($return_disk_usage) {
         $select .= ",r.disk_usage";
     }
     # select group and user access rights if available, otherwise select null values so columns can still be used regardless
     # this makes group and user specific access available in the basic search query, which can then be passed through access functions
     # in order to eliminate many single queries.
     if (!checkperm("v") && !$access_override) {
         $select .= ",rca.access group_access,rca2.access user_access ";
     } else {
         $select .= ",null group_access, null user_access ";
     }
     # add 'joins' to select (adding them
     $joins = get_resource_table_joins();
     foreach ($joins as $datajoin) {
         $select .= ",r.field" . $datajoin . " ";
     }
     # Prepare SQL to add join table for all provided keywods
     $suggested = $keywords;
     # a suggested search
     $fullmatch = true;
     $c = 0;
     $t = "";
     $t2 = "";
     $score = "";
     $skipped_last = false;
     $keysearch = true;
     # Do not process if a numeric search is provided (resource ID)
     global $config_search_for_number, $category_tree_search_use_and;
     if ($config_search_for_number && is_numeric($search)) {
         $keysearch = false;
     }
     # Fetch a list of fields that are not available to the user - these must be omitted from the search.
     $hidden_indexed_fields = get_hidden_indexed_fields();
     # This is a performance enhancement that will discard any keyword matches for fields that are not supposed to be indexed.
     $sql_restrict_by_field_types = "";
     global $search_sql_force_field_index_check;
     if (isset($search_sql_force_field_index_check) && $search_sql_force_field_index_check && $restypes != "") {
         $sql_restrict_by_field_types = sql_value("select group_concat(ref) as value from resource_type_field where keywords_index=1 and resource_type in ({$restypes})", "");
         if ($sql_restrict_by_field_types != "") {
             $sql_restrict_by_field_types = "-1," . $sql_restrict_by_field_types;
             // -1 needed for global search
         }
     }
     if ($keysearch) {
         for ($n = 0; $n < count($keywords); $n++) {
             $keyword = $keywords[$n];
             if (substr($keyword, 0, 1) != "!" || substr($keyword, 0, 6) == "!empty") {
                 global $date_field;
                 $field = 0;
                 #echo "<li>$keyword<br/>";
                 if (strpos($keyword, ":") !== false && !$ignore_filters) {
                     $kw = explode(":", $keyword, 2);
                     global $datefieldinfo_cache;
                     if (isset($datefieldinfo_cache[$kw[0]])) {
                         $datefieldinfo = $datefieldinfo_cache[$kw[0]];
                     } else {
                         $datefieldinfo = sql_query("select ref from resource_type_field where name='" . escape_check($kw[0]) . "' and type IN (4,6,10)", 0);
                         $datefieldinfo_cache[$kw[0]] = $datefieldinfo;
                     }
                     if (count($datefieldinfo) && substr($kw[1], 0, 5) != "range") {
                         $c++;
                         $datefieldinfo = $datefieldinfo[0];
                         $datefield = $datefieldinfo["ref"];
                         if ($sql_filter != "") {
                             $sql_filter .= " and ";
                         }
                         $val = str_replace("n", "_", $kw[1]);
                         $val = str_replace("|", "-", $val);
                         $sql_filter .= "rd" . $c . ".value like '" . $val . "%' ";
                         $sql_join .= " join resource_data rd" . $c . " on rd" . $c . ".resource=r.ref and rd" . $c . ".resource_type_field='" . $datefield . "'";
                     } elseif ($kw[0] == "day") {
                         if ($sql_filter != "") {
                             $sql_filter .= " and ";
                         }
                         $sql_filter .= "r.field{$date_field} like '____-__-" . $kw[1] . "%' ";
                     } elseif ($kw[0] == "month") {
                         if ($sql_filter != "") {
                             $sql_filter .= " and ";
                         }
                         $sql_filter .= "r.field{$date_field} like '____-" . $kw[1] . "%' ";
                     } elseif ($kw[0] == "year") {
                         if ($sql_filter != "") {
                             $sql_filter .= " and ";
                         }
                         $sql_filter .= "r.field{$date_field} like '" . $kw[1] . "%' ";
                     } elseif ($kw[0] == "startdate") {
                         if ($sql_filter != "") {
                             $sql_filter .= " and ";
                         }
                         $sql_filter .= "r.field{$date_field} >= '" . $kw[1] . "' ";
                     } elseif ($kw[0] == "enddate") {
                         if ($sql_filter != "") {
                             $sql_filter .= " and ";
                         }
                         $sql_filter .= "r.field{$date_field} <= '" . $kw[1] . " 23:59:59' ";
                     } elseif (count($datefieldinfo) && substr($kw[1], 0, 5) == "range") {
                         $c++;
                         $rangefield = $datefieldinfo[0]["ref"];
                         $daterange = false;
                         $rangestring = substr($kw[1], 5);
                         if (strpos($rangestring, "start") !== FALSE) {
                             $rangestart = str_replace(" ", "-", $rangestring);
                             if ($sql_filter != "") {
                                 $sql_filter .= " and ";
                             }
                             $sql_filter .= "rd" . $c . ".value >= '" . substr($rangestart, strpos($rangestart, "start") + 5, 10) . "'";
                         }
                         if (strpos($kw[1], "end") !== FALSE) {
                             $rangeend = str_replace(" ", "-", $rangestring);
                             if ($sql_filter != "") {
                                 $sql_filter .= " and ";
                             }
                             $sql_filter .= "rd" . $c . ".value <= '" . substr($rangeend, strpos($rangeend, "end") + 3, 10) . " 23:59:59'";
                         }
                         $sql_join .= " join resource_data rd" . $c . " on rd" . $c . ".resource=r.ref and rd" . $c . ".resource_type_field='" . $rangefield . "'";
                     } elseif (!hook('customsearchkeywordfilter', null, array($kw))) {
                         $ckeywords = explode(";", $kw[1]);
                         # Fetch field info
                         global $fieldinfo_cache;
                         if (isset($fieldinfo_cache[$kw[0]])) {
                             $fieldinfo = $fieldinfo_cache[$kw[0]];
                         } else {
                             $fieldinfo = sql_query("select ref,type from resource_type_field where name='" . escape_check($kw[0]) . "'", 0);
                             $fieldinfo_cache[$kw[0]] = $fieldinfo;
                         }
                         if (count($fieldinfo) == 0) {
                             debug("Field short name not found.");
                             return false;
                         }
                         # Create an array of matching field IDs.
                         $fields = array();
                         foreach ($fieldinfo as $fi) {
                             if (in_array($fi["ref"], $hidden_indexed_fields)) {
                                 # Attempt to directly search field that the user does not have access to.
                                 return false;
                             }
                             # Add to search array
                             $fields[] = $fi["ref"];
                         }
                         # Special handling for dates
                         if ($fieldinfo[0]["type"] == 4 || $fieldinfo[0]["type"] == 6 || $fieldinfo[0]["type"] == 10) {
                             $ckeywords = array(str_replace(" ", "-", $kw[1]));
                         }
                         #special SQL generation for category trees to use AND instead of OR
                         if ($fieldinfo[0]["type"] == 7 && $category_tree_search_use_and || $fieldinfo[0]["type"] == 2 && $checkbox_and) {
                             for ($m = 0; $m < count($ckeywords); $m++) {
                                 $keyref = resolve_keyword($ckeywords[$m]);
                                 if (!($keyref === false)) {
                                     $c++;
                                     # Add related keywords
                                     $related = get_related_keywords($keyref);
                                     $relatedsql = "";
                                     for ($r = 0; $r < count($related); $r++) {
                                         $relatedsql .= " or k" . $c . ".keyword='" . $related[$r] . "'";
                                     }
                                     # Form join
                                     $sql_join .= " join resource_keyword k" . $c . " on k" . $c . ".resource=r.ref and k" . $c . ".resource_type_field in ('" . join("','", $fields) . "') and (k" . $c . ".keyword='{$keyref}' {$relatedsql})";
                                     if ($score != "") {
                                         $score .= "+";
                                     }
                                     $score .= "k" . $c . ".hit_count";
                                     # Log this
                                     if ($stats_logging) {
                                         daily_stat("Keyword usage", $keyref);
                                     }
                                 }
                             }
                         } else {
                             $c++;
                             # work through all options in an OR approach for multiple selects on the same field
                             $searchkeys = array();
                             for ($m = 0; $m < count($ckeywords); $m++) {
                                 $keyref = resolve_keyword($ckeywords[$m]);
                                 if ($keyref === false) {
                                     $keyref = -1;
                                 }
                                 $searchkeys[] = $keyref;
                                 # Also add related.
                                 $related = get_related_keywords($keyref);
                                 for ($o = 0; $o < count($related); $o++) {
                                     $searchkeys[] = $related[$o];
                                 }
                                 # Log this
                                 if ($stats_logging) {
                                     daily_stat("Keyword usage", $keyref);
                                 }
                             }
                             $union = "select resource,";
                             for ($p = 1; $p <= count($keywords); $p++) {
                                 if ($p == $c) {
                                     $union .= "true";
                                 } else {
                                     $union .= "false";
                                 }
                                 $union .= " as keyword_" . $p . "_found,";
                             }
                             $union .= "hit_count as score from resource_keyword k" . $c . " where (k" . $c . ".keyword='{$keyref}' or k" . $c . ".keyword in ('" . join("','", $searchkeys) . "')) and k" . $c . ".resource_type_field in ('" . join("','", $fields) . "')";
                             if (!empty($sql_exclude_fields)) {
                                 $union .= " and k" . $c . ".resource_type_field not in (" . $sql_exclude_fields . ")";
                             }
                             if (count($hidden_indexed_fields) > 0) {
                                 $union .= " and k" . $c . ".resource_type_field not in ('" . join("','", $hidden_indexed_fields) . "')";
                             }
                             $sql_keyword_union_aggregation[] = "bit_or(keyword_" . $c . "_found) as keyword_" . $c . "_found";
                             $sql_keyword_union_criteria[] = "h.keyword_" . $c . "_found";
                             $sql_keyword_union[] = $union;
                         }
                     }
                 } else {
                     # Normal keyword (not tied to a field) - searches all fields that the user has access to
                     # If ignoring field specifications then remove them.
                     if (strpos($keyword, ":") !== false && $ignore_filters) {
                         $s = explode(":", $keyword);
                         $keyword = $s[1];
                     }
                     # Omit resources containing this keyword?
                     $omit = false;
                     if (substr($keyword, 0, 1) == "-") {
                         $omit = true;
                         $keyword = substr($keyword, 1);
                     }
                     # Search for resources with an empty field, ex: !empty18  or  !emptycaption
                     $empty = false;
                     if (substr($keyword, 0, 6) == "!empty") {
                         $nodatafield = str_replace("!empty", "", $keyword);
                         if (!is_numeric($nodatafield)) {
                             $nodatafield = sql_value("select ref value from resource_type_field where name='" . escape_check($nodatafield) . "'", "");
                         }
                         if ($nodatafield == "" || !is_numeric($nodatafield)) {
                             exit('invalid !empty search');
                         }
                         $empty = true;
                     }
                     global $noadd, $wildcard_always_applied;
                     if (in_array($keyword, $noadd)) {
                         $skipped_last = true;
                     } else {
                         # Handle wildcards
                         $wildcards = array();
                         if (strpos($keyword, "*") !== false || $wildcard_always_applied) {
                             if ($wildcard_always_applied && strpos($keyword, "*") === false) {
                                 # Suffix asterisk if none supplied and using $wildcard_always_applied mode.
                                 $keyword = $keyword . "*";
                             }
                             # Keyword contains a wildcard. Expand.
                             global $wildcard_expand_limit;
                             $wildcards = sql_array("select ref value from keyword where keyword like '" . escape_check(str_replace("*", "%", $keyword)) . "' order by hit_count desc limit " . $wildcard_expand_limit);
                         }
                         $keyref = resolve_keyword(str_replace('*', '', $keyword));
                         # Resolve keyword. Ignore any wildcards when resolving. We need wildcards to be present later but not here.
                         if ($keyref === false && !$omit && !$empty && count($wildcards) == 0) {
                             $fullmatch = false;
                             $soundex = resolve_soundex($keyword);
                             if ($soundex === false) {
                                 # No keyword match, and no keywords sound like this word. Suggest dropping this word.
                                 $suggested[$n] = "";
                             } else {
                                 # No keyword match, but there's a word that sounds like this word. Suggest this word instead.
                                 $suggested[$n] = "<i>" . $soundex . "</i>";
                             }
                         } else {
                             if ($keyref === false) {
                                 # make a new keyword
                                 $keyref = resolve_keyword(str_replace('*', '', $keyword), true);
                             }
                             # Key match, add to query.
                             $c++;
                             $relatedsql = "";
                             if (!$quoted_string) {
                                 # Add related keywords
                                 $related = get_related_keywords($keyref);
                                 # Merge wildcard expansion with related keywords
                                 $related = array_merge($related, $wildcards);
                                 if (count($related) > 0) {
                                     $relatedsql = " or k" . $c . ".keyword IN ('" . join("','", $related) . "')";
                                 }
                             }
                             # Form join
                             $sql_exclude_fields = hook("excludefieldsfromkeywordsearch");
                             if (!$omit) {
                                 # Include in query
                                 // --------------------------------------------------------------------------------
                                 // Start of normal union for resource keywords
                                 // --------------------------------------------------------------------------------
                                 // add false for keyword matches other than the current one
                                 $bit_or_condition = "";
                                 for ($p = 1; $p <= count($keywords); $p++) {
                                     if ($p == $c) {
                                         $bit_or_condition .= "true";
                                     } else {
                                         $bit_or_condition .= "false";
                                     }
                                     $bit_or_condition .= " as keyword_" . $p . "_found,";
                                 }
                                 // these restrictions apply to both !empty searches as well as normal keyword searches (i.e. both branches of next if statement)
                                 $union_restriction_clause = "";
                                 if (!empty($sql_exclude_fields)) {
                                     $union_restriction_clause .= " and k" . $c . ".resource_type_field not in (" . $sql_exclude_fields . ")";
                                 }
                                 if (count($hidden_indexed_fields) > 0) {
                                     $union_restriction_clause .= " and k" . $c . ".resource_type_field not in ('" . join("','", $hidden_indexed_fields) . "')";
                                 }
                                 if ($empty) {
                                     $rtype = sql_value("select resource_type value from resource_type_field where ref='{$nodatafield}'", 0);
                                     if ($rtype != 0) {
                                         if ($rtype == 999) {
                                             $restypesql = "and (r" . $c . ".archive=1 or r" . $c . ".archive=2) and ";
                                             if ($sql_filter != "") {
                                                 $sql_filter .= " and ";
                                             }
                                             $sql_filter .= str_replace("r" . $c . ".archive='0'", "(r" . $c . ".archive=1 or r" . $c . ".archive=2)", $sql_filter);
                                         } else {
                                             $restypesql = "and r" . $c . ".resource_type ='{$rtype}' ";
                                         }
                                     } else {
                                         $restypesql = "";
                                     }
                                     $union = "select ref as resource, {$bit_or_condition} 1 as score from resource r" . $c . " left outer join resource_data rd" . $c . " on r" . $c . ".ref=rd" . $c . ".resource and rd" . $c . ".resource_type_field='{$nodatafield}' where  (rd" . $c . ".value ='' or rd" . $c . ".value is null or rd" . $c . ".value=',') {$restypesql}  and r" . $c . ".ref>0 group by r" . $c . ".ref ";
                                     $union .= $union_restriction_clause;
                                     $sql_keyword_union[] = $union;
                                 } else {
                                     if ($search_sql_optimization) {
                                         $sql_keyword_union_sub_query[$c] = $keyref;
                                     } else {
                                         $filter_by_resource_field_type = "";
                                         if ($sql_restrict_by_field_types != "") {
                                             $filter_by_resource_field_type = "and k{$c}.resource_type_field in ({$sql_restrict_by_field_types})";
                                             // -1 needed for global search
                                         }
                                         $union = "SELECT resource, {$bit_or_condition} SUM(hit_count) AS score FROM resource_keyword k{$c}\n\t\t\t\t\t\t\t\t\t\tWHERE (k{$c}.keyword={$keyref} {$filter_by_resource_field_type} {$relatedsql} {$union_restriction_clause})\n\t\t\t\t\t\t\t\t\t\tGROUP BY resource";
                                         $sql_keyword_union[] = $union;
                                     }
                                 }
                                 $sql_keyword_union_aggregation[] = "bit_or(keyword_" . $c . "_found) as keyword_" . $c . "_found";
                                 $sql_keyword_union_criteria[] = "h.keyword_" . $c . "_found";
                                 // --------------------------------------------------------------------------------
                                 # Quoted search? Also add a specific join to check that the positions add up.
                                 # The UNION / bit_or() approach doesn't support position checking hence the need for additional joins to do this.
                                 if ($quoted_string) {
                                     $sql_join .= " join resource_keyword qrk_{$c} on qrk_{$c}.resource=r.ref and qrk_{$c}.keyword='{$keyref}' ";
                                     # Exclude fields from the quoted search join also
                                     if (!empty($sql_exclude_fields)) {
                                         $sql_join .= " and qrk_" . $c . ".resource_type_field not in (" . $sql_exclude_fields . ")";
                                     }
                                     if (count($hidden_indexed_fields) > 0) {
                                         $sql_join .= " and qrk_" . $c . ".resource_type_field not in ('" . join("','", $hidden_indexed_fields) . "')";
                                     }
                                     # For keywords other than the first one, check the position is next to the previous keyword.
                                     if ($c > 1) {
                                         $last_key_offset = 1;
                                         if (isset($skipped_last) && $skipped_last) {
                                             $last_key_offset = 2;
                                         }
                                         # Support skipped keywords - if the last keyword was skipped (listed in $noadd), increase the allowed position from the previous keyword. Useful for quoted searches that contain $noadd words, e.g. "black and white" where "and" is a skipped keyword.
                                         # Also check these occurances are within the same field.
                                         $sql_join .= " and qrk_" . $c . ".position>0 and qrk_" . $c . ".position=qrk_" . ($c - 1) . ".position+" . $last_key_offset . " and qrk_" . $c . ".resource_type_field=qrk_" . ($c - 1) . ".resource_type_field";
                                     }
                                 }
                             } else {
                                 if ($omit) {
                                     # Exclude matching resources from query (omit feature)
                                     if ($sql_filter != "") {
                                         $sql_filter .= " and ";
                                     }
                                     $sql_filter .= "r.ref not in (select resource from resource_keyword where keyword='{$keyref}')";
                                     # Filter out resources that do contain the keyword.
                                 }
                             }
                             # Log this
                             if ($stats_logging) {
                                 daily_stat("Keyword usage", $keyref);
                             }
                         }
                     }
                     $skipped_last = false;
                 }
             }
         }
     }
     # Could not match on provided keywords? Attempt to return some suggestions.
     if ($fullmatch == false) {
         if ($suggested == $keywords) {
             # Nothing different to suggest.
             debug("No alternative keywords to suggest.");
             return "";
         } else {
             # Suggest alternative spellings/sound-a-likes
             $suggest = "";
             if (strpos($search, ",") === false) {
                 $suggestjoin = " ";
             } else {
                 $suggestjoin = ", ";
             }
             for ($n = 0; $n < count($suggested); $n++) {
                 if ($suggested[$n] != "") {
                     if ($suggest != "") {
                         $suggest .= $suggestjoin;
                     }
                     $suggest .= $suggested[$n];
                 }
             }
             debug("Suggesting {$suggest}");
             return $suggest;
         }
     }
     hook("additionalsqlfilter");
     hook("parametricsqlfilter", '', array($search));
     # ------ Search filtering: If search_filter is specified on the user group, then we must always apply this filter.
     global $usersearchfilter;
     $sf = explode(";", $usersearchfilter);
     if (strlen($usersearchfilter) > 0) {
         for ($n = 0; $n < count($sf); $n++) {
             $s = explode("=", $sf[$n]);
             if (count($s) != 2) {
                 exit("Search filter is not correctly configured for this user group.");
             }
             # Support for "NOT" matching. Return results only where the specified value or values are NOT set.
             $filterfield = $s[0];
             $filter_not = false;
             if (substr($filterfield, -1) == "!") {
                 $filter_not = true;
                 $filterfield = substr($filterfield, 0, -1);
                 # Strip off the exclamation mark.
             }
             # Support for multiple fields on the left hand side, pipe separated - allows OR matching across multiple fields in a basic way
             $filterfields = explode("|", escape_check($filterfield));
             # Find field(s) - multiple fields can be returned to support several fields with the same name.
             $f = sql_array("select ref value from resource_type_field where name in ('" . join("','", $filterfields) . "')");
             if (count($f) == 0) {
                 exit("Field(s) with short name '" . $filterfield . "' not found in user group search filter.");
             }
             # Find keyword(s)
             $ks = explode("|", strtolower(escape_check($s[1])));
             for ($x = 0; $x < count($ks); $x++) {
                 # Cleanse the string as keywords are stored without special characters
                 $ks[$x] = cleanse_string($ks[$x], true);
                 global $stemming;
                 if ($stemming && function_exists("GetStem")) {
                     $ks[$x] = GetStem($ks[$x]);
                 }
             }
             $modifiedsearchfilter = hook("modifysearchfilter");
             if ($modifiedsearchfilter) {
                 $ks = $modifiedsearchfilter;
             }
             $kw = sql_array("select ref value from keyword where keyword in ('" . join("','", $ks) . "')");
             if (!$filter_not) {
                 # Standard operation ('=' syntax)
                 $sql_join .= " join resource_keyword filter" . $n . " on r.ref=filter" . $n . ".resource and filter" . $n . ".resource_type_field in ('" . join("','", $f) . "') and filter" . $n . ".keyword in ('" . join("','", $kw) . "') ";
                 if ($search_filter_strict > 1) {
                     $sql_join .= " join resource_data dfilter" . $n . " on r.ref=dfilter" . $n . ".resource and dfilter" . $n . ".resource_type_field in ('" . join("','", $f) . "') and (find_in_set('" . join("', dfilter" . $n . ".value) or find_in_set('", explode("|", escape_check($s[1]))) . "', dfilter" . $n . ".value))";
                 }
             } else {
                 # Inverted NOT operation ('!=' syntax)
                 if ($sql_filter != "") {
                     $sql_filter .= " and ";
                 }
                 $sql_filter .= "r.ref not in (select resource from resource_keyword where resource_type_field in ('" . join("','", $f) . "') and keyword in ('" . join("','", $kw) . "'))";
                 # Filter out resources that do contain the keyword(s)
             }
         }
     }
     $userownfilter = hook("userownfilter");
     if ($userownfilter) {
         $sql_join .= $userownfilter;
     }
     # Handle numeric searches when $config_search_for_number=false, i.e. perform a normal search but include matches for resource ID first
     global $config_search_for_number;
     if (!$config_search_for_number && is_numeric($search)) {
         # Always show exact resource matches first.
         $order_by = "(r.ref='" . $search . "') desc," . $order_by;
     }
     # ---------------------------------------------------------------
     # union with inner join
     #
     # Populating the following array:
     #
     # $sql_keyword_union_sub_query[<keyword number>]=<keyword ref>
     #
     # will combine keyword searches in join within BIT_OR union
     # This saves on data copying to temporary MySQL tables
     # ---------------------------------------------------------------
     if ($search_sql_optimization && count($sql_keyword_union_sub_query) > 0) {
         $sql_keyword_union_sub_query_keys = array_keys($sql_keyword_union_sub_query);
         $union = "SELECT keyword" . $sql_keyword_union_sub_query[$sql_keyword_union_sub_query_keys[0]] . ".resource";
         for ($p = 1; $p <= count($keywords); $p++) {
             $union .= "," . (isset($sql_keyword_union_sub_query[$p]) ? "TRUE" : "FALSE") . " as keyword_{$p}_found";
         }
         $union .= ",SUM(keyword" . $sql_keyword_union_sub_query[$sql_keyword_union_sub_query_keys[0]] . ".hit_count) AS score";
         $union .= " FROM resource_keyword keyword" . $sql_keyword_union_sub_query[$sql_keyword_union_sub_query_keys[0]];
         for ($i = 1; $i < count($sql_keyword_union_sub_query_keys); $i++) {
             $union .= " JOIN resource_keyword keyword" . $sql_keyword_union_sub_query[$sql_keyword_union_sub_query_keys[$i]];
             $union .= " ON keyword" . $sql_keyword_union_sub_query[$sql_keyword_union_sub_query_keys[$i - 1]];
             $union .= ".resource=keyword" . $sql_keyword_union_sub_query[$sql_keyword_union_sub_query_keys[$i]] . ".resource";
             if ($sql_restrict_by_field_types != "") {
                 $union .= " AND keyword" . $sql_keyword_union_sub_query[$sql_keyword_union_sub_query_keys[$i]] . ".resource_type_field IN ({$sql_restrict_by_field_types})";
             }
         }
         $union .= " WHERE";
         for ($i = 0; $i < count($sql_keyword_union_sub_query_keys); $i++) {
             if ($i > 0) {
                 $union .= " AND";
             }
             $union .= " keyword" . $sql_keyword_union_sub_query[$sql_keyword_union_sub_query_keys[$i]] . ".keyword=" . $sql_keyword_union_sub_query[$sql_keyword_union_sub_query_keys[$i]];
         }
         $union .= " GROUP BY keyword" . $sql_keyword_union_sub_query[$sql_keyword_union_sub_query_keys[0]] . ".resource";
         $sql_keyword_union[] = $union;
         // add to normal union array
     }
     # ---------------------------------------------------------------
     # Keyword union assembly.
     # Use UNIONs for keyword matching instead of the older JOIN technique - much faster
     # Assemble the new join from the stored unions
     # ---------------------------------------------------------------
     if (count($sql_keyword_union) > 0) {
         $sql_join .= " join (\n\t\tselect resource,sum(score) as score,\n\t\t" . join(", ", $sql_keyword_union_aggregation) . " from\n\t\t(" . join(" union ", $sql_keyword_union) . ") as hits group by resource) as h on h.resource=r.ref ";
         if ($sql_filter != "") {
             $sql_filter .= " and ";
         }
         $sql_filter .= join(" and ", $sql_keyword_union_criteria);
         # Use amalgamated resource_keyword hitcounts for scoring (relevance matching based on previous user activity)
         $score = "h.score";
     }
     # --------------------------------------------------------------------------------
     # Special Searches (start with an exclamation mark)
     # --------------------------------------------------------------------------------
     # Can only search for resources that belong to themes
     if (checkperm("J")) {
         $sql_join = " join collection_resource jcr on jcr.resource=r.ref join collection jc on jcr.collection=jc.ref and length(jc.theme)>0 " . $sql_join;
     }
     # ------ Special searches ------
     # View Last
     if (substr($search, 0, 5) == "!last") {
         # Replace r2.ref with r.ref for the alternative query used here.
         $order_by = str_replace("r.ref", "r2.ref", $order_by);
         if ($orig_order == "relevance") {
             $order_by = "r2.ref desc";
         }
         # Extract the number of records to produce
         $last = explode(",", $search);
         $last = str_replace("!last", "", $last[0]);
         if (!is_numeric($last)) {
             $last = 1000;
             $search = "!last1000";
         }
         # 'Last' must be a number. SQL injection filter.
         # Fix the order by for this query (special case due to inner query)
         $order_by = str_replace("r.rating", "rating", $order_by);
         return sql_query($sql_prefix . "select distinct *,r2.hit_count score from (select {$select} from resource r {$sql_join} where {$sql_filter} order by ref desc limit {$last} ) r2 order by {$order_by}" . $sql_suffix, false, $fetchrows);
     }
     # View Resources With No Downloads
     if (substr($search, 0, 12) == "!nodownloads") {
         if ($orig_order == "relevance") {
             $order_by = "ref desc";
         }
         return sql_query($sql_prefix . "select distinct r.hit_count score, {$select} from resource r {$sql_join}  where {$sql_filter} and ref not in (select distinct object_ref from daily_stat where activity_type='Resource download') order by {$order_by}" . $sql_suffix, false, $fetchrows);
     }
     # Duplicate Resources (based on file_checksum)
     if (substr($search, 0, 11) == "!duplicates") {
         # find duplicates of a given resource
         # Extract the resource ID
         $ref = explode(" ", $search);
         $ref = str_replace("!duplicates", "", $ref[0]);
         $ref = explode(",", $ref);
         // just get the number
         $ref = escape_check($ref[0]);
         if ($ref != "") {
             $results = sql_query("select distinct r.hit_count score, {$select} from resource r {$sql_join}  where {$sql_filter} and file_checksum= (select file_checksum from (select file_checksum from resource where archive = 0 and ref={$ref} and file_checksum is not null)r2) order by file_checksum", false, $fetchrows);
             $count = count($results);
             if ($count > 1) {
                 return $results;
             } else {
                 return false;
             }
         } else {
             return sql_query($sql_prefix . "select distinct r.hit_count score, {$select} from resource r {$sql_join}  where {$sql_filter} and file_checksum in (select file_checksum from (select file_checksum from resource where archive = 0 and file_checksum <> '' and file_checksum is not null group by file_checksum having count(file_checksum)>1)r2) order by file_checksum" . $sql_suffix, false, $fetchrows);
         }
     }
     # View Collection
     if (substr($search, 0, 11) == '!collection') {
         if ($orig_order == 'relevance') {
             $order_by = 'c.sortorder ASC, c.date_added DESC, r.ref DESC';
         }
         $colcustperm = $sql_join;
         $colcustfilter = $sql_filter;
         // to avoid allowing this sql_filter to be modified by the $access_override search in the smart collection update below!!!
         # Special case if a key has been provided.
         if (getval('k', '') != '') {
             $sql_filter = 'r.ref > 0';
         }
         # Extract the collection number
         $collection = explode(' ', $search);
         $collection = str_replace('!collection', '', $collection[0]);
         $collection = explode(',', $collection);
         // just get the number
         $collection = escape_check($collection[0]);
         # Check access
         if (!collection_readable($collection)) {
             return false;
         }
         # Smart collections update
         global $allow_smart_collections, $smart_collections_async;
         if ($allow_smart_collections) {
             global $smartsearch_ref_cache;
             if (isset($smartsearch_ref_cache[$collection])) {
                 $smartsearch_ref = $smartsearch_ref_cache[$collection];
                 // this value is pretty much constant
             } else {
                 $smartsearch_ref = sql_value('SELECT savedsearch value FROM collection WHERE ref="' . $collection . '"', '');
                 $smartsearch_ref_cache[$collection] = $smartsearch_ref;
             }
             global $php_path;
             if ($smartsearch_ref != '' && !$return_disk_usage) {
                 if ($smart_collections_async && isset($php_path) && file_exists($php_path . '/php')) {
                     exec($php_path . '/php ' . dirname(__FILE__) . '/../pages/ajax/update_smart_collection.php ' . escapeshellarg($collection) . ' ' . '> /dev/null 2>&1 &');
                 } else {
                     include dirname(__FILE__) . '/../pages/ajax/update_smart_collection.php';
                 }
             }
         }
         $result = sql_query($sql_prefix . "select distinct c.date_added,c.comment,c.purchase_size,c.purchase_complete,r.hit_count score,length(c.comment) commentset, {$select} from resource r  join collection_resource c on r.ref=c.resource {$colcustperm}  where c.collection='" . $collection . "' and {$colcustfilter} group by r.ref order by {$order_by}" . $sql_suffix, false, $fetchrows);
         hook('beforereturnresults', '', array($result, $archive));
         return $result;
     }
     # View Related
     if (substr($search, 0, 8) == "!related") {
         # Extract the resource number
         $resource = explode(" ", $search);
         $resource = str_replace("!related", "", $resource[0]);
         $order_by = str_replace("r.", "", $order_by);
         # UNION below doesn't like table aliases in the order by.
         global $pagename, $related_search_show_self;
         $sql_self = '';
         if ($related_search_show_self && $pagename == 'search') {
             $sql_self = " select distinct r.hit_count score, {$select} from resource r {$sql_join} where r.ref={$resource} and {$sql_filter} group by r.ref UNION ";
         }
         return sql_query($sql_prefix . $sql_self . "select distinct r.hit_count score, {$select} from resource r join resource_related t on (t.related=r.ref and t.resource='" . $resource . "') {$sql_join}  where 1=1 and {$sql_filter} group by r.ref \n        UNION\n        select distinct r.hit_count score, {$select} from resource r join resource_related t on (t.resource=r.ref and t.related='" . $resource . "') {$sql_join}  where 1=1 and {$sql_filter} group by r.ref \n        order by {$order_by}" . $sql_suffix, false, $fetchrows);
     }
     # Geographic search
     if (substr($search, 0, 4) == "!geo") {
         $geo = explode("t", str_replace(array("m", "p"), array("-", "."), substr($search, 4)));
         # Specially encoded string to avoid keyword splitting
         $bl = explode("b", $geo[0]);
         $tr = explode("b", $geo[1]);
         $sql = "select r.hit_count score, {$select} from resource r {$sql_join} where \n\n                    geo_lat > '" . escape_check($bl[0]) . "'\n              and   geo_lat < '" . escape_check($tr[0]) . "'        \n              and   geo_long > '" . escape_check($bl[1]) . "'       \n              and   geo_long < '" . escape_check($tr[1]) . "'       \n                          \n         and {$sql_filter} group by r.ref order by {$order_by}";
         return sql_query($sql_prefix . $sql . $sql_suffix, false, $fetchrows);
     }
     # Colour search
     if (substr($search, 0, 7) == "!colour") {
         $colour = explode(" ", $search);
         $colour = str_replace("!colour", "", $colour[0]);
         $sql = "select r.hit_count score, {$select} from resource r {$sql_join}\n                where \n                    colour_key like '" . escape_check($colour) . "%'\n                or  colour_key like '_" . escape_check($colour) . "%'\n                          \n         and {$sql_filter} group by r.ref order by {$order_by}";
         return sql_query($sql_prefix . $sql . $sql_suffix, false, $fetchrows);
     }
     # Similar to a colour
     if (substr($search, 0, 4) == "!rgb") {
         $rgb = explode(":", $search);
         $rgb = explode(",", $rgb[1]);
         return sql_query($sql_prefix . "select distinct r.hit_count score, {$select} from resource r {$sql_join}  where has_image=1 and {$sql_filter} group by r.ref order by (abs(image_red-" . $rgb[0] . ")+abs(image_green-" . $rgb[1] . ")+abs(image_blue-" . $rgb[2] . ")) asc limit 500" . $sql_suffix, false, $fetchrows);
     }
     # Has no preview image
     if (substr($search, 0, 10) == "!nopreview") {
         return sql_query($sql_prefix . "select distinct r.hit_count score, {$select} from resource r {$sql_join}  where has_image=0 and {$sql_filter} group by r.ref" . $sql_suffix, false, $fetchrows);
     }
     # Similar to a colour by key
     if (substr($search, 0, 10) == "!colourkey") {
         # Extract the colour key
         $colourkey = explode(" ", $search);
         $colourkey = str_replace("!colourkey", "", $colourkey[0]);
         return sql_query($sql_prefix . "select distinct r.hit_count score, {$select} from resource r {$sql_join}  where has_image=1 and left(colour_key,4)='" . $colourkey . "' and {$sql_filter} group by r.ref" . $sql_suffix, false, $fetchrows);
     }
     global $config_search_for_number;
     if ($config_search_for_number && is_numeric($search) || substr($search, 0, 9) == "!resource") {
         $theref = escape_check($search);
         $theref = preg_replace("/[^0-9]/", "", $theref);
         return sql_query($sql_prefix . "select distinct r.hit_count score, {$select} from resource r {$sql_join}  where r.ref='{$theref}' and {$sql_filter} group by r.ref" . $sql_suffix);
     }
     # Searching for pending archive
     if (substr($search, 0, 15) == "!archivepending") {
         return sql_query($sql_prefix . "select distinct r.hit_count score, {$select} from resource r {$sql_join}  where archive=1 and ref>0 group by r.ref order by {$order_by}" . $sql_suffix, false, $fetchrows);
     }
     if (substr($search, 0, 12) == "!userpending") {
         if ($orig_order == "rating") {
             $order_by = "request_count desc," . $order_by;
         }
         return sql_query($sql_prefix . "select distinct r.hit_count score, {$select} from resource r {$sql_join}  where archive=-1 and ref>0 group by r.ref order by {$order_by}" . $sql_suffix, false, $fetchrows);
     }
     # View Contributions
     if (substr($search, 0, 14) == "!contributions") {
         global $userref;
         # Extract the user ref
         $cuser = explode(" ", $search);
         $cuser = str_replace("!contributions", "", $cuser[0]);
         if ($userref == $cuser) {
             $sql_filter = "archive='{$archive}'";
             $sql_join = "";
         }
         # Disable permissions when viewing your own contributions - only restriction is the archive status
         $select = str_replace(",rca.access group_access,rca2.access user_access ", ",null group_access, null user_access ", $select);
         return sql_query($sql_prefix . "select distinct r.hit_count score, {$select} from resource r {$sql_join}  where created_by='" . $cuser . "' and r.ref > 0 and {$sql_filter} group by r.ref order by {$order_by}" . $sql_suffix, false, $fetchrows);
     }
     # Search for resources with images
     if ($search == "!images") {
         return sql_query($sql_prefix . "select distinct r.hit_count score, {$select} from resource r {$sql_join}  where has_image=1 group by r.ref order by {$order_by}" . $sql_suffix, false, $fetchrows);
     }
     # Search for resources not used in Collections
     if (substr($search, 0, 7) == "!unused") {
         return sql_query($sql_prefix . "SELECT distinct {$select} FROM resource r {$sql_join}  where r.ref>0 and r.ref not in (select c.resource from collection_resource c) and {$sql_filter}" . $sql_suffix, false, $fetchrows);
     }
     # Search for a list of resources
     # !listall = archive state is not applied as a filter to the list of resources.
     if (substr($search, 0, 5) == "!list") {
         $resources = explode(" ", $search);
         if (substr($search, 0, 8) == "!listall") {
             $resources = str_replace("!listall", "", $resources[0]);
         } else {
             $resources = str_replace("!list", "", $resources[0]);
         }
         $resources = explode(",", $resources);
         // separate out any additional keywords
         $resources = escape_check($resources[0]);
         if (strlen(trim($resources)) == 0) {
             $resources = "where r.ref IS NULL";
         } else {
             $resources = "where (r.ref='" . str_replace(":", "' OR r.ref='", $resources) . "')";
         }
         return sql_query($sql_prefix . "SELECT distinct r.hit_count score, {$select} FROM resource r {$sql_join} {$resources} and {$sql_filter} order by {$order_by}" . $sql_suffix, false, $fetchrows);
     }
     # View resources that have data in the specified field reference - useful if deleting unused fields
     if (substr($search, 0, 8) == "!hasdata") {
         $fieldref = intval(trim(substr($search, 8)));
         $sql_join .= " join resource_data on r.ref=resource_data.resource and resource_data.resource_type_field={$fieldref} and resource_data.value<>'' ";
         return sql_query($sql_prefix . "select distinct r.hit_count score, {$select} from resource r {$sql_join} and r.ref > 0 and {$sql_filter} group by r.ref order by {$order_by}" . $sql_suffix, false, $fetchrows);
     }
     # Within this hook implementation, set the value of the global $sql variable:
     # Since there will only be one special search executed at a time, only one of the
     # hook implementations will set the value.  So, you know that the value set
     # will always be the correct one (unless two plugins use the same !<type> value).
     $sql = "";
     hook("addspecialsearch", "", array($search));
     if ($sql != "") {
         debug("Addspecialsearch hook returned useful results.");
         return sql_query($sql_prefix . $sql . $sql_suffix, false, $fetchrows);
     }
     # -------------------------------------------------------------------------------------
     # Standard Searches
     # -------------------------------------------------------------------------------------
     # We've reached this far without returning.
     # This must be a standard (non-special) search.
     # Construct and perform the standard search query.
     #$sql="";
     if ($sql_filter != "") {
         if ($sql != "") {
             $sql .= " and ";
         }
         $sql .= $sql_filter;
     }
     # Append custom permissions
     $t .= $sql_join;
     if ($score == "") {
         $score = "r.hit_count";
     }
     # In case score hasn't been set (i.e. empty search)
     global $max_results;
     if ($t2 != "" && $sql != "") {
         $sql = " and " . $sql;
     }
     # Compile final SQL
     # Performance enhancement - set return limit to number of rows required
     if ($search_sql_double_pass_mode && $fetchrows != -1) {
         $max_results = $fetchrows;
     }
     $results_sql = $sql_prefix . "select distinct {$score} score, {$select} from resource r" . $t . "  where {$t2} {$sql} group by r.ref order by {$order_by} limit {$max_results}" . $sql_suffix;
     # Debug
     debug("altert " . $results_sql);
     # Execute query
     $result = sql_query($results_sql, false, $fetchrows);
     # Performance improvement - perform a second count-only query and pad the result array as necessary
     if ($search_sql_double_pass_mode && count($result) >= $max_results) {
         $count_sql = "select count(distinct r.ref) value from resource r" . $t . "  where {$t2} {$sql}";
         $count = sql_value($count_sql, 0);
         $result = array_pad($result, $count, 0);
     }
     debug("Search found " . count($result) . " results");
     if (count($result) > 0) {
         hook("beforereturnresults", "", array($result, $archive));
         return $result;
     }
     hook('zero_search_results');
     # (temp) - no suggestion for field-specific searching for now - TO DO: modify function below to support this
     if (strpos($search, ":") !== false) {
         return "";
     }
     # All keywords resolved OK, but there were no matches
     # Remove keywords, least used first, until we get results.
     $lsql = "";
     $omitmatch = false;
     for ($n = 0; $n < count($keywords); $n++) {
         if (substr($keywords[$n], 0, 1) == "-") {
             $omitmatch = true;
             $omit = $keywords[$n];
         }
         if ($lsql != "") {
             $lsql .= " or ";
         }
         $lsql .= "keyword='" . escape_check($keywords[$n]) . "'";
     }
     if ($omitmatch) {
         return trim_spaces(str_replace(" " . $omit . " ", " ", " " . join(" ", $keywords) . " "));
     }
     if ($lsql != "") {
         $least = sql_value("select keyword value from keyword where {$lsql} order by hit_count asc limit 1", "");
         return trim_spaces(str_replace(" " . $least . " ", " ", " " . join(" ", $keywords) . " "));
     } else {
         return array();
     }
 }
function HookImagestreamUpload_pluploadInitialuploadprocessing()
{
    #Support for uploading multi files as zip
    global $config_windows, $id, $targetDir, $resource_type, $imagestream_restypes, $imagestream_transitiontime, $zipcommand, $use_zip_extension, $userref, $session_hash, $filename, $filename_field, $collection_add, $archiver, $zipcommand, $ffmpeg_fullpath, $ffmpeg_preview_extension, $ffmpeg_preview_options, $ffmpeg_preview_min_height, $ffmpeg_preview_max_height, $ffmpeg_preview_min_width, $ffmpeg_preview_max_width, $lang, $collection_download_settings, $archiver_listfile_argument;
    $ffmpeg_fullpath = get_utility_path("ffmpeg");
    debug("DEBUG: Imagestream - checking restype: " . $resource_type . $imagestream_restypes);
    if (in_array($resource_type, $imagestream_restypes)) {
        debug("DEBUG: Imagestream - uploading file");
        #Check that we have an archiver configured
        $archiver_fullpath = get_utility_path("archiver");
        if (!isset($zipcommand) && !$use_zip_extension) {
            if ($archiver_fullpath == false) {
                exit($lang["archiver-utility-not-found"]);
            }
        }
        echo print_r($_POST) . print_r($_GET);
        if (getval("lastqueued", "")) {
            debug("DEBUG: Imagestream - last queued file");
            $ref = copy_resource(0 - $userref);
            # Copy from user template
            debug("DEBUG: Imagestream - creating resource: " . $ref);
            # Create the zip file
            $imagestreamzippath = get_resource_path($ref, true, "", true, "zip");
            if ($use_zip_extension) {
                $zip = new ZipArchive();
                $zip->open($imagestreamzippath, ZIPARCHIVE::CREATE);
            }
            $deletion_array = array();
            debug("DEBUG: opening directory: " . $targetDir);
            $imagestream_files = opendir($targetDir);
            $imagestream_workingfiles = get_temp_dir() . DIRECTORY_SEPARATOR . "plupload" . DIRECTORY_SEPARATOR . $session_hash . "workingfiles";
            if (!file_exists($imagestream_workingfiles)) {
                if ($config_windows) {
                    @mkdir($imagestream_workingfiles);
                } else {
                    @mkdir($imagestream_workingfiles, 0777, true);
                }
            }
            $filenumber = 00;
            $imagestream_filelist = array();
            while ($imagestream_filelist[] = readdir($imagestream_files)) {
                sort($imagestream_filelist);
            }
            closedir($imagestream_files);
            $imageindex = 1;
            foreach ($imagestream_filelist as $imagestream_file) {
                if ($imagestream_file != '.' && $imagestream_file != '..') {
                    $filenumber = sprintf("%03d", $filenumber);
                    $deletion_array[] = $targetDir . DIRECTORY_SEPARATOR . $imagestream_file;
                    if (!$use_zip_extension) {
                        $imagestreamcmd_file = get_temp_dir(false, $id) . "/imagestreamzipcmd" . $imagestream_file . ".txt";
                        $fh = fopen($imagestreamcmd_file, 'w') or die("can't open file");
                        fwrite($fh, $targetDir . DIRECTORY_SEPARATOR . $imagestream_file . "\r\n");
                        fclose($fh);
                        $deletion_array[] = $imagestreamcmd_file;
                    }
                    if ($use_zip_extension) {
                        debug("DEBUG: Imagestream - adding filename: " . $imagestream_file);
                        debug("DEBUG: using zip PHP extension, set up zip at : " . $imagestreamzippath);
                        $zip->addFile($imagestream_file);
                        debug(" Added files number : " . $zip->numFiles);
                        $wait = $zip->close();
                        debug("DEBUG: closed zip");
                    } else {
                        if ($archiver_fullpath) {
                            debug("DEBUG: using archiver, running command: \r\n" . $archiver_fullpath . " " . $collection_download_settings[0]["arguments"] . " " . escapeshellarg($imagestreamzippath) . " " . $archiver_listfile_argument . escapeshellarg($imagestream_file));
                            run_command($archiver_fullpath . " " . $collection_download_settings[0]["arguments"] . " " . escapeshellarg($imagestreamzippath) . " " . $archiver_listfile_argument . escapeshellarg($imagestreamcmd_file));
                        } else {
                            if (!$use_zip_extension) {
                                if ($config_windows) {
                                    debug("DEBUG: using zip command: . {$zipcommand} " . escapeshellarg($imagestreamzippath) . " @" . escapeshellarg($imagestreamcmd_file));
                                    exec("{$zipcommand} " . escapeshellarg($imagestreamzippath) . " @" . escapeshellarg($imagestreamcmd_file));
                                } else {
                                    # Pipe the command file, containing the filenames, to the executable.
                                    exec("{$zipcommand} " . escapeshellarg($imagestreamzippath) . " -@ < " . escapeshellarg($imagestreamcmd_file));
                                }
                            }
                        }
                    }
                    #Create a JPEG if not already in that format
                    $imagestream_file_parts = explode('.', $imagestream_file);
                    $imagestream_file_ext = $imagestream_file_parts[count($imagestream_file_parts) - 1];
                    $imagestream_file_noext = basename($imagestream_file, $imagestream_file_ext);
                    global $imagemagick_path, $imagemagick_quality;
                    $icc_transform_complete = false;
                    # Camera RAW images need prefix
                    if (preg_match('/^(dng|nef|x3f|cr2|crw|mrw|orf|raf|dcr)$/i', $imagestream_file_ext, $rawext)) {
                        $prefix = $rawext[0] . ':';
                    }
                    # Locate imagemagick.
                    $convert_fullpath = get_utility_path("im-convert");
                    if ($convert_fullpath == false) {
                        exit("Could not find ImageMagick 'convert' utility at location '{$imagemagick_path}'.");
                    }
                    $prefix = '';
                    if ($prefix == "cr2:" || $prefix == "nef:") {
                        $flatten = "";
                    } else {
                        $flatten = "-flatten";
                    }
                    $command = $convert_fullpath . ' ' . escapeshellarg($targetDir . DIRECTORY_SEPARATOR . $imagestream_file) . ' +matte ' . $flatten . ' -quality ' . $imagemagick_quality;
                    # EXPERIMENTAL CODE TO USE EXISTING ICC PROFILE IF PRESENT
                    global $icc_extraction, $icc_preview_profile, $icc_preview_options, $ffmpeg_supported_extensions;
                    if ($icc_extraction) {
                        $iccpath = $targetDir . DIRECTORY_SEPARATOR . $imagestream_file . '.icc';
                        if (!file_exists($iccpath) && !isset($iccfound) && $extension != "pdf" && !in_array($imagestream_file_ext, $ffmpeg_supported_extensions)) {
                            // extracted profile doesn't exist. Try extracting.
                            if (extract_icc_profile($ref, $imagestream_file_ext)) {
                                $iccfound = true;
                            } else {
                                $iccfound = false;
                            }
                        }
                    }
                    if ($icc_extraction && file_exists($iccpath) && !$icc_transform_complete) {
                        // we have an extracted ICC profile, so use it as source
                        $targetprofile = dirname(__FILE__) . '/../iccprofiles/' . $icc_preview_profile;
                        $profile = " +profile \"*\" -profile {$iccpath} {$icc_preview_options} -profile {$targetprofile} +profile \"*\" ";
                        $icc_transform_complete = true;
                    } else {
                        // use existing strategy for color profiles
                        # Preserve colour profiles? (omit for smaller sizes)
                        $profile = "+profile \"*\" -colorspace RGB";
                        # By default, strip the colour profiles ('+' is remove the profile, confusingly)
                        #if ($imagemagick_preserve_profiles && $id!="thm" && $id!="col" && $id!="pre" && $id!="scr") {$profile="";}
                    }
                    $runcommand = $command . " +matte {$profile} " . escapeshellarg($imagestream_workingfiles . DIRECTORY_SEPARATOR . "imagestream" . $filenumber . ".jpg");
                    $deletion_array[] = $imagestream_workingfiles . DIRECTORY_SEPARATOR . "imagestream" . $filenumber . ".jpg";
                    $output = run_command($runcommand);
                    debug("processed file" . $filenumber . ": " . $imagestream_file . "\r\n");
                    debug("Image index: " . $imageindex . ". file count: " . count($imagestream_filelist));
                    if ($filenumber == 00) {
                        $snapshotsize = getimagesize($imagestream_workingfiles . DIRECTORY_SEPARATOR . "imagestream" . $filenumber . ".jpg");
                        list($width, $height) = $snapshotsize;
                        # Frame size must be a multiple of two
                        if ($width % 2) {
                            $width++;
                        }
                        if ($height % 2) {
                            $height++;
                        }
                    }
                    if ($imageindex == count($imagestream_filelist) - 1) {
                        $additionalfile = $filenumber + 1;
                        $additionalfile = sprintf("%03d", $additionalfile);
                        copy($imagestream_workingfiles . DIRECTORY_SEPARATOR . "imagestream" . $filenumber . ".jpg", $imagestream_workingfiles . DIRECTORY_SEPARATOR . "imagestream" . $additionalfile . ".jpg");
                        $deletion_array[] = $imagestream_workingfiles . DIRECTORY_SEPARATOR . "imagestream" . $additionalfile . ".jpg";
                    }
                    $filenumber++;
                }
                #end of loop for each uploadedfile
                $imageindex++;
            }
            #Add the resource and move this zip file, set extension
            # Add to collection?
            if ($collection_add != "") {
                add_resource_to_collection($ref, $collection_add);
            }
            # Log this
            daily_stat("Resource upload", $ref);
            resource_log($ref, "u", 0);
            #Change this!!!!!!!!!!!
            #$status=upload_file($ref,true,false,false));
            if (!$config_windows) {
                @chmod($imagestreamzippath, 0777);
            }
            # Store extension in the database and update file modified time.
            sql_query("update resource set file_extension='zip',preview_extension='zip',file_modified=now(), has_image=0 where ref='{$ref}'");
            #update_field($ref,$filename_field,$filename);
            update_disk_usage($ref);
            # create the mp4 version
            # Add a new alternative file
            $aref = add_alternative_file($ref, "MP4 version");
            $imagestreamqtfile = get_resource_path($ref, true, "", false, "mp4", -1, 1, false, "", $aref);
            $shell_exec_cmd = $ffmpeg_fullpath . " -loglevel panic -y -r " . $imagestream_transitiontime . " -i " . $imagestream_workingfiles . DIRECTORY_SEPARATOR . "imagestream%3d.jpg -r " . $imagestream_transitiontime . " -s {$width}x{$height} " . $imagestreamqtfile;
            echo "Running command: " . $shell_exec_cmd;
            if ($config_windows) {
                $shell_exec_cmd = $ffmpeg_fullpath . " -loglevel panic -y -r " . $imagestream_transitiontime . " -i " . $imagestream_workingfiles . DIRECTORY_SEPARATOR . "imagestream%%3d.jpg -r " . $imagestream_transitiontime . " -s {$width}x{$height} " . $imagestreamqtfile;
                file_put_contents(get_temp_dir() . DIRECTORY_SEPARATOR . "imagestreammp4" . $session_hash . ".bat", $shell_exec_cmd);
                $shell_exec_cmd = get_temp_dir() . DIRECTORY_SEPARATOR . "imagestreammp4" . $session_hash . ".bat";
                $deletion_array[] = $shell_exec_cmd;
            }
            run_command($shell_exec_cmd);
            debug("DEBUG created slideshow MP4 video");
            if (!$config_windows) {
                @chmod($imagestreamqtfile, 0777);
            }
            $file_size = @filesize_unlimited($imagestreamqtfile);
            # Save alternative file data.
            sql_query("update resource_alt_files set file_name='quicktime.mp4',file_extension='mp4',file_size='" . $file_size . "',creation_date=now() where resource='{$ref}' and ref='{$aref}'");
            #create the FLV preview as per normal video processing if possible?
            if ($height < $ffmpeg_preview_min_height) {
                $height = $ffmpeg_preview_min_height;
            }
            if ($width < $ffmpeg_preview_min_width) {
                $width = $ffmpeg_preview_min_width;
            }
            if ($height > $ffmpeg_preview_max_height) {
                $width = ceil($width * ($ffmpeg_preview_max_height / $height));
                $height = $ffmpeg_preview_max_height;
            }
            if ($width > $ffmpeg_preview_max_width) {
                $height = ceil($height * ($ffmpeg_preview_max_width / $width));
                $width = $ffmpeg_preview_max_width;
            }
            $flvzippreviewfile = get_resource_path($ref, true, "pre", false, $ffmpeg_preview_extension);
            $shell_exec_cmd = $ffmpeg_fullpath . " -loglevel panic -y -i " . $imagestreamqtfile . " {$ffmpeg_preview_options} -s {$width}x{$height} " . $flvzippreviewfile;
            debug("Running command: " . $shell_exec_cmd);
            if ($config_windows) {
                file_put_contents(get_temp_dir() . DIRECTORY_SEPARATOR . "imagestreamflv" . $session_hash . ".bat", $shell_exec_cmd);
                $shell_exec_cmd = get_temp_dir() . DIRECTORY_SEPARATOR . "imagestreamflv" . $session_hash . ".bat";
                $deletion_array[] = $shell_exec_cmd;
            }
            run_command($shell_exec_cmd);
            debug("DEBUG created slideshow FLV video");
            if (!$config_windows) {
                @chmod($flvzippreviewfile, 0777);
            }
            #Tidy up
            rcRmdir($imagestream_workingfiles);
            rcRmdir($targetDir);
            foreach ($deletion_array as $tmpfile) {
                debug("\r\nDEBUG: Deleting: " . $tmpfile);
                delete_exif_tmpfile($tmpfile);
            }
            echo "SUCCESS";
            #return true;
            exit;
        } else {
            echo "SUCCESS";
            exit;
        }
        return true;
    } else {
        return false;
    }
}
예제 #11
0
            ?>
		parent.document.getElementById("dosearch").value="<?php 
            echo $lang["view"] . " " . number_format($count) . " " . $lang["matchingresources"];
            ?>
";
		parent.document.getElementById("dosearch").disabled=false;
		<?php 
        }
        ?>
		</script>
		</html>
		<?php 
        exit;
    } else {
        # Log this
        daily_stat("Advanced search", $userref);
        redirect("pages/search.php?search=" . urlencode($search) . "&archive=" . $archive);
    }
}
# Reconstruct a values array based on the search keyword, so we can pre-populate the form from the current search
$search = @$_COOKIE["search"];
$keywords = explode(",", $search);
$allwords = "";
$found_year = "";
$found_month = "";
$found_day = "";
$values = array();
for ($n = 0; $n < count($keywords); $n++) {
    $keyword = $keywords[$n];
    if (strpos($keyword, ":") !== false) {
        $k = explode(":", $keyword);
예제 #12
0
$ref = getvalescaped("ref", "", true);
$resource = get_resource_data($ref);
# check permissions (error message is not pretty but they shouldn't ever arrive at this page unless entering a URL manually)
if (!checkperm("v") && $resource["access"] == 2) {
    exit("This is a confidential resource.");
}
# Get story text
$fields = get_resource_field_data($ref);
$storyextract = "";
for ($n = 0; $n < count($fields); $n++) {
    if ($fields[$n]["title"] == "Story Extract") {
        $storyextract = $fields[$n]["value"];
    }
}
# Log this activity
daily_stat("Print story", $ref);
?>
<html>
<head><title><?php 
echo $applicationname;
?>
 <?php 
echo $lang["storyextract"];
?>
</title>
<style>
body {font-family:verdana,arial,sans-serif;font-size:12px;}
h1 {font-size:16px;}
h2 {font-size:14px;}
.footer {font-size:10px;margin-top:30px;}
</style>
예제 #13
0
        echo $search_title_links;
        hook("beforesearchresults2");
        hook("beforesearchresultsexpandspace");
        ?>
	<div class="clearerleft"></div>
	<div id="CentralSpaceResources">
	<?php 
        //exit("HERE" . print_r($result));
        if ((!is_array($result) || count($result) < 1) && empty($collections)) {
            // No matches found? Log this in
            $key_id = resolve_keyword($search);
            if ($key_id === FALSE) {
                $key_id = resolve_keyword($search, TRUE);
                daily_stat('Keyword usage', $key_id);
            }
            daily_stat("Keyword usage - no results found", $key_id);
            ?>
		<div class="BasicsBox"> 
		  <div class="NoFind">
			<p><?php 
            echo $lang["searchnomatches"];
            ?>
</p>
			<?php 
            if (!$collectionsearch) {
                if ($result != "" && !is_array($result)) {
                    ?>
					<p><?php 
                    echo $lang["try"];
                    ?>
: <a onClick="return CentralSpaceLoad(this,true);" href="<?php 
예제 #14
0
 } else {
     $no_exif = getval("no_exif", "");
 }
 $autorotate = getval("autorotate", "");
 if ($upload_collection_name_required) {
     if (getvalescaped("entercolname", "") == "" && getval("collection_add", "") == -1) {
         if (!is_array($save_errors)) {
             $save_errors = array();
         }
         $save_errors['collectionname'] = $lang["requiredfield"];
     }
 }
 if (($save_errors === true || $is_template) && getval("tweak", "") == "") {
     if ($ref > 0 && getval("save", "") != "") {
         # Log this
         daily_stat("Resource edit", $ref);
         if (!hook('redirectaftersave')) {
             redirect($baseurl_short . "pages/view.php?ref=" . urlencode($ref) . "&search=" . urlencode($search) . "&offset=" . urlencode($offset) . "&order_by=" . urlencode($order_by) . "&sort=" . urlencode($sort) . "&archive=" . urlencode($archive) . "&refreshcollectionframe=true");
         }
     } else {
         if (getval("uploader", "") != "" && getval("uploader", "") != "local") {
             # Save button pressed? Move to next step.
             if (getval("save", "") != "") {
                 redirect($baseurl_short . "pages/upload_" . getval("uploader", "") . ".php?collection_add=" . getval("collection_add", "") . "&entercolname=" . urlencode(getvalescaped("entercolname", "")) . "&resource_type=" . urlencode($resource_type) . "&no_exif=" . urlencode($no_exif) . "&autorotate=" . urlencode($autorotate) . "&themestring=" . urlencode(getval('themestring', '')) . "&public=" . urlencode(getval('public', '')) . " &archive=" . urlencode($archive) . $uploadparams . hook("addtouploadurl"));
             }
         } elseif (getval("local", "") != "" || getval("uploader", "") == "local") {
             # Save button pressed? Move to next step.
             if (getval("save", "") != "") {
                 redirect($baseurl_short . "pages/team/team_batch_select.php?use_local=yes&collection_add=" . getval("collection_add", "") . "&entercolname=" . urlencode(getvalescaped("entercolname", "")) . "&resource_type=" . urlencode($resource_type) . "&no_exif=" . $no_exif . "&autorotate=" . $autorotate . $uploadparams);
             }
         } elseif (getval("single", "") != "") {
    } else {
        $from_name = $userfullname;
    }
    // make sure from_name matches email
    if (getval("ccme", false)) {
        $cc = $useremail;
    } else {
        $cc = "";
    }
    $errors = email_collection($ref, i18n_get_collection_name($collection), $userfullname, $users, $message, $feedback, $access, $expires, $user_email, $from_name, $cc, $themeshare, $themename, $linksuffix, $list_recipients, $add_internal_access, $group);
    if ($errors == "") {
        # Log this
        // fix for bomb on multiple collections, daily stat object ref must be a single number.
        $crefs = explode(",", $ref);
        foreach ($crefs as $cref) {
            daily_stat("E-mailed collection", $cref);
        }
        if (!hook("replacecollectionemailredirect")) {
            redirect($baseurl_short . "pages/done.php?text=collection_email");
        }
    }
}
if ($collection_dropdown_user_access_mode) {
    $users = get_users();
}
include "../include/header.php";
?>
<div class="BasicsBox">
<h1><?php 
if ($themeshare) {
    echo $lang["email_theme_category"];
예제 #16
0
function copy_resource($from,$resource_type=-1)
	{
	# Create a new resource, copying all data from the resource with reference $from.
	# Note this copies only the data and not any attached file. It's very unlikely the
	# same file would be in the system twice, however users may want to clone an existing resource
	# to avoid reentering data if the resource is very similar.
	# If $resource_type if specified then the resource type for the new resource will be set to $resource_type
	# rather than simply copied from the $from resource.
	
	# Check that the resource exists
	if (sql_value("select count(*) value from resource where ref='$from'",0)==0) {return false;}
	
	# copy joined fields to the resource column
	$joins=get_resource_table_joins();
	$joins_sql="";
	foreach ($joins as $join){
		$joins_sql.=",field$join ";
	}
	
	$add="";

	# Work out the archive status
	$archive=sql_value("select archive value from resource where ref='$from'",0);
	if (!checkperm("e" . $archive))
		{
		# Find the right permission mode to use
		for ($n=-2;$n<3;$n++)
			{
			if (checkperm("e" . $n)) {$archive=$n;break;}
			}
		}

	# First copy the resources row
	sql_query("insert into resource($add resource_type,creation_date,rating,archive,access,created_by $joins_sql) select $add" . (($resource_type==-1)?"resource_type":("'" . $resource_type . "'")) . ",now(),rating,'" . $archive . "',access,created_by $joins_sql from resource where ref='$from';");
	$to=sql_insert_id();
	
	# Copying a resource of the 'pending review' state? Notify, if configured.
	$archive=sql_value("select archive value from resource where ref='$from'",0);
	if ($archive==-1)
		{
		notify_user_contributed_submitted(array($to));
		}
	
	# Set that this resource was created by this user. 
	# This needs to be done if either:
	# 1) The user does not have direct 'resource create' permissions and is therefore contributing using My Contributions directly into the active state
	# 2) The user is contributiting via My Contributions to the standard User Contributed pre-active states.
	global $userref;
	global $always_record_resource_creator;
	if ((!checkperm("c")) || $archive<0 || (isset($always_record_resource_creator) && $always_record_resource_creator))
		{
		# Update the user record
		sql_query("update resource set created_by='$userref' where ref='$to'");

		# Also add the user's username and full name to the keywords index so the resource is searchable using this name.
		global $username,$userfullname;
		add_keyword_mappings($to,$username . " " . $userfullname,-1);
		}
	
	# Now copy all data
	sql_query("insert into resource_data(resource,resource_type_field,value) select '$to',rd.resource_type_field,rd.value from resource_data rd join resource r on rd.resource=r.ref join resource_type_field rtf on rd.resource_type_field=rtf.ref and (rtf.resource_type=r.resource_type or rtf.resource_type=999 or rtf.resource_type=0) where rd.resource='$from'");
	
	# Copy relationships
	sql_query("insert into resource_related(resource,related) select '$to',related from resource_related where resource='$from'");

	# Copy access
	sql_query("insert into resource_custom_access(resource,usergroup,access) select '$to',usergroup,access from resource_custom_access where resource='$from'");

	# Set any resource defaults
	set_resource_defaults($to);

	# Reindex the resource so the resource_keyword entries are created
	reindex_resource($to);
	
	# Log this			
	daily_stat("Create resource",$to);
	resource_log($to,'c',0);

	hook("afternewresource", "", array($to));
	
	return $to;
	}
                    sql_query("update user set logged_in=0,session='' where ref='{$userref}'");
                    hook("removeuseridcookie");
                    # Blank cookie / var
                    rs_setcookie("user", "", time() - 3600, "", "", substr($baseurl, 0, 5) == "https", true);
                    unset($username);
                    if (isset($anonymous_login)) {
                        # If the system is set up with anonymous access, redirect to the home page after logging out.
                        redirect("pages/" . $default_home_page);
                    } else {
                        $valid = false;
                        $autologgedout = true;
                    }
                } else {
                    # Session end reached, but the user may still remain logged in.
                    # This is a new 'session' for the purposes of statistics.
                    daily_stat("User session", $userref);
                }
            }
        }
    } else {
        $valid = false;
    }
} else {
    $valid = false;
    $nocookies = true;
    # Set a cookie that we'll check for again on the login page after the redirection.
    # If this cookie is missing, it's assumed that cookies are switched off or blocked and a warning message is displayed.
    setcookie("cookiecheck", "true", 0, '/', '', false, true);
    hook("removeuseridcookie");
}
if (!$valid && !$api && !isset($system_login)) {
예제 #18
0
<?php
include "../include/db.php";
include "../include/authenticate.php";
include "../include/general.php";
include "../include/research_functions.php";

if (getval("save","")!="")
	{
	$errors=false;
	if (getvalescaped("name","")=="") {$errors=true;$error_name=true;}
	if (getvalescaped("description","")=="") {$errors=true;$error_description=true;}
	if (isset($anonymous_login) && $anonymous_login==$username && getvalescaped("email","")=="") {$errors=true;$error_email=true;}
	if ($errors==false) 
		{
		# Log this
		daily_stat("New research request",0);

		send_research_request();
		redirect($baseurl_short."pages/done.php?text=research_request");
		}
	}

include "../include/header.php";
?>

<div class="BasicsBox">
<h1><?php echo $lang["researchrequest"]?></h1>
<p class="tight"><?php echo text("introtext")?></p>
<form method="post" action="<?php echo $baseurl_short?>pages/research_request.php">

<?php if (getval("assign","")!="") { ?>
예제 #19
0
	{
	$restypes=getvalescaped("restypes","");
	}
else
	{ 
	$restypes="";
	reset($_POST);reset($_GET);foreach (array_merge($_GET, $_POST) as $key=>$value)

		{
		if ($key=="rttickall" && $value=="on"){$restypes="";break;}	
		if (substr($key,0,8)=="resource") {if ($restypes!="") {$restypes.=",";} $restypes.=substr($key,8);}
		}
	setcookie("restypes",$restypes);

	# This is a new search, log this activity
	if ($archive==2) {daily_stat("Archive search",0);} else {daily_stat("Search",0);}
	}

# if search is not a special search (ie. !recent), use starsearchvalue.
if (getvalescaped("search","")!="" && strpos(getvalescaped("search",""),"!")!==false)
	{
	$starsearch="";
	}
else
	{
	$starsearch=getvalescaped("starsearch","");	
	setcookie("starsearch",$starsearch);
}

# If returning to an old search, restore the page/order by
if (!array_key_exists("search",$_GET) && !array_key_exists("search",$_POST))
예제 #20
0
			foreach ($crefs as $cref){		
				daily_stat("E-mailed collection",$cref);
			}
			if (!hook("replacecollectionemailredirect")){
				redirect($baseurl_short."pages/done.php?text=collection_email");
				}
			}
		}
	else
		{
		// Email single resource
		$errors=email_resource($ref,i18n_get_translated($resource["field".$view_title_field]),$userfullname,$users,$message,$access,$expires,$user_email,$from_name,$cc,$list_recipients,$add_internal_access,$useraccess,$group);
		if ($errors=="")
			{
			// Log this			
			daily_stat("E-mailed resource",$ref);
			if (!hook("replaceresourceemailredirect")){
				redirect("pages/done.php?text=resource_email&resource=".urlencode($ref)."&search=".urlencode($search)."&offset=".urlencode($offset)."&order_by=".urlencode($order_by)."&sort=".urlencode($sort)."&archive=".urlencode($archive));
			}
			}
		}
	}

include "../include/header.php";
?>
<div class="BasicsBox">
<p><a onClick="return CentralSpaceLoad(this,true);" href="<?php echo $baseurl_short?>pages/view.php?ref=<?php echo urlencode($ref) ?>&search=<?php echo urlencode($search)?>&offset=<?php echo urlencode($offset)?>&order_by=<?php echo urlencode($order_by)?>&sort=<?php echo urlencode($sort)?>&archive=<?php echo urlencode($archive)?>">&lt;&nbsp;<?php echo $lang["backtoresourceview"]?></a></p>
<h1><?php echo $lang["emailresourcetitle"]?></h1>

<p><?php echo text("introtext")?></p>
예제 #21
0
 function do_search($search, $restypes = "", $order_by = "relevance", $archive = 0, $fetchrows = -1, $sort = "desc", $access_override = false, $starsearch = 0, $ignore_filters = false, $return_disk_usage = false)
 {
     debug("search={$search} restypes={$restypes} archive={$archive}");
     # globals needed for hooks
     global $sql, $order, $select, $sql_join, $sql_filter, $orig_order, $checkbox_and, $collections_omit_archived, $search_sql_double_pass_mode;
     # Takes a search string $search, as provided by the user, and returns a results set
     # of matching resources.
     # If there are no matches, instead returns an array of suggested searches.
     # $restypes is optionally used to specify which resource types to search.
     # $access_override is used by smart collections, so that all all applicable resources can be judged regardless of the final access-based results
     # resolve $order_by to something meaningful in sql
     $orig_order = $order_by;
     global $date_field;
     $order = array("relevance" => "score {$sort}, user_rating {$sort}, hit_count {$sort}, field{$date_field} {$sort},r.ref {$sort}", "popularity" => "user_rating {$sort},hit_count {$sort},field{$date_field} {$sort},r.ref {$sort}", "rating" => "r.rating {$sort}, user_rating {$sort}, score {$sort},r.ref {$sort}", "date" => "field{$date_field} {$sort},r.ref {$sort}", "colour" => "has_image {$sort},image_blue {$sort},image_green {$sort},image_red {$sort},field{$date_field} {$sort},r.ref {$sort}", "country" => "country {$sort},r.ref {$sort}", "title" => "title {$sort},r.ref {$sort}", "file_path" => "file_path {$sort},r.ref {$sort}", "resourceid" => "r.ref {$sort}", "resourcetype" => "resource_type {$sort},r.ref {$sort}", "titleandcountry" => "title {$sort},country {$sort}", "random" => "RAND()");
     if (!in_array($order_by, $order) && substr($order_by, 0, 5) == "field") {
         $order[$order_by] = "{$order_by} {$sort}";
     }
     hook("modifyorderarray");
     # Recognise a quoted search, which is a search for an exact string
     $quoted_string = false;
     if (substr($search, 0, 1) == "\"" && substr($search, -1, 1) == "\"") {
         $quoted_string = true;
         $search = substr($search, 1, -1);
     }
     $order_by = $order[$order_by];
     $keywords = split_keywords($search);
     $search = trim($search);
     # -- Build up filter SQL that will be used for all queries
     $sql_filter = "";
     # append resource type filtering
     if ($restypes != "") {
         if ($sql_filter != "") {
             $sql_filter .= " and ";
         }
         $restypes_x = explode(",", $restypes);
         $sql_filter .= "resource_type in ('" . join("','", $restypes_x) . "')";
     }
     if ($starsearch != "" && $starsearch != 0) {
         if ($sql_filter != "") {
             $sql_filter .= " and ";
         }
         $sql_filter .= "user_rating >= '{$starsearch}'";
     }
     # If returning disk used by the resources in the search results ($return_disk_usage=true) then wrap the returned SQL in an outer query that sums disk usage.
     $sql_prefix = "";
     $sql_suffix = "";
     if ($return_disk_usage) {
         $sql_prefix = "select sum(disk_usage) total_disk_usage,count(*) total_resources from (";
         $sql_suffix = ") resourcelist";
     }
     # append resource type restrictions based on 'T' permission
     # look for all 'T' permissions and append to the SQL filter.
     global $userpermissions;
     $rtfilter = array();
     for ($n = 0; $n < count($userpermissions); $n++) {
         if (substr($userpermissions[$n], 0, 1) == "T") {
             $rt = substr($userpermissions[$n], 1);
             if (is_numeric($rt) && !$access_override) {
                 $rtfilter[] = $rt;
             }
         }
     }
     if (count($rtfilter) > 0) {
         if ($sql_filter != "") {
             $sql_filter .= " and ";
         }
         $sql_filter .= "resource_type not in (" . join(",", $rtfilter) . ")";
     }
     # append "use" access rights, do not show restricted resources unless admin
     if (!checkperm("v") && !$access_override) {
         if ($sql_filter != "") {
             $sql_filter .= " and ";
         }
         $sql_filter .= "r.access<>'2'";
     }
     # append archive searching (don't do this for collections or !listall, archived resources can still appear in these searches)
     if (substr($search, 0, 8) != "!listall" && substr($search, 0, 11) != "!collection" || $collections_omit_archived && !checkperm("e2")) {
         global $pending_review_visible_to_all;
         if ($archive == 0 && $pending_review_visible_to_all) {
             # If resources pending review are visible to all, when listing only active resources include
             # pending review (-1) resources too.
             if ($sql_filter != "") {
                 $sql_filter .= " and ";
             }
             $sql_filter .= "(archive='0' or archive=-1)";
         } else {
             # Append normal filtering.
             if ($sql_filter != "") {
                 $sql_filter .= " and ";
             }
             $sql_filter .= "archive='{$archive}'";
         }
     }
     # append ref filter - never return the batch upload template (negative refs)
     if ($sql_filter != "") {
         $sql_filter .= " and ";
     }
     $sql_filter .= "r.ref>0";
     # ------ Advanced 'custom' permissions, need to join to access table.
     $sql_join = "";
     global $k;
     if (!checkperm("v") && !$access_override) {
         global $usergroup;
         global $userref;
         # one extra join (rca2) is required for user specific permissions (enabling more intelligent watermarks in search view)
         # the original join is used to gather group access into the search query as well.
         $sql_join = " left outer join resource_custom_access rca2 on r.ref=rca2.resource and rca2.user='******'  and (rca2.user_expires is null or rca2.user_expires>now()) and rca2.access<>2  ";
         $sql_join .= " left outer join resource_custom_access rca on r.ref=rca.resource and rca.usergroup='{$usergroup}' and rca.access<>2 ";
         if ($sql_filter != "") {
             $sql_filter .= " and ";
         }
         # If rca.resource is null, then no matching custom access record was found
         # If r.access is also 3 (custom) then the user is not allowed access to this resource.
         # Note that it's normal for null to be returned if this is a resource with non custom permissions (r.access<>3).
         $sql_filter .= " not(rca.resource is null and r.access=3)";
     }
     # Join thumbs_display_fields to resource table
     $select = "r.ref, r.resource_type, r.has_image, r.is_transcoding, r.hit_count, r.creation_date, r.rating, r.user_rating, r.user_rating_count, r.user_rating_total, r.file_extension, r.preview_extension, r.image_red, r.image_green, r.image_blue, r.thumb_width, r.thumb_height, r.archive, r.access, r.colour_key, r.created_by, r.file_modified, r.file_checksum, r.request_count, r.new_hit_count, r.expiry_notification_sent, r.preview_tweaks, r.file_path ";
     $modified_select = hook("modifyselect");
     if ($modified_select) {
         $select .= $modified_select;
     }
     $modified_select2 = hook("modifyselect2");
     if ($modified_select2) {
         $select .= $modified_select2;
     }
     # Return disk usage for each resource if returning sum of disk usage.
     if ($return_disk_usage) {
         $select .= ",r.disk_usage";
     }
     # select group and user access rights if available, otherwise select null values so columns can still be used regardless
     # this makes group and user specific access available in the basic search query, which can then be passed through access functions
     # in order to eliminate many single queries.
     if (!checkperm("v") && !$access_override) {
         $select .= ",rca.access group_access,rca2.access user_access ";
     } else {
         $select .= ",null group_access, null user_access ";
     }
     # add 'joins' to select (adding them
     $joins = get_resource_table_joins();
     foreach ($joins as $datajoin) {
         $select .= ",r.field" . $datajoin . " ";
     }
     # Prepare SQL to add join table for all provided keywods
     $suggested = $keywords;
     # a suggested search
     $fullmatch = true;
     $c = 0;
     $t = "";
     $t2 = "";
     $score = "";
     $keysearch = true;
     # Do not process if a numeric search is provided (resource ID)
     global $config_search_for_number, $category_tree_search_use_and;
     if ($config_search_for_number && is_numeric($search)) {
         $keysearch = false;
     }
     if ($keysearch) {
         for ($n = 0; $n < count($keywords); $n++) {
             $keyword = $keywords[$n];
             if (substr($keyword, 0, 1) != "!") {
                 global $date_field;
                 $field = 0;
                 #echo "<li>$keyword<br/>";
                 if (strpos($keyword, ":") !== false && !$ignore_filters) {
                     $kw = explode(":", $keyword, 2);
                     if ($kw[0] == "day") {
                         if ($sql_filter != "") {
                             $sql_filter .= " and ";
                         }
                         $sql_filter .= "r.field{$date_field} like '____-__-" . $kw[1] . "%' ";
                     } elseif ($kw[0] == "month") {
                         if ($sql_filter != "") {
                             $sql_filter .= " and ";
                         }
                         $sql_filter .= "r.field{$date_field} like '____-" . $kw[1] . "%' ";
                     } elseif ($kw[0] == "year") {
                         if ($sql_filter != "") {
                             $sql_filter .= " and ";
                         }
                         $sql_filter .= "r.field{$date_field} like '" . $kw[1] . "%' ";
                     } else {
                         $ckeywords = explode(";", $kw[1]);
                         # Fetch field info
                         $fieldinfo = sql_query("select ref,type from resource_type_field where name='" . escape_check($kw[0]) . "'", 0);
                         if (count($fieldinfo) == 0) {
                             debug("Field short name not found.");
                             return false;
                         } else {
                             $fieldinfo = $fieldinfo[0];
                         }
                         # Special handling for dates
                         if ($fieldinfo["type"] == 4 || $fieldinfo["type"] == 6) {
                             $ckeywords = array(str_replace(" ", "-", $kw[1]));
                         }
                         $field = $fieldinfo["ref"];
                         #special SQL generation for category trees to use AND instead of OR
                         if ($fieldinfo["type"] == 7 && $category_tree_search_use_and || $fieldinfo["type"] == 2 && $checkbox_and) {
                             for ($m = 0; $m < count($ckeywords); $m++) {
                                 $keyref = resolve_keyword($ckeywords[$m]);
                                 if (!($keyref === false)) {
                                     $c++;
                                     # Add related keywords
                                     $related = get_related_keywords($keyref);
                                     $relatedsql = "";
                                     for ($r = 0; $r < count($related); $r++) {
                                         $relatedsql .= " or k" . $c . ".keyword='" . $related[$r] . "'";
                                     }
                                     # Form join
                                     //$sql_join.=" join (SELECT distinct k".$c.".resource,k".$c.".hit_count from resource_keyword k".$c." where k".$c.".keyword='$keyref' $relatedsql) t".$c." ";
                                     $sql_join .= " join resource_keyword k" . $c . " on k" . $c . ".resource=r.ref and k" . $c . ".resource_type_field='" . $field . "' and (k" . $c . ".keyword='{$keyref}' {$relatedsql})";
                                     if ($score != "") {
                                         $score .= "+";
                                     }
                                     $score .= "k" . $c . ".hit_count";
                                     # Log this
                                     daily_stat("Keyword usage", $keyref);
                                 }
                             }
                         } else {
                             $c++;
                             $sql_join .= " join resource_keyword k" . $c . " on k" . $c . ".resource=r.ref and k" . $c . ".resource_type_field='" . $field . "'";
                             if ($score != "") {
                                 $score .= "+";
                             }
                             $score .= "k" . $c . ".hit_count";
                             # work through all options in an OR approach for multiple selects on the same field
                             # where k.resource=type_field=$field and (k*.keyword=3 or k*.keyword=4) etc
                             $keyjoin = "";
                             for ($m = 0; $m < count($ckeywords); $m++) {
                                 $keyref = resolve_keyword($ckeywords[$m]);
                                 if ($keyref === false) {
                                     $keyref = -1;
                                 }
                                 if ($m != 0) {
                                     $keyjoin .= " OR ";
                                 }
                                 $keyjoin .= "k" . $c . ".keyword='{$keyref}'";
                                 # Also add related.
                                 $related = get_related_keywords($keyref);
                                 for ($o = 0; $o < count($related); $o++) {
                                     $keyjoin .= " OR k" . $c . ".keyword='" . $related[$o] . "'";
                                 }
                                 # Log this
                                 daily_stat("Keyword usage", $keyref);
                             }
                             if ($keyjoin != "") {
                                 $sql_join .= " and (" . $keyjoin . ")";
                             }
                         }
                     }
                 } else {
                     # Normal keyword (not tied to a field) - searches all fields
                     # If ignoring field specifications then remove them.
                     if (strpos($keyword, ":") !== false && $ignore_filters) {
                         $s = explode(":", $keyword);
                         $keyword = $s[1];
                     }
                     # Omit resources containing this keyword?
                     $omit = false;
                     if (substr($keyword, 0, 1) == "-") {
                         $omit = true;
                         $keyword = substr($keyword, 1);
                     }
                     global $noadd, $wildcard_always_applied;
                     if (in_array($keyword, $noadd)) {
                         $skipped_last = true;
                     } else {
                         # Handle wildcards
                         if (strpos($keyword, "*") !== false || $wildcard_always_applied) {
                             if ($wildcard_always_applied && strpos($keyword, "*") === false) {
                                 $keyword .= "*";
                             }
                             # Suffix asterisk if none supplied and using $wildcard_always_applied mode.
                             # Keyword contains a wildcard. Expand.
                             $c++;
                             global $use_temp_tables;
                             if (!$use_temp_tables) {
                                 global $wildcard_expand_limit;
                                 $wildcards = sql_array("select ref value from keyword where keyword like '" . escape_check(str_replace("*", "%", $keyword)) . "' order by hit_count desc limit " . $wildcard_expand_limit);
                                 # Form join
                                 if (!$omit) {
                                     # Include in query
                                     $sql_join .= " join resource_keyword k" . $c . " on k" . $c . ".resource=r.ref and k" . $c . ".keyword in ('" . join("','", $wildcards) . "')";
                                     $sql_exclude_fields = hook("excludefieldsfromkeywordsearch");
                                     if (!empty($sql_exclude_fields)) {
                                         $sql_join .= " and k" . $c . ".resource_type_field not in (" . $sql_exclude_fields . ")";
                                     }
                                 } else {
                                     # Exclude matching resources from query (omit feature)
                                     if ($sql_filter != "") {
                                         $sql_filter .= " and ";
                                     }
                                     $sql_filter .= "r.ref not in (select resource from resource_keyword where keyword in ('" . join("','", $wildcards) . "'))";
                                     # Filter out resources that do contain the keyword.
                                 }
                                 #echo $sql_join;
                             } else {
                                 //begin code for temporary table wildcard expansion
                                 // use a global counter to avoide temporary table naming collisions
                                 global $temptable_counter;
                                 if (!isset($temptable_counter)) {
                                     $temptable_counter = 0;
                                 }
                                 $temptable_counter++;
                                 $thetemptable = 'wcql' . $c . '_' . $temptable_counter;
                                 $sql_exclude_fields = hook("excludefieldsfromkeywordsearch");
                                 $temptable_exclude = '';
                                 if (!empty($sql_exclude_fields)) {
                                     $temptable_exclude = "and rk.resource_type_field not in (" . $sql_exclude_fields . ")";
                                 }
                                 sql_query("create temporary table {$thetemptable} (resource bigint unsigned)");
                                 sql_query("insert into {$thetemptable} select distinct r.ref from resource r\n                                                                        left join resource_keyword rk on r.ref = rk.resource {$temptable_exclude}\n                                                                        left join keyword k  on rk.keyword = k.ref\n                                                                        where k.keyword like '" . escape_check(str_replace("*", "%", $keyword)) . "'");
                                 if (!$omit) {
                                     # Include in query
                                     $sql_join .= " join {$thetemptable} on {$thetemptable}.resource = r.ref ";
                                 } else {
                                     # Exclude matching resources from query (omit feature)
                                     if ($sql_filter != "") {
                                         $sql_filter .= " and ";
                                     }
                                     $sql_filter .= "r.ref not in (select resource from {$thetemptable})";
                                     # Filter out resources that do contain the keyword.
                                 }
                             }
                         } else {
                             # Not a wildcard. Normal matching.
                             $keyref = resolve_keyword($keyword);
                             # Resolve keyword. Ignore any wildcards when resolving. We need wildcards to be present later but not here.
                             if ($keyref === false && !$omit) {
                                 $fullmatch = false;
                                 $soundex = resolve_soundex($keyword);
                                 if ($soundex === false) {
                                     # No keyword match, and no keywords sound like this word. Suggest dropping this word.
                                     $suggested[$n] = "";
                                 } else {
                                     # No keyword match, but there's a word that sounds like this word. Suggest this word instead.
                                     $suggested[$n] = "<i>" . $soundex . "</i>";
                                 }
                             } else {
                                 # Key match, add to query.
                                 $c++;
                                 # Add related keywords
                                 $related = get_related_keywords($keyref);
                                 $relatedsql = "";
                                 for ($m = 0; $m < count($related); $m++) {
                                     $relatedsql .= " or k" . $c . ".keyword='" . $related[$m] . "'";
                                 }
                                 # Form join
                                 global $use_temp_tables, $use_temp_tables_for_keyword_joins;
                                 if (substr($search, 0, 8) == "!related") {
                                     $use_temp_tables_for_keyword_joins = false;
                                 }
                                 // temp tables can't be used twice (unions)
                                 $sql_exclude_fields = hook("excludefieldsfromkeywordsearch");
                                 if (!$use_temp_tables_for_keyword_joins || !$use_temp_tables) {
                                     // Not using temporary tables
                                     # Quoted string support
                                     $positionsql = "";
                                     if ($quoted_string) {
                                         if ($c > 1) {
                                             $last_key_offset = 1;
                                             if (isset($skipped_last) && $skipped_last) {
                                                 $last_key_offset = 2;
                                             }
                                             # Support skipped keywords - if the last keyword was skipped (listed in $noadd), increase the allowed position from the previous keyword. Useful for quoted searches that contain $noadd words, e.g. "black and white" where "and" is a skipped keyword.
                                             $positionsql = "and k" . $c . ".position=k" . ($c - 1) . ".position+" . $last_key_offset;
                                         }
                                     }
                                     if (!empty($sql_exclude_fields)) {
                                         $sql_join .= " and k" . $c . ".resource_type_field not in (" . $sql_exclude_fields . ")";
                                     }
                                     if (!$omit) {
                                         # Include in query
                                         $sql_join .= " join resource_keyword k" . $c . " on k" . $c . ".resource=r.ref and (k" . $c . ".keyword='{$keyref}' {$relatedsql}) {$positionsql}";
                                         if ($score != "") {
                                             $score .= "+";
                                         }
                                         $score .= "k" . $c . ".hit_count";
                                     } else {
                                         # Exclude matching resources from query (omit feature)
                                         if ($sql_filter != "") {
                                             $sql_filter .= " and ";
                                         }
                                         $sql_filter .= "r.ref not in (select resource from resource_keyword where keyword='{$keyref}')";
                                         # Filter out resources that do contain the keyword.
                                     }
                                 } else {
                                     //use temp tables
                                     if (!isset($temptable_counter)) {
                                         $temptable_counter = 0;
                                     }
                                     $temptable_counter++;
                                     $jtemptable = 'jtt' . $c . '_' . $temptable_counter;
                                     sql_query("drop table IF EXISTS {$jtemptable} ", false);
                                     $exclude_sql = '';
                                     # Quoted string support
                                     $positionsql = "";
                                     if ($quoted_string) {
                                         if ($c > 1) {
                                             $last_key_offset = 1;
                                             if (isset($skipped_last) && $skipped_last) {
                                                 $last_key_offset = 2;
                                             }
                                             # Support skipped keywords - if the last keyword was skipped (listed in $noadd), increase the allowed position from the previous keyword. Useful for quoted searches that contain $noadd words, e.g. "black and white" where "and" is a skipped keyword.
                                             $positionsql = "and {$jtemptable}.position=" . 'jtt' . ($c - 1) . '_' . ($temptable_counter - 1) . ".position+" . $last_key_offset;
                                         }
                                     }
                                     if (!empty($sql_exclude_fields)) {
                                         $exclude_sql = "and k" . $c . ".resource_type_field not in (" . $sql_exclude_fields . ")";
                                     }
                                     $test = sql_query("create temporary table {$jtemptable} SELECT distinct k" . $c . ".resource,k" . $c . ".hit_count,k" . $c . ".position from \tresource_keyword k" . $c . " where (k" . $c . ".keyword='{$keyref}' {$relatedsql})  {$exclude_sql}");
                                     if (!$omit) {
                                         # Include in query
                                         $sql_join .= " join {$jtemptable} on {$jtemptable}.resource = r.ref {$positionsql}";
                                         if ($score != "") {
                                             $score .= "+";
                                         }
                                         $score .= $jtemptable . ".hit_count";
                                     } else {
                                         # Exclude matching resources from query (omit feature)
                                         if ($sql_filter != "") {
                                             $sql_filter .= " and ";
                                         }
                                         $sql_filter .= "r.ref not in (select resource from {$jtemptable})";
                                         # Filter out resources that do contain the keyword.
                                     }
                                 }
                                 # Log this
                                 daily_stat("Keyword usage", $keyref);
                             }
                         }
                         $skipped_last = false;
                     }
                 }
             }
         }
     }
     # Could not match on provided keywords? Attempt to return some suggestions.
     if ($fullmatch == false) {
         if ($suggested == $keywords) {
             # Nothing different to suggest.
             debug("No alternative keywords to suggest.");
             return "";
         } else {
             # Suggest alternative spellings/sound-a-likes
             $suggest = "";
             if (strpos($search, ",") === false) {
                 $suggestjoin = " ";
             } else {
                 $suggestjoin = ", ";
             }
             for ($n = 0; $n < count($suggested); $n++) {
                 if ($suggested[$n] != "") {
                     if ($suggest != "") {
                         $suggest .= $suggestjoin;
                     }
                     $suggest .= $suggested[$n];
                 }
             }
             debug("Suggesting {$suggest}");
             return $suggest;
         }
     }
     # Some useful debug.
     #echo("keywordjoin=" . $sql_join);
     #echo("<br>Filter=" . $sql_filter);
     #echo("<br>Search=" . $search);
     hook("additionalsqlfilter");
     # ------ Search filtering: If search_filter is specified on the user group, then we must always apply this filter.
     global $usersearchfilter;
     $sf = explode(";", $usersearchfilter);
     if (strlen($usersearchfilter) > 0) {
         for ($n = 0; $n < count($sf); $n++) {
             $s = explode("=", $sf[$n]);
             if (count($s) != 2) {
                 exit("Search filter is not correctly configured for this user group.");
             }
             # Find field(s) - multiple fields can be returned to support several fields with the same name.
             $f = sql_array("select ref value from resource_type_field where name='" . escape_check($s[0]) . "'");
             if (count($f) == 0) {
                 exit("Field(s) with short name '" . $s[0] . "' not found in user group search filter.");
             }
             # Find keyword(s)
             $ks = explode("|", strtolower(escape_check($s[1])));
             $modifiedsearchfilter = hook("modifysearchfilter");
             if ($modifiedsearchfilter) {
                 $ks = $modifiedsearchfilter;
             }
             $kw = sql_array("select ref value from keyword where keyword in ('" . join("','", $ks) . "')");
             #if (count($k)==0) {exit ("At least one of keyword(s) '" . join("', '",$ks) . "' not found in user group search filter.");}
             $sql_join .= " join resource_keyword filter" . $n . " on r.ref=filter" . $n . ".resource and filter" . $n . ".resource_type_field in ('" . join("','", $f) . "') and filter" . $n . ".keyword in ('" . join("','", $kw) . "') ";
         }
     }
     $userownfilter = hook("userownfilter");
     if ($userownfilter) {
         $sql_join .= $userownfilter;
     }
     # Handle numeric searches when $config_search_for_number=false, i.e. perform a normal search but include matches for resource ID first
     global $config_search_for_number;
     if (!$config_search_for_number && is_numeric($search)) {
         # Always show exact resource matches first.
         $order_by = "(r.ref='" . $search . "') desc," . $order_by;
     }
     # --------------------------------------------------------------------------------
     # Special Searches (start with an exclamation mark)
     # --------------------------------------------------------------------------------
     # Can only search for resources that belong to themes
     if (checkperm("J")) {
         $sql_join .= " join collection_resource jcr on jcr.resource=r.ref join collection jc on jcr.collection=jc.ref and length(jc.theme)>0 ";
     }
     # ------ Special searches ------
     # View Last
     if (substr($search, 0, 5) == "!last") {
         # Replace r2.ref with r.ref for the alternative query used here.
         $order_by = str_replace("r.ref", "r2.ref", $order_by);
         if ($orig_order == "relevance") {
             $order_by = "r2.ref desc";
         }
         # Extract the number of records to produce
         $last = explode(",", $search);
         $last = str_replace("!last", "", $last[0]);
         if (!is_numeric($last)) {
             $last = 1000;
         }
         # 'Last' must be a number. SQL injection filter.
         # Fix the order by for this query (special case due to inner query)
         $order_by = str_replace("r.rating", "rating", $order_by);
         return sql_query($sql_prefix . "select distinct *,r2.hit_count score from (select {$select} from resource r {$sql_join}  where {$sql_filter} order by ref desc limit {$last} ) r2 order by {$order_by}" . $sql_suffix, false, $fetchrows);
     }
     # View Resources With No Downloads
     if (substr($search, 0, 12) == "!nodownloads") {
         if ($orig_order == "relevance") {
             $order_by = "ref desc";
         }
         return sql_query($sql_prefix . "select distinct r.hit_count score, {$select} from resource r {$sql_join}  where {$sql_filter} and ref not in (select distinct object_ref from daily_stat where activity_type='Resource download') order by {$order_by}" . $sql_suffix, false, $fetchrows);
     }
     # Duplicate Resources (based on file_checksum)
     if (substr($search, 0, 11) == "!duplicates") {
         // old code disabled due to performance issues
         //return sql_query("select distinct r.hit_count score, $select from resource r $sql_join  where $sql_filter and file_checksum in (select file_checksum from (select file_checksum,count(*) dupecount from resource group by file_checksum) r2 where r2.dupecount>1) order by file_checksum",false,$fetchrows);
         // new code relies on MySQL temporary tables being enabled, as well as checksums
         // if either is not turned on, just give up.
         global $use_temp_tables;
         global $file_checksums;
         if ($use_temp_tables && $file_checksums) {
             global $temptable_counter;
             if (!isset($temptable_counter)) {
                 $temptable_counter = 0;
             }
             $temptable_counter++;
             $thetemptable = 'dupehashx' . '_' . $temptable_counter;
             $dupequery = "select distinct r.hit_count score, {$select} from resource r {$sql_join} join {$thetemptable} on r.file_checksum = {$thetemptable}.hash where {$sql_filter} order by file_checksum";
             sql_query("create temporary table {$thetemptable} (`hash` varchar(255) NOT NULL,`hashcount` int(10) default NULL, KEY `Index 1` (`hash`))", false);
             sql_query("insert into {$thetemptable} select file_checksum, count(file_checksum) from resource where archive = 0 and ref > 0 and file_checksum <> '' and file_checksum is not null group by file_checksum having count(file_checksum) > 1", false);
             $duperesult = sql_query($dupequery, false, $fetchrows);
             return $duperesult;
         } else {
             return false;
         }
     }
     # View Collection
     if (substr($search, 0, 11) == "!collection") {
         if ($orig_order == "relevance") {
             $order_by = "c.sortorder asc,c.date_added desc,r.ref";
         }
         $colcustperm = $sql_join;
         if (getval("k", "") != "") {
             $sql_filter = "ref>0";
         }
         # Special case if a key has been provided.
         # Extract the collection number
         $collection = explode(" ", $search);
         $collection = str_replace("!collection", "", $collection[0]);
         $collection = explode(",", $collection);
         // just get the number
         $collection = $collection[0];
         # smart collections update
         global $allow_smart_collections;
         if ($allow_smart_collections) {
             $smartsearch_ref = sql_value("select savedsearch value from collection where ref={$collection}", "");
             if ($smartsearch_ref != "") {
                 $smartsearch = sql_query("select * from collection_savedsearch where ref={$smartsearch_ref}");
                 if (isset($smartsearch[0]['search'])) {
                     $smartsearch = $smartsearch[0];
                     $results = do_search($smartsearch['search'], $smartsearch['restypes'], "relevance", $smartsearch['archive'], -1, "desc", true, $smartsearch['starsearch']);
                     # results is a list of the current search without any restrictions
                     # we need to compare against the current collection contents to minimize inserts and deletions
                     $current = sql_query("select resource from collection_resource where collection={$collection}");
                     $current_contents = array();
                     $results_contents = array();
                     if (!empty($current)) {
                         foreach ($current as $current_item) {
                             $current_contents[] = $current_item['resource'];
                         }
                     }
                     if (!empty($results) && is_array($results)) {
                         foreach ($results as $results_item) {
                             $results_contents[] = $results_item['ref'];
                         }
                     }
                     for ($n = 0; $n < count($results_contents); $n++) {
                         if (!in_array($results_contents[$n], $current_contents)) {
                             add_resource_to_collection($results_contents[$n], $collection, true);
                         }
                     }
                     for ($n = 0; $n < count($current_contents); $n++) {
                         if (!in_array($current_contents[$n], $results_contents)) {
                             remove_resource_from_collection($current_contents[$n], $collection, true);
                         }
                     }
                 }
             }
         }
         return sql_query($sql_prefix . "select distinct c.date_added,c.comment,c.purchase_size,c.purchase_complete,r.hit_count score,length(c.comment) commentset, {$select} from resource r  join collection_resource c on r.ref=c.resource {$colcustperm}  where c.collection='" . $collection . "' and {$sql_filter} group by r.ref order by {$order_by}" . $sql_suffix, false, $fetchrows);
     }
     # View Related
     if (substr($search, 0, 8) == "!related") {
         # Extract the resource number
         $resource = explode(" ", $search);
         $resource = str_replace("!related", "", $resource[0]);
         $order_by = str_replace("r.", "", $order_by);
         # UNION below doesn't like table aliases in the order by.
         return sql_query($sql_prefix . "select distinct r.hit_count score, {$select} from resource r join resource_related t on (t.related=r.ref and t.resource='" . $resource . "') {$sql_join}  where 1=1 and {$sql_filter} group by r.ref \n\t\tUNION\n\t\tselect distinct r.hit_count score, {$select} from resource r join resource_related t on (t.resource=r.ref and t.related='" . $resource . "') {$sql_join}  where 1=1 and {$sql_filter} group by r.ref \n\t\torder by {$order_by}" . $sql_suffix, false, $fetchrows);
     }
     # Geographic search
     if (substr($search, 0, 4) == "!geo") {
         $geo = explode("t", str_replace(array("m", "p"), array("-", "."), substr($search, 4)));
         # Specially encoded string to avoid keyword splitting
         $bl = explode("b", $geo[0]);
         $tr = explode("b", $geo[1]);
         $sql = "select r.hit_count score, {$select} from resource r {$sql_join} where \n\n\t\t\t\t\tgeo_lat > '" . escape_check($bl[0]) . "'\n              and   geo_lat < '" . escape_check($tr[0]) . "'\t\t\n              and   geo_long > '" . escape_check($bl[1]) . "'\t\t\n              and   geo_long < '" . escape_check($tr[1]) . "'\t\t\n                          \n\t\t and {$sql_filter} group by r.ref order by {$order_by}";
         return sql_query($sql_prefix . $sql . $sql_suffix, false, $fetchrows);
     }
     # Colour search
     if (substr($search, 0, 7) == "!colour") {
         $colour = explode(" ", $search);
         $colour = str_replace("!colour", "", $colour[0]);
         $sql = "select r.hit_count score, {$select} from resource r {$sql_join}\n\t\t\t\twhere \n\t\t\t\t\tcolour_key like '" . escape_check($colour) . "%'\n              \tor  colour_key like '_" . escape_check($colour) . "%'\n                          \n\t\t and {$sql_filter} group by r.ref order by {$order_by}";
         return sql_query($sql_prefix . $sql . $sql_suffix, false, $fetchrows);
     }
     # Similar to a colour
     if (substr($search, 0, 4) == "!rgb") {
         $rgb = explode(":", $search);
         $rgb = explode(",", $rgb[1]);
         return sql_query($sql_prefix . "select distinct r.hit_count score, {$select} from resource r {$sql_join}  where has_image=1 and {$sql_filter} group by r.ref order by (abs(image_red-" . $rgb[0] . ")+abs(image_green-" . $rgb[1] . ")+abs(image_blue-" . $rgb[2] . ")) asc limit 500" . $sql_suffix, false, $fetchrows);
     }
     # Similar to a colour by key
     if (substr($search, 0, 10) == "!colourkey") {
         # Extract the colour key
         $colourkey = explode(" ", $search);
         $colourkey = str_replace("!colourkey", "", $colourkey[0]);
         return sql_query($sql_prefix . "select distinct r.hit_count score, {$select} from resource r {$sql_join}  where has_image=1 and left(colour_key,4)='" . $colourkey . "' and {$sql_filter} group by r.ref" . $sql_suffix, false, $fetchrows);
     }
     global $config_search_for_number;
     if ($config_search_for_number && is_numeric($search) || substr($search, 0, 9) == "!resource") {
         $theref = escape_check($search);
         $theref = preg_replace("/[^0-9]/", "", $theref);
         return sql_query($sql_prefix . "select distinct r.hit_count score, {$select} from resource r {$sql_join}  where r.ref='{$theref}' and {$sql_filter} group by r.ref" . $sql_suffix);
     }
     # Searching for pending archive
     if (substr($search, 0, 15) == "!archivepending") {
         return sql_query($sql_prefix . "select distinct r.hit_count score, {$select} from resource r {$sql_join}  where archive=1 and ref>0 group by r.ref order by {$order_by}" . $sql_suffix, false, $fetchrows);
     }
     if (substr($search, 0, 12) == "!userpending") {
         if ($orig_order == "rating") {
             $order_by = "request_count desc," . $order_by;
         }
         return sql_query($sql_prefix . "select distinct r.hit_count score, {$select} from resource r {$sql_join}  where archive=-1 and ref>0 group by r.ref order by {$order_by}" . $sql_suffix, false, $fetchrows);
     }
     # View Contributions
     if (substr($search, 0, 14) == "!contributions") {
         global $userref;
         # Extract the user ref
         $cuser = explode(" ", $search);
         $cuser = str_replace("!contributions", "", $cuser[0]);
         if ($userref == $cuser) {
             $sql_filter = "archive='{$archive}'";
             $sql_join = "";
         }
         # Disable permissions when viewing your own contributions - only restriction is the archive status
         $select = str_replace(",rca.access group_access,rca2.access user_access ", ",null group_access, null user_access ", $select);
         return sql_query($sql_prefix . "select distinct r.hit_count score, {$select} from resource r {$sql_join}  where created_by='" . $cuser . "' and r.ref > 0 and {$sql_filter} group by r.ref order by {$order_by}" . $sql_suffix, false, $fetchrows);
     }
     # Search for resources with images
     if ($search == "!images") {
         return sql_query($sql_prefix . "select distinct r.hit_count score, {$select} from resource r {$sql_join}  where has_image=1 group by r.ref order by {$order_by}" . $sql_suffix, false, $fetchrows);
     }
     # Search for resources not used in Collections
     if (substr($search, 0, 7) == "!unused") {
         return sql_query($sql_prefix . "SELECT distinct {$select} FROM resource r {$sql_join}  where r.ref>0 and r.ref not in (select c.resource from collection_resource c) and {$sql_filter}" . $sql_suffix, false, $fetchrows);
     }
     # Search for a list of resources
     # !listall = archive state is not applied as a filter to the list of resources.
     if (substr($search, 0, 5) == "!list") {
         $resources = explode(" ", $search);
         if (substr($search, 0, 8) == "!listall") {
             $resources = str_replace("!listall", "", $resources[0]);
         } else {
             $resources = str_replace("!list", "", $resources[0]);
         }
         $resources = explode(",", $resources);
         // separate out any additional keywords
         $resources = escape_check($resources[0]);
         if (strlen(trim($resources)) == 0) {
             $resources = "where r.ref IS NULL";
         } else {
             $resources = "where (r.ref='" . str_replace(":", "' OR r.ref='", $resources) . "')";
         }
         return sql_query($sql_prefix . "SELECT distinct r.hit_count score, {$select} FROM resource r {$sql_join} {$resources} and {$sql_filter} order by {$order_by}" . $sql_suffix, false, $fetchrows);
     }
     # Within this hook implementation, set the value of the global $sql variable:
     # Since there will only be one special search executed at a time, only one of the
     # hook implementations will set the value.  So, you know that the value set
     # will always be the correct one (unless two plugins use the same !<type> value).
     $sql = "";
     hook("addspecialsearch");
     if ($sql != "") {
         debug("Addspecialsearch hook returned useful results.");
         return sql_query($sql_prefix . $sql . $sql_suffix, false, $fetchrows);
     }
     # -------------------------------------------------------------------------------------
     # Standard Searches
     # -------------------------------------------------------------------------------------
     # We've reached this far without returning.
     # This must be a standard (non-special) search.
     # Construct and perform the standard search query.
     #$sql="";
     if ($sql_filter != "") {
         if ($sql != "") {
             $sql .= " and ";
         }
         $sql .= $sql_filter;
     }
     # Append custom permissions
     $t .= $sql_join;
     if ($score == "") {
         $score = "r.hit_count";
     }
     # In case score hasn't been set (i.e. empty search)
     global $max_results;
     if ($t2 != "" && $sql != "") {
         $sql = " and " . $sql;
     }
     # Compile final SQL
     # Performance enhancement - set return limit to number of rows required
     if ($search_sql_double_pass_mode && $fetchrows != -1) {
         $max_results = $fetchrows;
     }
     $results_sql = $sql_prefix . "select distinct {$score} score, {$select} from resource r" . $t . "  where {$t2} {$sql} group by r.ref order by {$order_by} limit {$max_results}" . $sql_suffix;
     # Debug
     debug("\n" . $results_sql);
     # Execute query
     $result = sql_query($results_sql, false, $fetchrows);
     # Performance improvement - perform a second count-only query and pad the result array as necessary
     if ($search_sql_double_pass_mode && count($result) > 0 && count($result) >= $max_results) {
         $count_sql = "select count(distinct r.ref) value from resource r" . $t . "  where {$t2} {$sql}";
         $count = sql_value($count_sql, 0);
         $result = array_pad($result, $count, 0);
     }
     debug("Search found " . count($result) . " results");
     if (count($result) > 0) {
         return $result;
     }
     # (temp) - no suggestion for field-specific searching for now - TO DO: modify function below to support this
     if (strpos($search, ":") !== false) {
         return "";
     }
     # All keywords resolved OK, but there were no matches
     # Remove keywords, least used first, until we get results.
     $lsql = "";
     $omitmatch = false;
     for ($n = 0; $n < count($keywords); $n++) {
         if (substr($keywords[$n], 0, 1) == "-") {
             $omitmatch = true;
             $omit = $keywords[$n];
         }
         if ($lsql != "") {
             $lsql .= " or ";
         }
         $lsql .= "keyword='" . escape_check($keywords[$n]) . "'";
     }
     if ($omitmatch) {
         return trim_spaces(str_replace(" " . $omit . " ", " ", " " . join(" ", $keywords) . " "));
     }
     if ($lsql != "") {
         $least = sql_value("select keyword value from keyword where {$lsql} order by hit_count asc limit 1", "");
         return trim_spaces(str_replace(" " . $least . " ", " ", " " . join(" ", $keywords) . " "));
     } else {
         return array();
     }
 }
예제 #22
0
    $info = get_resource_data($ref);
    $path = "../gfx/" . get_nopreview_icon($info["resource_type"], $ext, "thm");
}
# writing RS metadata to files: exiftool
if ($noattach == "" && $alternative == -1) {
    $tmpfile = write_metadata($path, $ref);
    if ($tmpfile !== false && file_exists($tmpfile)) {
        $path = $tmpfile;
    }
}
hook('modifydownloadfile');
$filesize = filesize_unlimited($path);
header("Content-Length: " . $filesize);
# Log this activity (download only, not preview)
if ($noattach == "") {
    daily_stat("Resource download", $ref);
    resource_log($ref, 'd', 0, $usagecomment, "", "", $usage, $size);
    hook('moredlactions');
    # update hit count if tracking downloads only
    if ($resource_hit_count_on_downloads) {
        # greatest() is used so the value is taken from the hit_count column in the event that new_hit_count is zero to support installations that did not previously have a new_hit_count column (i.e. upgrade compatability).
        sql_query("update resource set new_hit_count=greatest(hit_count,new_hit_count)+1 where ref='{$ref}'");
    }
    # We compute a file name for the download.
    $filename = $ref . $size . ($alternative > 0 ? "_" . $alternative : "") . "." . $ext;
    if ($original_filenames_when_downloading) {
        # Use the original filename.
        if ($alternative > 0) {
            # Fetch from the resource_alt_files alternatives table (this is an alternative file)
            $origfile = get_alternative_file($ref, $alternative);
            $origfile = get_data_by_field($ref, $filename_field) . "-" . $origfile["file_name"];
예제 #23
0
    $restypes = "";
    reset($_GET);
    foreach ($_GET as $key => $value) {
        if (substr($key, 0, 8) == "resource") {
            if ($restypes != "") {
                $restypes .= ",";
            }
            $restypes .= substr($key, 8);
        }
    }
    setcookie("restypes", $restypes);
    # This is a new search, log this activity
    if ($archive == 2) {
        daily_stat("Archive search", 0);
    } else {
        daily_stat("Search", 0);
    }
}
# If returning to an old search, restore the page/order by
if (!array_key_exists("search", $_GET)) {
    $offset = getvalescaped("saved_offset", 0);
    setcookie("saved_offset", $offset);
    $order_by = getvalescaped("saved_order_by", "relevance");
    setcookie("saved_order_by", $order_by);
    $archive = getvalescaped("saved_archive", 0);
    setcookie("saved_archive", $archive);
}
$refs = array();
#echo "search=$search";
# Special query? Ignore restypes
if (strpos($search, "!") !== false) {
예제 #24
0
/**
 * Performs the login using the global $username, and $password. Since the "externalauth" hook
 * is allowed to change the credentials later on, the $password_hash needs to be global as well.
 *
 * @return array Containing the login details ('valid' determines whether or not the login succeeded).
 */
function perform_login()
{
    global $api, $scramble_key, $enable_remote_apis, $lang, $max_login_attempts_wait_minutes, $max_login_attempts_per_ip, $max_login_attempts_per_username, $global_cookies, $username, $password, $password_hash;
    if (!$api && strlen($password) == 32 && getval("userkey", "") != md5($username . $scramble_key)) {
        exit("Invalid password.");
        # Prevent MD5s being entered directly while still supporting direct entry of plain text passwords (for systems that were set up prior to MD5 password encryption was added). If a special key is sent, which is the md5 hash of the username and the secret scramble key, then allow a login using the MD5 password hash as the password. This is for the 'log in as this user' feature.
    }
    if (strlen($password) != 32) {
        # Provided password is not a hash, so generate a hash.
        $password_hash = md5("RS" . $username . $password);
    } else {
        $password_hash = $password;
    }
    $ip = get_ip();
    # This may change the $username, $password, and $password_hash
    hook("externalauth", "", array($username, $password));
    #Attempt external auth if configured
    $session_hash = md5($password_hash . $username . $password . date("Y-m-d"));
    if ($enable_remote_apis) {
        $session_hash = md5($password_hash . $username . date("Y-m-d"));
    }
    // no longer necessary to omit password in this hash for api support
    $valid = sql_query("select ref,usergroup from user where lower(username)='" . escape_check($username) . "' and (password='******' or password='******')");
    # Prepare result array
    $result = array();
    $result['valid'] = false;
    if (count($valid) >= 1) {
        # Account expiry
        $expires = sql_value("select account_expires value from user where username='******' and password='******'", "");
        if ($expires != "" && $expires != "0000-00-00 00:00:00" && strtotime($expires) <= time()) {
            $result['error'] = $lang["accountexpired"];
            return $result;
        }
        $result['valid'] = true;
        $result['session_hash'] = $session_hash;
        $result['password_hash'] = $password_hash;
        # Update the user record. Set the password hash again in case a plain text password was provided.
        sql_query("update user set password='******',session='" . escape_check($session_hash) . "',last_active=now(),login_tries=0,lang='" . getvalescaped("language", "") . "' where lower(username)='" . escape_check($username) . "' and (password='******' or password='******')");
        # Log this
        $userref = $valid[0]["ref"];
        $usergroup = $valid[0]["usergroup"];
        daily_stat("User session", $userref);
        sql_query("insert into resource_log(date,user,resource,type) values (now()," . ($userref != "" ? "'{$userref}'" : "null") . ",0,'l')");
        # Blank the IP address lockout counter for this IP
        sql_query("delete from ip_lockout where ip='" . escape_check($ip) . "'");
        return $result;
    }
    # Invalid login
    $result['error'] = $lang["loginincorrect"];
    hook("loginincorrect");
    # Add / increment a lockout value for this IP
    $lockouts = sql_value("select count(*) value from ip_lockout where ip='" . escape_check($ip) . "' and tries<'" . $max_login_attempts_per_ip . "'", "");
    if ($lockouts > 0) {
        # Existing row with room to move
        $tries = sql_value("select tries value from ip_lockout where ip='" . escape_check($ip) . "'", 0);
        $tries++;
        if ($tries == $max_login_attempts_per_ip) {
            # Show locked out message.
            $result['error'] = str_replace("?", $max_login_attempts_wait_minutes, $lang["max_login_attempts_exceeded"]);
        }
        # Increment
        sql_query("update ip_lockout set last_try=now(),tries=tries+1 where ip='" . escape_check($ip) . "'");
    } else {
        # New row
        sql_query("delete from ip_lockout where ip='" . escape_check($ip) . "'");
        sql_query("insert into ip_lockout (ip,tries,last_try) values ('" . escape_check($ip) . "',1,now())");
    }
    # Increment a lockout value for any matching username.
    $ulocks = sql_query("select ref,login_tries,login_last_try from user where username='******'");
    if (count($ulocks) > 0) {
        $tries = $ulocks[0]["login_tries"];
        if ($tries == "") {
            $tries = 1;
        } else {
            $tries++;
        }
        if ($tries > $max_login_attempts_per_username) {
            $tries = 1;
        }
        if ($tries == $max_login_attempts_per_username) {
            # Show locked out message.
            $result['error'] = str_replace("?", $max_login_attempts_wait_minutes, $lang["max_login_attempts_exceeded"]);
        }
        sql_query("update user set login_tries='{$tries}',login_last_try=now() where username='******'");
    }
    return $result;
}
    $usercollection = hook("modifyusercollection");
}
# Process adding of items
$add = getvalescaped("add", "");
if ($add != "") {
    hook("preaddtocollection");
    #add to current collection
    if (add_resource_to_collection($add, $usercollection) == false) {
        ?>
<script type="text/javascript">alert("<?php 
        echo $lang["cantmodifycollection"];
        ?>
");</script><?php 
    }
    # Log this
    daily_stat("Add resource to collection", $add);
    # update resource/keyword kit count
    $search = getvalescaped("search", "");
    if (strpos($search, "!") === false && $search != "") {
        update_resource_keyword_hitcount($add, $search);
    }
    hook("postaddtocollection");
}
# Process removal of items
$remove = getvalescaped("remove", "");
if ($remove != "") {
    hook("preremovefromcollection");
    #remove from current collection
    if (remove_resource_from_collection($remove, $usercollection) == false) {
        ?>
<script type="text/javascript">alert("<?php