// Copyright: Matthias Steffens and the file's // original author(s). // // This code is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY. Please see the GNU General Public // License for more details. // // File: ./includes/opensearch.inc.php // Repository: $HeadURL$ // Author(s): Matthias Steffens // // Created: 09-Jan-08, 00:30 // Modified: $Date: 2008-09-18 13:54:33 +0000 (Thu, 18 Sep 2008) $ // $Author$ // $Revision: 1240 $ // This include file contains functions that'll return an OpenSearch response. // Requires ActiveLink PHP XML Package, which is available under the GPL from: // . See 'opensearch.php' for more info. // TODO: I18n // Incorporate some include files: include_once 'includes/webservice.inc.php'; // include functions that are commonly used with the refbase webservices // Import the ActiveLink Packages require_once("classes/include.php"); import("org.active-link.xml.XML"); import("org.active-link.xml.XMLDocument"); // -------------------------------------------------------------------- // Return an OpenSearch description document if the OpenSearch client issued: // - .../opensearch.php?operation=explain // // Spec: // See also: function openSearchDescription($exportStylesheet) { global $contentTypeCharset; // these variables are specified in 'ini.inc.php' global $convertExportDataToUTF8; global $officialDatabaseName; global $hostInstitutionName; global $hostInstitutionAbbrevName; global $feedbackEmail; global $databaseBaseURL; global $databaseKeywords; global $logoSmallImageURL; global $logoSmallImageWidth; global $logoSmallImageHeight; global $logoSmallImageType; global $faviconImageURL; global $loc; // defined in 'locales/core.php' $openSearchCollectionDoc = new XMLDocument(); $openSearchCollectionDoc->setEncoding($contentTypeCharset); $openSearchCollection = openSearchGenerateBaseTags("Description"); // --- begin search engine info ----------------------------- // (note that we don't enforce any character length limits) // The 'ShortName' element contains a brief human-readable title that identifies this search engine: // (the value must contain 16 or fewer characters of plain text) addNewBranch($openSearchCollection, "ShortName", array(), "refbase (" . $hostInstitutionAbbrevName . ")"); // function 'addNewBranch()' is defined in 'webservice.inc.php' // The 'LongName' element contains an extended human-readable title that identifies this search engine: // (the value must contain 48 or fewer characters of plain text) addNewBranch($openSearchCollection, "LongName", array(), $officialDatabaseName); // The 'Description' element contains a human-readable text description of the search engine: // (the value must contain 1024 or fewer characters of plain text) addNewBranch($openSearchCollection, "Description", array(), $officialDatabaseName . ": " . $loc["SearchMain"] . ". " . $loc["ThisDatabaseIsMaintained"] . " " . $hostInstitutionName . " (" . $hostInstitutionAbbrevName . ")." ); // The 'Tags' element contains a set of words that are used as keywords to identify and categorize the search content: // (the value must contain 256 or fewer characters of plain text; tags must be a single word and are delimited by the space character) addNewBranch($openSearchCollection, "Tags", array(), $databaseKeywords); // The 'Contact' element contains an email address at which the maintainer of the description document can be reached: // (the value must conform to the requirements of Section 3.4.1 "Addr-spec specification" in RFC 2822 ) addNewBranch($openSearchCollection, "Contact", array(), $feedbackEmail); // The 'Attribution' element contains a list of all sources or entities that should be credited for the content contained in the search feed: // (the value must contain 256 or fewer characters of plain text) // addNewBranch($openSearchCollection, "Attribution", array(), "Search data copyright ..."); // uncomment and edit copyright statement if desired // The 'SyndicationRight' element contains a value that indicates the degree to which the search results provided by this search engine can be queried, displayed, and redistributed: // (possible values: "open", "limited", "private", "closed"; see ) addNewBranch($openSearchCollection, "SyndicationRight", array(), "open"); // The 'AdultContent' element contains a boolean value that should be set to true if the search results may contain material intended only for adults: // (possible values: "true", "false") addNewBranch($openSearchCollection, "AdultContent", array(), "false"); // The 'Language' element contains a string that indicates that the search engine supports search results in the specified language: // (the value must conform to the XML 1.0 Language Identification, as specified by RFC 3066 in ; // in addition, a value of "*" signifies that the search engine does not restrict search results to any particular language) addNewBranch($openSearchCollection, "Language", array(), "*"); // The 'InputEncoding' element contains a string that indicates that the search engine supports search requests encoded with the specified character encoding: // (the value must conform to the XML 1.0 Character Encodings, as specified by the IANA Character Set Assignments: ) addNewBranch($openSearchCollection, "InputEncoding", array(), $contentTypeCharset); // The 'OutputEncoding' element contains a string that indicates that the search engine supports search responses encoded with the specified character encoding: // (the value must conform to the XML 1.0 Character Encodings, as specified by the IANA Character Set Assignments: ) if (($convertExportDataToUTF8 == "yes") AND ($contentTypeCharset != "UTF-8")) addNewBranch($openSearchCollection, "OutputEncoding", array(), "UTF-8"); else addNewBranch($openSearchCollection, "OutputEncoding", array(), $contentTypeCharset); // The 'Developer' element contains the human-readable name or identifier of the creator or maintainer of the description document: // (the value must contain 64 or fewer characters of plain text) addNewBranch($openSearchCollection, "Developer", array(), "Web Reference Database (http://refbase.sourceforge.net)"); // The 'Query' element defines a search query that can be performed by search clients: // (Spec: ) addNewBranch($openSearchCollection, "Query", array("role" => "example", "title" => "Sample search", "searchTerms" => "Miller", // search term example (we could also use ".+" but an ubiquitous author name such as "Miller" seems more intuitive and almost always results in some hits) "startIndex" => "1", // index number of the first search result, starting with one "count" => $_SESSION['userRecordsPerPage'] // default number of records per page preferred by the current user ), "" ); // The 'Image' element contains a URL that identifies the location of an image that can be used in association with the search content: // (images with square aspect ratios are recommended, e.g. a 16x16 image of type ".ico" and a 64x64 image of type ".jpeg" or ".png") // - favicon image (16x16): addNewBranch($openSearchCollection, "Image", array("type" => "image/x-icon", // MIME type of this image "height" => "16", // image height, in pixels "width" => "16" // image width, in pixels ), $databaseBaseURL . $faviconImageURL ); // - small logo image (e.g. 64x64): addNewBranch($openSearchCollection, "Image", array("type" => $logoSmallImageType, "height" => $logoSmallImageHeight, "width" => $logoSmallImageWidth ), $databaseBaseURL . $logoSmallImageURL ); // --- end search engine info ------------------------------- // --- begin URL templates ---------------------------------- // The 'Url' element describes an interface by which a search client can make search requests of the search engine: // - URL template for output of OpenSearch Atom XML (which is the default): addNewBranch($openSearchCollection, "Url", array("type" => "application/atom+xml", // MIME type of the search result format "template" => $databaseBaseURL . "opensearch.php?query={searchTerms}&startRecord={startIndex?}&maximumRecords={count?}&recordSchema=atom", // search URL template to be processed according to the OpenSearch URL template syntax "indexOffset" => "1", // index number of the first search result, starting with one // "pageOffset" => "1" // page number of the first set of search results (NOTE: currently, page-based searches are not supported by refbase) ), "" ); // - URL template for output of RSS XML: addNewBranch($openSearchCollection, "Url", array("type" => "application/rss+xml", "template" => $databaseBaseURL . "opensearch.php?query={searchTerms}&startRecord={startIndex?}&maximumRecords={count?}&recordSchema=rss", "indexOffset" => "1" ), "" ); // - URL template for output of SRW_DC XML: addNewBranch($openSearchCollection, "Url", array("type" => "application/xml", "template" => $databaseBaseURL . "opensearch.php?query={searchTerms}&startRecord={startIndex?}&maximumRecords={count?}&recordSchema=srw_dc", "indexOffset" => "1" ), "" ); // - URL template for output of SRW_MODS XML: addNewBranch($openSearchCollection, "Url", array("type" => "application/xml", "template" => $databaseBaseURL . "opensearch.php?query={searchTerms}&startRecord={startIndex?}&maximumRecords={count?}&recordSchema=srw_mods", "indexOffset" => "1" ), "" ); // - URL template for output of HTML: addNewBranch($openSearchCollection, "Url", array("type" => "text/html", "template" => $databaseBaseURL . "opensearch.php?query={searchTerms}&startRecord={startIndex?}&maximumRecords={count?}&recordSchema=html", "indexOffset" => "1" ), "" ); // - URL template for output of JSON-formatted search suggestions: // // NOTE: An URL template with 'type="application/x-suggestions+json"' is used by Firefox // to specify the URL to use for fetching search suggestions in JSON format // See also: // // // addNewBranch($openSearchCollection, "Url", array("type" => "application/x-suggestions+json", "template" => $databaseBaseURL . "opensearch.php?query={searchTerms}&startRecord={startIndex?}&maximumRecords={count?}&recordSchema=json&operation=suggest&client=sug-refbase_suggest-1.0", "indexOffset" => "1" ), "" ); // --- end URL templates ------------------------------------ // --- begin Mozilla-specific elements ---------------------- // The 'SearchForm' element contains the URL to go to to open up the search page at the site for which the plugin is designed to search: // (this provides a way for Firefox to let the user visit the web site directly) addNewBranch($openSearchCollection, "mozilla:SearchForm", array(), $databaseBaseURL); // this will show the main refbase page with the Quick Search form (to link to other search pages, append '. "simple_search.php"' etc) // --- end Mozilla-specific elements ------------------------ $openSearchCollectionDoc->setXML($openSearchCollection); $openSearchCollectionString = $openSearchCollectionDoc->getXMLString(); // Add the XML Stylesheet definition: // Note that this is just a hack (that should get fixed) since I don't know how to do it properly using the ActiveLink PHP XML Package ?:-/ if (!empty($exportStylesheet)) $openSearchCollectionString = preg_replace("/(?=\\n",$openSearchCollectionString); return $openSearchCollectionString; } // -------------------------------------------------------------------- // Return OpenSearch diagnostics (i.e. OpenSearch error information) wrapped into OpenSearch Atom XML: function openSearchDiagnostics($diagCode, $diagDetails, $exportStylesheet) { global $contentTypeCharset; // defined in 'ini.inc.php' // Map SRU/W diagnostic numbers to their corresponding messages: // (i.e., for OpenSearch diagnostics, we simply re-use the SRU/W diagnostics) $diagMessages = mapSRWDiagnostics(); // function 'mapSRWDiagnostics()' is defined in 'webservice.inc.php' if (isset($diagMessages[$diagCode])) $diagMessage = $diagMessages[$diagCode]; else $diagMessage = "Unknown error"; $atomCollectionDoc = new XMLDocument(); $atomCollectionDoc->setEncoding($contentTypeCharset); $atomCollection = openSearchGenerateBaseTags("Error"); // add feed-level tags: // - 'id': addNewBranch($atomCollection, "id", array(), "info:srw/diagnostic/1/"); // could something else be used as diagnostics feed ID instead? // - OpenSearch elements: addNewBranch($atomCollection, "opensearch:totalResults", array(), "1"); addNewBranch($atomCollection, "openSearch:startIndex", array(), "1"); addNewBranch($atomCollection, "openSearch:itemsPerPage", array(), "1"); $diagnosticsBranch = new XMLBranch("entry"); // add entry-level tags: addNewBranch($diagnosticsBranch, "title", array(), $diagMessage); // addNewBranch($atomCollection, "link", array("href" => ""), ""); // TODO (what could be used as link for a diagnostics entry?) addNewBranch($diagnosticsBranch, "updated", array(), generateISO8601TimeStamp()); // function 'generateISO8601TimeStamp()' is defined in 'include.inc.php' addNewBranch($diagnosticsBranch, "id", array(), "info:srw/diagnostic/1/" . $diagCode); $diagContent = $diagMessage; if (!empty($diagDetails)) $diagContent .= ": " . $diagDetails; addNewBranch($diagnosticsBranch, "content", array("type" => "text"), "Error " . $diagCode . ": " . $diagContent); // TODO: I18n $atomCollection->addXMLBranch($diagnosticsBranch); $atomCollectionDoc->setXML($atomCollection); $atomCollectionString = $atomCollectionDoc->getXMLString(); return $atomCollectionString; } // -------------------------------------------------------------------- // Generate the basic OpenSearch XML tree required for a query response: function openSearchGenerateBaseTags($openSearchOperation) { if ($openSearchOperation == "Error") // OpenSearch Atom XML is used for diagnostics $atomCollection = atomGenerateBaseTags($openSearchOperation); // function 'atomGenerateBaseTags()' is defined in 'atomxml.inc.php' elseif ($openSearchOperation == "Description") // OpenSearch Description XML { $atomCollection = new XML("OpenSearchDescription"); $atomCollection->setTagAttribute("xmlns", "http://a9.com/-/spec/opensearch/1.1/"); $atomCollection->setTagAttribute("xmlns:opensearch", "http://a9.com/-/spec/opensearch/1.1/"); $atomCollection->setTagAttribute("xmlns:mozilla", "http://www.mozilla.org/2006/browser/search/"); } return $atomCollection; } // -------------------------------------------------------------------- ?>