コード例 #1
0
ファイル: search.php プロジェクト: Olari0/Finugriling
function displayDetails($result, $rowsFound, $query, $queryURL, $showQuery, $showLinks, $rowOffset, $showRows, $previousOffset, $nextOffset, $wrapResults, $nothingChecked, $citeStyle, $citeOrder, $orderBy, $showMaxRow, $headerMsg, $userID, $displayType, $viewType, $addCounterMax, $formType)
{
    global $filesBaseURL;
    // these variables are defined in 'ini.inc.php'
    global $searchReplaceActionsArray;
    global $databaseBaseURL;
    global $defaultDropDownFieldsEveryone;
    global $defaultDropDownFieldsLogin;
    global $displayResultsHeaderDefault;
    global $displayResultsFooterDefault;
    global $showFieldItemLinks;
    global $fileVisibility;
    global $fileVisibilityException;
    global $maximumBrowseLinks;
    global $openURLResolver;
    global $isbnURLFormat;
    global $loc;
    // '$loc' is made globally available in 'core.php'
    global $client;
    if ($formType != "queryResults" or $formType == "queryResults" and !$nothingChecked) {
        // If the query has results ...
        if ($rowsFound > 0) {
            // BEGIN RESULTS HEADER --------------------
            // 1) First, initialize some variables that we'll need later on
            if ($showLinks == "1") {
                $CounterMax = 5;
            } else {
                $CounterMax = 0;
            }
            // Otherwise don't hide any columns
            if (isset($_SESSION['loginEmail']) and preg_match("/SELECT .*?\\brelated\\b.*? FROM /i", $query)) {
                // if a user is logged in, and the 'related' field is part of the SQL SELECT clause...
                $CounterMax = $CounterMax + 1;
            }
            // ...we'll also need to hide the 'related' column (which isn't displayed in Details view but is only used to generate a link to related records)
            // count the number of fields
            $fieldsFound = mysql_num_fields($result);
            // hide those last columns that were added by the script and not by the user
            $fieldsToDisplay = $fieldsFound - (2 + $CounterMax + $addCounterMax);
            // (2+$CounterMax) -> $CounterMax is increased by 2 in order to hide the 'orig_record' & 'serial' columns (which were added to make checkboxes & dup warning work)
            // $addCounterMax is set to 1 when the field given in '$fileVisibilityException[0]' (defined in 'ini.inc.php') was added to the query, otherwise '$addCounterMax = 0'
            // In summary, when displaying a 'Links' column AND with a user being logged in AND with '$addCounterMax = 1', we hide the following fields: 'related, (the field given in '$fileVisibilityException[0]'), orig_record, serial, file, url, doi, isbn, type' (i.e., truncate the last nine columns)
            // Calculate the number of all visible columns (which is needed as colspan value inside some TD tags)
            if ($showLinks == "1") {
                // in 'display details' layout, we simply set it to a fixed no of columns:
                $NoColumns = 8;
            } else {
                $NoColumns = 7;
            }
            // 7 columns: checkbox, field name, field contents
            // Save the current Details view query to a session variable:
            saveSessionVariable("lastDetailsViewQuery", $query);
            // Defines field-specific search & replace 'actions' that will be applied to all those refbase
            // fields that are listed in the corresponding 'fields' element:
            // (These search and replace actions will be performed *in addition* to those specified globally
            //  in '$searchReplaceActionsArray' (defined in 'ini.inc.php'). Same rules apply as for
            //  '$searchReplaceActionsArray'.)
            $fieldSpecificSearchReplaceActionsArray = array(array('fields' => array("abstract"), 'actions' => array("/[\r\n]+/" => "<br><br>")), array('fields' => array("thesis", "approved", "marked", "copy", "selected"), 'actions' => array("/(.+)/e" => "\$loc['\\1']")), array('fields' => array("type"), 'actions' => array("/(.+)/e" => "\$loc['type\\1']")));
            // NOTE: We substitute contents of the given fields with localized field values from variable
            //       '$loc' (see '$fieldSpecificSearchReplaceActionsArray'). Since the locales in '$loc'
            //       are already HTML encoded, we have to exclude these fields from any further HTML encoding.
            static $encodingExceptionsArray = array("thesis", "approved", "marked", "copy", "selected", "type");
            // Note: we omit the results header, browse links & query form for CLI clients, and when outputting only a partial document structure ('wrapResults=0')
            if (!preg_match("/^cli/i", $client) and $wrapResults != "0") {
                // Note: we also omit the results header in print/mobile view! ('viewType=Print' or 'viewType=Mobile')
                if (!preg_match("/^(Print|Mobile)\$/i", $viewType) and (!isset($displayResultsHeaderDefault[$displayType]) or isset($displayResultsHeaderDefault[$displayType]) and $displayResultsHeaderDefault[$displayType] != "hidden")) {
                    // Extract the first field from the 'WHERE' clause:
                    if (preg_match("/ WHERE [ ()]*(\\w+)/i", $query)) {
                        $selectedField = preg_replace("/.+ WHERE [ ()]*(\\w+).*/i", "\\1", $query);
                    } else {
                        $selectedField = "author";
                    }
                    // in the 'Search within Results" form, we'll select the 'author' field by default
                    // Map MySQL field names to localized column names:
                    $fieldNamesArray = mapFieldNames(true);
                    // function 'mapFieldNames()' is defined in 'include.inc.php'
                    $localizedDropDownFieldsArray = array();
                    if (isset($_SESSION['loginEmail']) and !empty($defaultDropDownFieldsLogin)) {
                        // if a user is logged in -AND- there were any additional fields specified...
                        $dropDownFieldsArray = array_merge($defaultDropDownFieldsEveryone, $defaultDropDownFieldsLogin);
                    } else {
                        $dropDownFieldsArray = $defaultDropDownFieldsEveryone;
                    }
                    foreach ($dropDownFieldsArray as $field) {
                        if (isset($fieldNamesArray[$field])) {
                            $localizedDropDownFieldsArray[$field] = $fieldNamesArray[$field];
                        } else {
                            // no localized field name exists, so we use the original field name
                            $localizedDropDownFieldsArray[$field] = $field;
                        }
                    }
                    // Define option values for the display options dropdown menu:
                    $displayOptionsDropDownItemsArray = array("all fields" => $loc["DropDownFieldName_AllFields"], "keywords, abstract" => $loc["DropDownFieldName_KeywordsAbstract"], "additional fields" => $loc["DropDownFieldName_AdditionalFields"]);
                    if (isset($_SESSION['loginEmail'])) {
                        // if a user is logged in
                        $displayOptionsDropDownItemsArray["my fields"] = $loc["DropDownFieldName_MyFields"];
                    }
                    // 2) Build forms containing options to show the user's groups, refine the search results or change the displayed columns:
                    //    TODO for 2b+2c: should we allow users to choose via the web interface which columns are included in the popup menus?
                    //    2a) Build a FORM with a popup containing the user's groups:
                    $formElementsGroup = buildGroupSearchElements("search.php", $queryURL, $query, $showQuery, $showLinks, $showRows, $citeStyle, $citeOrder, $displayType);
                    // function 'buildGroupSearchElements()' is defined in 'include.inc.php'
                    //    2b) Build a FORM containing options to refine the search results:
                    //        Call the 'buildRefineSearchElements()' function (defined in 'include.inc.php') which does the actual work:
                    $formElementsRefine = buildRefineSearchElements("search.php", $queryURL, $showQuery, $showLinks, $showRows, $citeStyle, $citeOrder, $localizedDropDownFieldsArray, $selectedField, $displayType);
                    //    2c) Build a FORM containing display options (show/hide columns or change the number of records displayed per page):
                    //        Call the 'buildDisplayOptionsElements()' function (defined in 'include.inc.php') which does the actual work:
                    $formElementsDisplayOptions = buildDisplayOptionsElements("search.php", $queryURL, $showQuery, $showLinks, $rowOffset, $showRows, $citeStyle, $citeOrder, $displayOptionsDropDownItemsArray, "", $fieldsToDisplay, $displayType, $headerMsg);
                    echo displayResultsHeader("search.php", $formElementsGroup, $formElementsRefine, $formElementsDisplayOptions, $displayType);
                    // function 'displayResultsHeader()' is defined in 'results_header.inc.php'
                    //    and insert a divider line (which separates the results header from the browse links & results data below):
                    echo "\n";
                }
                // 3) Build a TABLE with links for "previous" & "next" browsing, as well as links to intermediate pages
                //    call the 'buildBrowseLinks()' function (defined in 'include.inc.php'):
                $BrowseLinks = buildBrowseLinks("search.php", $query, $NoColumns, $rowsFound, $showQuery, $showLinks, $showRows, $rowOffset, $previousOffset, $nextOffset, $wrapResults, $maximumBrowseLinks, "sqlSearch", "Display", $citeStyle, $citeOrder, $orderBy, $headerMsg, $viewType);
                echo $BrowseLinks;
                // 4) Start a FORM
                if (!preg_match("/^Print\$/i", $viewType) and (!isset($displayResultsFooterDefault[$displayType]) or isset($displayResultsFooterDefault[$displayType]) and $displayResultsFooterDefault[$displayType] != "hidden")) {
                    echo "\n<form action=\"search.php\" method=\"GET\" name=\"queryResults\">" . "\n<input type=\"hidden\" name=\"formType\" value=\"queryResults\">" . "\n<input type=\"hidden\" name=\"submit\" value=\"Cite\">" . "\n<input type=\"hidden\" name=\"originalDisplayType\" value=\"{$displayType}\">" . "\n<input type=\"hidden\" name=\"orderBy\" value=\"" . rawurlencode($orderBy) . "\">" . "\n<input type=\"hidden\" name=\"showQuery\" value=\"{$showQuery}\">" . "\n<input type=\"hidden\" name=\"showLinks\" value=\"{$showLinks}\">" . "\n<input type=\"hidden\" name=\"showRows\" value=\"{$showRows}\">" . "\n<input type=\"hidden\" name=\"rowOffset\" value=\"{$rowOffset}\">" . "\n<input type=\"hidden\" name=\"sqlQuery\" value=\"{$queryURL}\">";
                    // embed the current sqlQuery so that it can be re-applied after the user pressed either of the 'Add' or 'Remove' buttons within the 'queryResults' form
                }
            }
            // 5) And start a TABLE, with column headers
            echo "\n<table id=\"details\" class=\"results\" align=\"center\" border=\"0\" cellpadding=\"5\" cellspacing=\"0\" width=\"95%\" summary=\"This table holds the database results for your query\">";
            //    for the column headers, start a TABLE ROW ...
            echo "\n<tr>";
            // ... print a marker ('x') column (which will hold the checkboxes within the results part)
            if (!preg_match("/^(Print|Mobile)\$/i", $viewType) and !preg_match("/^cli/i", $client) and $wrapResults != "0") {
                // Note: we omit the marker column in print/mobile view ('viewType=Print' or 'viewType=Mobile'), for CLI clients, and when outputting only a partial document structure ('wrapResults=0')!
                echo "\n\t<th align=\"left\" valign=\"top\">&nbsp;</th>";
            }
            // ... print a record header
            if ($showMaxRow - $rowOffset == "1") {
                // '$showMaxRow-$rowOffset' gives the number of displayed records for a particular page) // '($rowsFound == "1" || $showRows == "1")' wouldn't trap the case of a single record on the last of multiple results pages!
                $recordHeader = $loc["Record"];
            } else {
                $recordHeader = $loc["Records"];
            }
            // use plural form if there are multiple records to display
            echo "\n\t<th align=\"left\" valign=\"top\" colspan=\"6\">{$recordHeader}</th>";
            if ($showLinks == "1") {
                $newORDER = "ORDER BY url DESC, doi DESC";
                // Build the appropriate ORDER BY clause to facilitate sorting by Links column
                $HTMLbeforeLink = "\n\t<th align=\"left\" valign=\"top\">";
                // start the table header tag
                $HTMLafterLink = "</th>";
                // close the table header tag
                // call the 'buildFieldNameLinks()' function (defined in 'include.inc.php'), which will return a properly formatted table header tag holding the current field's name
                // as well as the URL encoded query with the appropriate ORDER clause:
                $tableHeaderLink = buildFieldNameLinks("search.php", $query, $newORDER, $result, "", $showQuery, $showLinks, $rowOffset, $showRows, $wrapResults, $citeStyle, $HTMLbeforeLink, $HTMLafterLink, "sqlSearch", "Display", $loc["Links"], "url", $headerMsg, $viewType);
                echo $tableHeaderLink;
                // print the attribute name as link
            }
            // Finish the row
            echo "\n</tr>";
            // END RESULTS HEADER ----------------------
            // BEGIN RESULTS DATA COLUMNS --------------
            // Fetch one page of results (or less if on the last page)
            // (i.e., upto the limit specified in $showRows) fetch a row into the $row array and ...
            for ($rowCounter = 0; $rowCounter < $showRows && ($row = @mysql_fetch_array($result)); $rowCounter++) {
                // ... print out each of the attributes
                // in that row as a separate TR (Table Row)
                $recordData = "";
                // make sure that buffer variable is empty
                for ($i = 0; $i < $fieldsToDisplay; $i++) {
                    // fetch the current attribute name:
                    $orig_fieldname = getMySQLFieldInfo($result, $i, "name");
                    // function 'getMySQLFieldInfo()' is defined in 'include.inc.php'
                    // for all the fields specified (-> all fields to the left):
                    if (preg_match("/^(author|title|year|volume|corporate_author|address|keywords|abstract|publisher|language|series_editor|series_volume|issn|area|notes|location|call_number|marked|user_keys|user_notes|user_groups|created_date|modified_date)\$/", $orig_fieldname)) {
                        $recordData .= "\n<tr class=\"record\">";
                        // ...start a new TABLE row
                        if (!preg_match("/^(Print|Mobile)\$/i", $viewType) and !preg_match("/^cli/i", $client) and $wrapResults != "0") {
                            if ($i == 0) {
                                // ... print a column with a checkbox if it's the first row of attribute data:
                                $recordData .= "\n\t<td align=\"left\" valign=\"top\" width=\"10\"><input type=\"checkbox\" onclick=\"updateAllRecs();\" name=\"marked[]\" value=\"" . $row["serial"] . "\" title=\"" . $loc["selectRecord"] . "\"></td>";
                            } else {
                                // ... otherwise simply print an empty TD tag:
                                $recordData .= "\n\t<td valign=\"top\" width=\"10\">&nbsp;</td>";
                            }
                        }
                    }
                    // ... and print out each of the ATTRIBUTE NAMES:
                    // in that row as a bold link...
                    if (preg_match("/^(author|title|type|year|publication|abbrev_journal|volume|issue|pages|call_number|serial)\$/", $orig_fieldname)) {
                        $HTMLbeforeLink = "\n\t<td valign=\"top\" width=\"75\" class=\"mainfieldsbg\">";
                        // start the (bold) TD tag
                        $HTMLafterLink = "</td>";
                        // close the (bold) TD tag
                    } elseif (preg_match("/^(marked|copy|selected|user_keys|user_notes|user_file|user_groups|cite_key)\$/", $orig_fieldname)) {
                        $HTMLbeforeLink = "\n\t<td valign=\"top\" width=\"75\" class=\"userfieldsbg\">";
                        // start the (bold) TD tag
                        $HTMLafterLink = "</td>";
                        // close the (bold) TD tag
                    } else {
                        $HTMLbeforeLink = "\n\t<td valign=\"top\" width=\"75\" class=\"otherfieldsbg\">";
                        // start the (bold) TD tag
                        $HTMLafterLink = "</td>";
                        // close the (bold) TD tag
                    }
                    // call the 'buildFieldNameLinks()' function (defined in 'include.inc.php'), which will return a properly formatted table data tag holding the current field's name
                    // as well as the URL encoded query with the appropriate ORDER clause:
                    $recordData .= buildFieldNameLinks("search.php", $query, "", $result, $i, $showQuery, $showLinks, $rowOffset, $showRows, $wrapResults, $citeStyle, $HTMLbeforeLink, $HTMLafterLink, "sqlSearch", "Display", "", "", $headerMsg, $viewType);
                    // print the ATTRIBUTE DATA:
                    // first, calculate the correct colspan value for all the fields specified:
                    if (preg_match("/^(author|address|keywords|abstract|location|user_keys)\$/", $orig_fieldname)) {
                        $ColspanFields = 5;
                    } elseif (preg_match("/^(title|corporate_author|notes|call_number|user_notes|user_groups)\$/", $orig_fieldname)) {
                        $ColspanFields = 3;
                    }
                    // supply an appropriate colspan value
                    // then, start the TD tag, for all the fields specified:
                    if (preg_match("/^(author|title|corporate_author|address|keywords|abstract|notes|location|call_number|user_keys|user_notes|user_groups)\$/", $orig_fieldname)) {
                        if (preg_match("/^(author|title|call_number)\$/", $orig_fieldname)) {
                            // print a colored background (grey, by default)
                            $recordData .= "\n\t<td valign=\"top\" colspan=\"{$ColspanFields}\" class=\"mainfieldsbg\">";
                        } elseif (preg_match("/^(user_keys|user_notes|user_file|user_groups)\$/", $orig_fieldname)) {
                            // print a colored background (light orange, by default) for all the user specific fields
                            $recordData .= "\n\t<td valign=\"top\" colspan=\"{$ColspanFields}\" class=\"userfieldsbg\">";
                        } else {
                            // no colored background (by default)
                            $recordData .= "\n\t<td valign=\"top\" colspan=\"{$ColspanFields}\" class=\"otherfieldsbg\">";
                        }
                        // ...with colspan attribute & appropriate value
                    } else {
                        if (preg_match("/^(type|year|publication|abbrev_journal|volume|issue|pages|serial)\$/", $orig_fieldname)) {
                            // print a colored background (grey, by default)
                            $recordData .= "\n\t<td valign=\"top\" class=\"mainfieldsbg\">";
                        } elseif (preg_match("/^(marked|copy|selected|user_file|cite_key)\$/", $orig_fieldname)) {
                            // print a colored background (light orange, by default) for all the user specific fields
                            $recordData .= "\n\t<td valign=\"top\" class=\"userfieldsbg\">";
                        } else {
                            // no colored background (by default)
                            $recordData .= "\n\t<td valign=\"top\" class=\"otherfieldsbg\">";
                        }
                        // ...without colspan attribute
                    }
                    // print the attribute data:
                    if (!empty($row[$i])) {
                        if (preg_match("/^(author|title|year)\$/", $orig_fieldname)) {
                            // print author, title & year fields in bold
                            $recordData .= "";
                        }
                        // make field items into clickable search links:
                        if (in_array($displayType, $showFieldItemLinks)) {
                            // Note: function 'linkifyFieldItems()' will also call function 'encodeField()' to HTML
                            //       encode non-ASCII chars and to apply any field-specific search & replace actions
                            $recordData .= linkifyFieldItems($orig_fieldname, $row[$i], $userID, $fieldSpecificSearchReplaceActionsArray, $encodingExceptionsArray, "/\\s*[;]+\\s*/", "; ", $showQuery, $showLinks, $showRows, $citeStyle, $citeOrder, $wrapResults, $displayType, $viewType);
                        } else {
                            // don't hotlink field items
                            $recordData .= encodeField($orig_fieldname, $row[$i], $fieldSpecificSearchReplaceActionsArray, $encodingExceptionsArray);
                        }
                        // function 'encodeField()' is defined in 'include.inc.php'
                        if (preg_match("/^(author|title|year)\$/", $orig_fieldname)) {
                            $recordData .= "";
                        }
                    }
                    $recordData .= "</td>";
                    // finish the TD tag
                    // for all the fields specified (-> all fields to the right):
                    if (preg_match("/^(author|type|abbrev_journal|pages|thesis|address|keywords|abstract|editor|orig_title|abbrev_series_title|edition|medium|conference|approved|location|serial|selected|user_keys|user_file|cite_key|created_by|modified_by)\$/", $orig_fieldname)) {
                        if ($showLinks == "1") {
                            // ...embed appropriate links (if available):
                            if ($i == 0) {
                                if (preg_match("/^(cli|inc)/i", $client) or $wrapResults == "0") {
                                    // we use absolute links for CLI clients, for include mechanisms, or when returning only a partial document structure
                                    $baseURL = $databaseBaseURL;
                                } else {
                                    $baseURL = "";
                                }
                                $recordData .= "\n\t<td valign=\"top\" width=\"50\" rowspan=\"2\">";
                                // note that this table cell spans the next row!
                                $linkArray = array();
                                // initialize array variable that will hold all available links
                                if (isset($_SESSION['user_permissions']) and preg_match("/allow_edit/", $_SESSION['user_permissions'])) {
                                    // if the 'user_permissions' session variable contains 'allow_edit'...
                                    // ... display a link that opens the edit form for this record:
                                    $linkArray[] = "\n\t\t<a href=\"" . $baseURL . "record.php" . "?serialNo=" . $row["serial"] . "&amp;recordAction=edit" . "\"><i class=\"fa fa-search\"></i></a>";
                                }
                                // show a link to any corresponding FILE if one of the following conditions is met:
                                // - the variable '$fileVisibility' (defined in 'ini.inc.php') is set to 'everyone'
                                // - the variable '$fileVisibility' is set to 'login' AND the user is logged in
                                // - the variable '$fileVisibility' is set to 'user-specific' AND the 'user_permissions' session variable contains 'allow_download'
                                // - the array variable '$fileVisibilityException' (defined in 'ini.inc.php') contains a pattern (in array element 1) that matches the contents of the field given (in array element 0)
                                if ($fileVisibility == "everyone" or $fileVisibility == "login" and isset($_SESSION['loginEmail']) or $fileVisibility == "user-specific" and (isset($_SESSION['user_permissions']) and preg_match("/allow_download/", $_SESSION['user_permissions'])) or !empty($fileVisibilityException) and preg_match($fileVisibilityException[1], $row[$fileVisibilityException[0]])) {
                                    if (!empty($row["file"])) {
                                        if (isset($_SESSION['user_permissions']) and preg_match("/allow_edit/", $_SESSION['user_permissions'])) {
                                            $prefix = "&nbsp;";
                                        } else {
                                            $prefix = "";
                                        }
                                        if (preg_match("#^(https?|ftp|file)://#i", $row["file"])) {
                                            // if the 'file' field contains a full URL (starting with "http://", "https://", "ftp://" or "file://")
                                            $URLprefix = "";
                                        } else {
                                            // if the 'file' field contains only a partial path (like 'polarbiol/10240001.pdf') or just a file name (like '10240001.pdf')
                                            $URLprefix = $filesBaseURL;
                                        }
                                        // use the base URL of the standard files directory as prefix ('$filesBaseURL' is defined in 'ini.inc.php')
                                        if (preg_match("/\\.pdf\$/i", $row["file"])) {
                                            // if the 'file' field contains a link to a PDF file
                                            $linkArray[] = $prefix . "\n\t\t<a href=\"" . $URLprefix . $row["file"] . "\"><img src=\"" . $baseURL . "img/file_PDF.gif\" alt=\"" . $loc["pdf"] . "\" title=\"" . $loc["LinkTitle_DownloadPDFFile"] . "\" width=\"17\" height=\"17\" hspace=\"0\" border=\"0\"></a>";
                                        } else {
                                            $linkArray[] = $prefix . "\n\t\t<a href=\"" . $URLprefix . $row["file"] . "\"><img src=\"" . $baseURL . "img/file.gif\" alt=\"" . $loc["file"] . "\" title=\"" . $loc["LinkTitle_DownloadFile"] . "\" width=\"11\" height=\"15\" hspace=\"0\" border=\"0\"></a>";
                                        }
                                        // display a generic file icon as download link
                                    }
                                }
                                // generate a link from the URL field:
                                if (!empty($row["url"])) {
                                    // 'htmlentities()' is used to convert any '&' into '&amp;'
                                    $linkArray[] = "\n\t\t<a href=\"" . encodeHTML($row["url"]) . "\"><img src=\"" . $baseURL . "img/www.gif\" alt=\"" . $loc["url"] . "\" title=\"" . $loc["LinkTitle_GotoWebPage"] . "\" width=\"17\" height=\"20\" hspace=\"0\" border=\"0\"></a>";
                                }
                                // generate a link from the DOI field:
                                if (!empty($row["doi"])) {
                                    $linkArray[] = "\n\t\t<a href=\"http://dx.doi.org/" . rawurlencode($row["doi"]) . "\"><img src=\"" . $baseURL . "img/doi.gif\" alt=\"" . $loc["doi"] . "\" title=\"" . $loc["LinkTitle_GotoWebPageViaDOI"] . "\" width=\"17\" height=\"20\" hspace=\"0\" border=\"0\"></a>";
                                }
                                // generate a link from the RELATED field:
                                if (isset($_SESSION['loginEmail'])) {
                                    if (!empty($row["related"])) {
                                        $relatedRecordsLink = buildRelatedRecordsLink($row["related"], $userID);
                                        // function 'buildRelatedRecordsLink()' is defined in 'include.inc.php'
                                        $linkArray[] = "\n\t\t<a href=\"" . $baseURL . $relatedRecordsLink . "\"><img src=\"" . $baseURL . "img/related.gif\" alt=\"" . $loc["related"] . "\" title=\"" . $loc["LinkTitle_DisplayRelatedRecords"] . "\" width=\"19\" height=\"16\" hspace=\"0\" border=\"0\"></a>";
                                    }
                                }
                                // if an ISBN number exists for the current record, provide a link to an ISBN resolver:
                                if (!empty($isbnURLFormat) and !empty($row["isbn"])) {
                                    // this is a stupid hack that maps the names of the '$row' array keys to those used
                                    // by the '$formVars' array (which is required by function 'parsePlaceholderString()')
                                    // (eventually, the '$formVars' array should use the MySQL field names as names for its array keys)
                                    $formVars = buildFormVarsArray($row);
                                    // function 'buildFormVarsArray()' is defined in 'include.inc.php'
                                    // auto-generate an ISBN link according to the naming scheme given in '$isbnURLFormat' (in 'ini.inc.php'):
                                    $isbnURL = parsePlaceholderString($formVars, $isbnURLFormat, "");
                                    // function 'parsePlaceholderString()' is defined in 'include.inc.php'
                                    $encodedURL = encodeHTML($isbnURL);
                                    // 'htmlentities()' is used to convert higher ASCII chars into its entities and any '&' into '&amp;'
                                    $encodedURL = str_replace(" ", "%20", $encodedURL);
                                    // ensure that any spaces are also properly urlencoded
                                    if (!empty($isbnURL)) {
                                        $linkArray[] = "\n\t\t<a href=\"" . $encodedURL . "\"><img src=\"" . $baseURL . "img/isbn.gif\" alt=\"" . $loc["isbn"] . "\" title=\"" . $loc["LinkTitle_FindBookDetailsViaISBN"] . "\" width=\"17\" height=\"20\" hspace=\"0\" border=\"0\"></a>";
                                    }
                                }
                                // provide a link to an OpenURL resolver:
                                if (!empty($openURLResolver)) {
                                    $openURL = openURL($row);
                                    // function 'openURL()' is defined in 'openurl.inc.php'
                                    $linkArray[] = "\n\t\t<a href=\"" . $openURL . "\"><i class=\"fa fa-external-link\"></i></a>";
                                }
                                // insert COinS (ContextObjects in Spans):
                                $linkArray[] = "\n\t\t" . coins($row);
                                // function 'coins()' is defined in 'openurl.inc.php'
                                // merge links with delimiters appropriate for display in the Links column:
                                $recordData .= mergeLinks($linkArray);
                                $recordData .= "\n\t</td>";
                            } elseif ($i > 3) {
                                // ... for the third row up to the last row, simply print an empty TD tag:
                                $recordData .= "\n\t<td valign=\"top\" width=\"50\">&nbsp;</td>";
                            }
                        }
                        $recordData .= "\n</tr>";
                        // ...and finish the row
                    }
                }
                if (!preg_match("/^(Print|Mobile)\$/i", $viewType) and !preg_match("/^cli/i", $client) and $wrapResults != "0") {
                    // supply an appropriate colspan value
                    $ColspanFields = $NoColumns;
                } else {
                    // print view, CLI client, or partial document structure (i.e., no marker column)
                    $ColspanFields = $NoColumns - 1;
                }
                // Print out an URL that links directly to this record:
                $recordData .= "\n<tr class=\"record-link\">" . "\n\t<td colspan=\"{$ColspanFields}\" align=\"center\" class=\"smaller\"><a href=\"" . $databaseBaseURL . "show.php?record=" . $row["serial"] . "\" title=\"" . $loc["LinkTitle_Permalink"] . "\">" . $loc["PermalinkLong"] . "</a>" . "<div class=\"unapi\"><abbr class=\"unapi-id\" title=\"" . $databaseBaseURL . "show.php?record=" . $row["serial"] . "\"></abbr></div></td>" . "\n</tr>";
                // Append a divider line if it's not the last (or only) record on the page:
                if ($rowCounter + 1 < $showRows && $rowCounter + 1 < $rowsFound) {
                    if (!($showMaxRow == $rowsFound && $rowCounter + 1 == $showMaxRow - $rowOffset)) {
                        // if we're NOT on the *last* page processing the *last* record... ('$showMaxRow-$rowOffset' gives the number of displayed records for a particular page)
                        $recordData .= "\n<tr class=\"colspan\">" . "\n\t<td colspan=\"{$ColspanFields}\">&nbsp;</td>" . "\n</tr>" . "\n<tr class=\"colspan\">" . "\n\t<td colspan=\"{$ColspanFields}\"></td>" . "\n</tr>" . "\n<tr class=\"colspan\">" . "\n\t<td colspan=\"{$ColspanFields}\">&nbsp;</td>" . "\n</tr>";
                    }
                }
                echo $recordData;
            }
            // Finish the table
            echo "\n</table>";
            // END RESULTS DATA COLUMNS ----------------
            // BEGIN RESULTS FOOTER --------------------
            // Note: we omit the results footer, browse links & query form in print/mobile view ('viewType=Print' or 'viewType=Mobile'), for CLI clients, and when outputting only a partial document structure ('wrapResults=0')!
            if (!preg_match("/^(Print|Mobile)\$/i", $viewType) and !preg_match("/^cli/i", $client) and $wrapResults != "0") {
                // Again, insert the (already constructed) BROWSE LINKS
                // (i.e., a TABLE with links for "previous" & "next" browsing, as well as links to intermediate pages)
                echo $BrowseLinks;
                // Build a results footer with form elements to cite, group or export all/selected records:
                if (!isset($displayResultsFooterDefault[$displayType]) or isset($displayResultsFooterDefault[$displayType]) and $displayResultsFooterDefault[$displayType] != "hidden") {
                    if (isset($_SESSION['user_permissions']) and (isset($_SESSION['loginEmail']) and preg_match("/allow_cite|allow_user_groups|allow_export|allow_batch_export/", $_SESSION['user_permissions']) or !isset($_SESSION['loginEmail']) and preg_match("/allow_cite|allow_export|allow_batch_export/", $_SESSION['user_permissions']))) {
                        // if the 'user_permissions' session variable does contain any of the following: 'allow_cite' -AND- if logged in, aditionally: 'allow_user_groups', 'allow_export', 'allow_batch_export'...
                        // ...Insert a divider line (which separates the results data from the forms in the footer):
                        echo "\n";
                    }
                    // Call the 'buildResultsFooter()' function (which does the actual work):
                    $ResultsFooter = buildResultsFooter($showRows, $citeStyle, $citeOrder, $displayType, $headerMsg);
                    echo $ResultsFooter;
                }
            }
            // END RESULTS FOOTER ----------------------
            // Finally, finish the form
            if (!preg_match("/^Print\$/i", $viewType) and !preg_match("/^cli/i", $client) and $wrapResults != "0" and (!isset($displayResultsFooterDefault[$displayType]) or isset($displayResultsFooterDefault[$displayType]) and $displayResultsFooterDefault[$displayType] != "hidden")) {
                echo "\n</form>";
            }
        } else {
            // Report that nothing was found:
            $nothingFoundFeedback = nothingFound(false);
            // This is a clumsy workaround: by pretending that there were some records marked by the user ($nothingChecked = false) we force the 'nothingFound()' function to output "Sorry, but your query didn't produce any results!" instead of "No records selected..."
            echo $nothingFoundFeedback;
        }
        // end if $rowsFound body
    } else {
        // Report that nothing was selected:
        $nothingFoundFeedback = nothingFound($nothingChecked);
        echo $nothingFoundFeedback;
    }
}
コード例 #2
0
ファイル: cite_html.php プロジェクト: Olari0/Finugriling
function citeRecords($result, $rowsFound, $query, $queryURL, $showQuery, $showLinks, $rowOffset, $showRows, $previousOffset, $nextOffset, $wrapResults, $citeStyle, $citeOrder, $citeType, $orderBy, $headerMsg, $userID, $viewType)
{
    global $databaseBaseURL;
    // these variables are defined in 'ini.inc.php'
    global $useVisualEffects;
    global $defaultDropDownFieldsEveryone;
    global $defaultDropDownFieldsLogin;
    global $defaultCiteStyle;
    global $additionalFieldsCitationView;
    global $displayResultsHeaderDefault;
    global $displayResultsFooterDefault;
    global $showLinkTypesInCitationView;
    global $showFieldItemLinks;
    global $maximumBrowseLinks;
    global $loc;
    // '$loc' is made globally available in 'core.php'
    global $client;
    global $displayType;
    $htmlData = "";
    // make sure that our buffer variables are empty
    $recordData = "";
    // First, initialize some variables that we'll need later on
    // Calculate the number of all visible columns (which is needed as colspan value inside some TD tags)
    if ($showLinks == "1" && preg_match("/^(type|type-year|year)\$/i", $citeOrder)) {
        // in citation layout, we simply set it to a fixed value (either '1' or '2', depending on the values of '$showLinks' and '$citeOrder')
        $NoColumns = 2;
    } else {
        $NoColumns = 1;
    }
    if (empty($displayType)) {
        $displayType = $_SESSION['userDefaultView'];
    }
    // get the default view for the current user
    // If the results footer is displayed, we increase the colspan value by 1 to account for the checkbox column:
    if (!preg_match("/^(Print|Mobile)\$/i", $viewType) and !preg_match("/^cli/i", $client) and $wrapResults != "0" and (!isset($displayResultsFooterDefault[$displayType]) or isset($displayResultsFooterDefault[$displayType]) and $displayResultsFooterDefault[$displayType] != "hidden")) {
        $NoColumns++;
    }
    // Initialize array variables:
    $yearsArray = array();
    $typeTitlesArray = array();
    // Define inline text markup to be used by the 'citeRecord()' function:
    $markupPatternsArray = array("bold-prefix" => "<b>", "bold-suffix" => "</b>", "italic-prefix" => "<i>", "italic-suffix" => "</i>", "underline-prefix" => "<u>", "underline-suffix" => "</u>", "endash" => "&#8211;", "emdash" => "&#8212;", "ampersand" => "&", "double-quote" => '"', "double-quote-left" => "&ldquo;", "double-quote-right" => "&rdquo;", "single-quote" => "'", "single-quote-left" => "&lsquo;", "single-quote-right" => "&rsquo;", "less-than" => "<", "greater-than" => ">", "newline" => "\n<br>\n");
    // Defines field-specific search & replace 'actions' that will be applied to the actual citation
    // for all those refbase fields that are listed in the corresponding 'fields' element:
    // (These search and replace actions will be performed *in addition* to those specified globally
    //  in '$searchReplaceActionsArray' (defined in 'ini.inc.php'). Same rules apply as for
    //  '$searchReplaceActionsArray'.)
    $fieldSpecificSearchReplaceActionsArray = array(array('fields' => array("abstract"), 'actions' => array("/[\r\n]+/" => "\n<br>\n")));
    // In addition, for the "more info" section, we also substitute contents of the below 'fields'
    // with localized field values from variable '$loc'. Since the locales in '$loc' are already
    // HTML encoded, we have to exclude these fields from any further HTML encoding (done below).
    $fieldSpecificSearchReplaceActionsArray2 = $fieldSpecificSearchReplaceActionsArray;
    $fieldSpecificSearchReplaceActionsArray2[] = array('fields' => array("thesis", "approved", "marked", "copy", "selected"), 'actions' => array("/(.+)/e" => "\$loc['\\1']"));
    static $encodingExceptionsArray = array("thesis", "approved", "marked", "copy", "selected");
    // LOOP OVER EACH RECORD:
    // Fetch one page of results (or less if on the last page)
    // (i.e., upto the limit specified in $showRows) fetch a row into the $row array and ...
    for ($rowCounter = 0; $rowCounter < $showRows && ($row = @mysql_fetch_array($result)); $rowCounter++) {
        $encodedRowData = $row;
        // we keep '$row' in its original (unencoded) form since unencoded data will be required by function 'linkifyFieldItems()' below
        // NOTES: - Currently, HTML encoding and search & replace actions are applied separately
        //          for the citation and the "more info" section underneath the citation. The
        //          actions in this 'foreach' block concern the actual citation
        //        - It might be better to pass the unencoded '$row' data to function 'citeRecord()'
        //          which would then make calls to function 'encodeField()' individually for each
        //          field (similar to as it is done it 'modsxml.inc.php')
        foreach ($encodedRowData as $rowFieldName => $rowFieldValue) {
            // NOTES: - We HTML encode non-ASCII chars for all but the author & editor fields. The author & editor
            //          fields are excluded here since these fields must be passed *without* HTML entities to the
            //          'reArrangeAuthorContents()' function (which will then handle the HTML encoding by itself)
            //        - Function 'encodeField()' will also apply any field-specific search & replace actions
            $encodedRowData[$rowFieldName] = encodeField($rowFieldName, $rowFieldValue, $fieldSpecificSearchReplaceActionsArray, array("author", "editor"));
            // function 'encodeField()' is defined in 'include.inc.php'
        }
        // Order attributes according to the chosen output style & record type:
        $record = citeRecord($encodedRowData, $citeStyle, $citeType, $markupPatternsArray, true);
        // function 'citeRecord()' is defined in the citation style file given in '$citeStyleFile' (which, in turn, must reside in the 'cite' directory of the refbase root directory), see function 'generateCitations()'
        // Print out the current record:
        if (!empty($record)) {
            // Print any section heading(s):
            if (preg_match("/year|type/i", $citeOrder)) {
                if (preg_match("/^Mobile\$/i", $viewType)) {
                    $headingPrefix = "\n<div class=\"sect\">";
                    $headingSuffix = "</div>";
                } else {
                    $headingPrefix = "\n<tr>" . "\n\t<td valign=\"top\" colspan=\"{$NoColumns}\">";
                    $headingSuffix = "</td>" . "\n</tr>";
                }
                list($yearsArray, $typeTitlesArray, $sectionHeading) = generateSectionHeading($yearsArray, $typeTitlesArray, $row, $citeOrder, $headingPrefix, $headingSuffix, "<h4>", "</h4>", "<h5>", "</h5>");
                // function 'generateSectionHeading()' is defined in 'cite.inc.php'
                $recordData .= $sectionHeading;
            }
            // Print out the record:
            if (is_integer($rowCounter / 2)) {
                // if we currently are at an even number of rows
                $rowClass = "even";
            } else {
                $rowClass = "odd";
            }
            if (preg_match("/^(cli|inc)/i", $client) or $wrapResults == "0") {
                // we use absolute links for CLI clients, for include mechanisms, or when returning only a partial document structure
                $baseURL = $databaseBaseURL;
            } else {
                $baseURL = "";
            }
            $recordPermaLink = $databaseBaseURL . "show.php?record=" . $row["serial"];
            // generate a permanent link for the current record
            if (preg_match("/^Mobile\$/i", $viewType)) {
                $recordData .= "\n<div class=\"" . $rowClass . "\">" . "\n\t<div class=\"citation\">" . $record . "</div>";
            } else {
                $recordData .= "\n<tr class=\"" . $rowClass . "\">";
                // Print a column with a checkbox:
                // Note: we omit the results footer in print/mobile view ('viewType=Print' or 'viewType=Mobile'), for CLI clients, and when outputting only a partial document structure ('wrapResults=0')!
                if (!preg_match("/^Print\$/i", $viewType) and !preg_match("/^cli/i", $client) and $wrapResults != "0" and (!isset($displayResultsFooterDefault[$displayType]) or isset($displayResultsFooterDefault[$displayType]) and $displayResultsFooterDefault[$displayType] != "hidden")) {
                    $recordData .= "\n\t<td align=\"center\" valign=\"top\" width=\"10\">";
                    // - Print a checkbox form element:
                    if (!isset($displayResultsFooterDefault[$displayType]) or isset($displayResultsFooterDefault[$displayType]) and $displayResultsFooterDefault[$displayType] != "hidden") {
                        $recordData .= "\n\t\t<input type=\"checkbox\" onclick=\"updateAllRecs();\" name=\"marked[]\" value=\"" . $row["serial"] . "\" title=\"" . $loc["selectRecord"] . "\">";
                    }
                    if (!empty($row["orig_record"])) {
                        if (!isset($displayResultsFooterDefault[$displayType]) or isset($displayResultsFooterDefault[$displayType]) and $displayResultsFooterDefault[$displayType] != "hidden") {
                            $recordData .= "\n\t\t<br>";
                        }
                        if ($row["orig_record"] < 0) {
                            $recordData .= "\n\t\t<img src=\"" . $baseURL . "img/ok.gif\" alt=\"(" . $loc["original"] . ")\" title=\"" . $loc["originalRecord"] . "\" width=\"14\" height=\"16\" hspace=\"0\" border=\"0\">";
                        } else {
                            // $row["orig_record"] > 0
                            $recordData .= "\n\t\t<img src=\"" . $baseURL . "img/caution.gif\" alt=\"(" . $loc["duplicate"] . ")\" title=\"" . $loc["duplicateRecord"] . "\" width=\"5\" height=\"16\" hspace=\"0\" border=\"0\">";
                        }
                    }
                    // - Add <abbr> block which works as a microformat that allows applications to identify objects on web pages; see <http://unapi.info/specs/> for more info
                    $recordData .= "\n\t\t<div class=\"unapi\"><abbr class=\"unapi-id\" title=\"" . $recordPermaLink . "\"></abbr></div>";
                    $recordData .= "\n\t</td>";
                }
                // Print record data as a citation:
                $recordData .= "\n\t<td id=\"ref" . $row["serial"] . "\" class=\"citation\" valign=\"top\">" . "\n\t\t" . $record;
                // Display a triangle widget to show more info (keywords, abstract, etc) under each citation:
                if (!empty($additionalFieldsCitationView)) {
                    // Map MySQL field names to localized column names:
                    $fieldNamesArray = mapFieldNames();
                    // function 'mapFieldNames()' is defined in 'include.inc.php'
                    if ($useVisualEffects == "yes") {
                        $toggleVisibilityFunction = "toggleVisibilitySlide";
                    } else {
                        $toggleVisibilityFunction = "toggleVisibility";
                    }
                    $recordData .= "\n\t\t<div class=\"showhide\">" . "\n\t\t\t<a href=\"javascript:" . $toggleVisibilityFunction . "('moreinfo" . $row["serial"] . "','toggleimg" . $row["serial"] . "','toggletxt" . $row["serial"] . "','more%20info')\" title=\"" . $loc["LinkTitle_ToggleVisibility"] . "\">" . "<img id=\"toggleimg" . $row["serial"] . "\" class=\"toggleimg\" src=\"" . $baseURL . "img/closed.gif\" alt=\"" . $loc["LinkTitle_ToggleVisibility"] . "\" width=\"9\" height=\"9\" hspace=\"0\" border=\"0\">" . "</a>" . "\n\t\t</div>" . "\n\t\t<div id=\"moreinfo" . $row["serial"] . "\" class=\"moreinfo\" style=\"display: none;\">";
                    // Print additional fields:
                    foreach ($additionalFieldsCitationView as $field) {
                        if (isset($row[$field]) and !empty($row[$field])) {
                            $recordData .= "\n\t\t\t<div class=\"" . $field . "\"><strong>" . $fieldNamesArray[$field] . ":</strong> ";
                            // Make field items into clickable search links:
                            if (in_array($displayType, $showFieldItemLinks)) {
                                // Note: Function 'linkifyFieldItems()' will also call function 'encodeField()' to HTML
                                //       encode non-ASCII chars and to apply any field-specific search & replace actions
                                $recordData .= linkifyFieldItems($field, $row[$field], $userID, $fieldSpecificSearchReplaceActionsArray2, $encodingExceptionsArray, "/\\s*[;]+\\s*/", "; ", $showQuery, $showLinks, $showRows, $citeStyle, $citeOrder, $wrapResults, $displayType, $viewType);
                            } else {
                                // don't hotlink field items
                                $recordData .= encodeField($field, $row[$field], $fieldSpecificSearchReplaceActionsArray2, $encodingExceptionsArray);
                            }
                            // function 'encodeField()' is defined in 'include.inc.php'
                            $recordData .= "</div>";
                        }
                    }
                    // Print a row with links for the current record:
                    $recordData .= "\n\t\t\t<div class=\"reflinks\">";
                    // - Print the record's permanent URL:
                    if (preg_match("/^inc/i", $client)) {
                        // we open links in a new browser window if refbase data are included somewhere else:
                        $target = " target=\"_blank\"";
                    } else {
                        $target = "";
                    }
                    $recordData .= "\n\t\t\t\t<div class=\"permalink\"><a href=\"" . $recordPermaLink . "\"" . $target . " title=\"" . $loc["LinkTitle_Permalink"] . "\">";
                    if (preg_match("/^Print\$/i", $viewType)) {
                        // for print view, we use the URL as link title
                        $recordData .= $recordPermaLink;
                    } else {
                        $recordData .= $loc["PermalinkShort"];
                    }
                    $recordData .= "</a></div>";
                    // - Print additional links to cite/export the current record:
                    //   Note: we omit the additional links in print view ('viewType=Print')
                    if (!preg_match("/^Print\$/i", $viewType)) {
                        // -- Print cite links:
                        if (isset($_SESSION['user_permissions']) and preg_match("/allow_cite/", $_SESSION['user_permissions']) and isset($_SESSION['user_cite_formats'])) {
                            $userCiteFormatsArray = preg_split("/ *; */", $_SESSION['user_cite_formats'], -1, PREG_SPLIT_NO_EMPTY);
                            // get a list of the user's cite formats (the 'PREG_SPLIT_NO_EMPTY' flag causes only non-empty pieces to be returned)
                            $recordData .= "\n\t\t\t\t<div class=\"citelinks\">" . "&nbsp;|&nbsp;" . $loc["SaveCitation"] . ":";
                            foreach ($userCiteFormatsArray as $citeFormat) {
                                if (!preg_match("/^html\$/i", $citeFormat)) {
                                    // for now, we exclude the "HTML" cite format (as it's not any different to the regular Citation view HTML output)
                                    $recordData .= "\n\t\t\t\t\t&nbsp;<a href=\"" . $baseURL . generateURL("show.php", $citeFormat, array("record" => $row['serial']), true, "", "", $citeStyle, $citeOrder) . "\" title=\"" . $loc["LinkTitle_SaveCitationFormat_Prefix"] . $citeFormat . $loc["LinkTitle_SaveCitationFormat_Suffix"] . "\">" . $citeFormat . "</a>";
                                }
                            }
                            $recordData .= "\n\t\t\t\t</div>";
                        }
                        // -- Print export links:
                        if (isset($_SESSION['user_permissions']) and preg_match("/allow_export|allow_batch_export/", $_SESSION['user_permissions']) and isset($_SESSION['user_export_formats'])) {
                            $userExportFormatsArray = preg_split("/ *; */", $_SESSION['user_export_formats'], -1, PREG_SPLIT_NO_EMPTY);
                            // get a list of the user's export formats
                            $recordData .= "\n\t\t\t\t<div class=\"exportlinks\">" . "&nbsp;|&nbsp;" . $loc["ExportRecord"] . ":";
                            foreach ($userExportFormatsArray as $exportFormat) {
                                $recordData .= "\n\t\t\t\t\t&nbsp;<a href=\"" . $baseURL . generateURL("show.php", $exportFormat, array("record" => $row['serial'], "exportType" => "file"), true, "", "", $citeStyle) . "\" title=\"" . $loc["LinkTitle_ExportRecordFormat_Prefix"] . $exportFormat . $loc["LinkTitle_ExportRecordFormat_Suffix"] . "\">" . $exportFormat . "</a>";
                            }
                            $recordData .= "\n\t\t\t\t</div>";
                        }
                    }
                    $recordData .= "\n\t\t\t</div>" . "\n\t\t</div>";
                }
                $recordData .= "\n\t</td>";
            }
            // Display the regular links column:
            if ($showLinks == "1") {
                if (preg_match("/^Mobile\$/i", $viewType)) {
                    $recordData .= "\n\t<div class=\"links\">";
                } else {
                    $recordData .= "\n\t<td class=\"links\" valign=\"top\" width=\"42\">";
                }
                // Print out available links:
                // for Citation view, we'll use the '$showLinkTypesInCitationView' array that's defined in 'ini.inc.php'
                // to specify which links shall be displayed (if available and if 'showLinks == 1')
                // (for links of type DOI/URL/ISBN/XREF, only one link will be printed; order of preference: DOI, URL, ISBN, XREF)
                $recordData .= printLinks($showLinkTypesInCitationView, $row, $showQuery, $showLinks, $wrapResults, $userID, $viewType, $orderBy);
                // function 'printLinks()' is defined in 'search.php'
                if (preg_match("/^Mobile\$/i", $viewType)) {
                    $recordData .= "\n\t</div>";
                } else {
                    $recordData .= "\n\t</td>";
                }
            }
            if (preg_match("/^Mobile\$/i", $viewType)) {
                $recordData .= "\n</div>";
            } else {
                $recordData .= "\n</tr>";
            }
        }
    }
    // OUTPUT RESULTS:
    // Note: we omit the results header, browse links & query form for CLI clients, and when outputting only a partial document structure ('wrapResults=0')
    if (!preg_match("/^cli/i", $client) and $wrapResults != "0") {
        // Note: we also omit the results header in print/mobile view ('viewType=Print' or 'viewType=Mobile')
        if (!preg_match("/^(Print|Mobile)\$/i", $viewType) and (!isset($displayResultsHeaderDefault[$displayType]) or isset($displayResultsHeaderDefault[$displayType]) and $displayResultsHeaderDefault[$displayType] != "hidden")) {
            // Extract the first field from the 'WHERE' clause:
            if (preg_match("/ WHERE [ ()]*(\\w+)/i", $query)) {
                $selectedField = preg_replace("/.+ WHERE [ ()]*(\\w+).*/i", "\\1", $query);
            } else {
                $selectedField = "author";
            }
            // in the 'Search within Results" form, we'll select the 'author' field by default
            // Map MySQL field names to localized column names:
            $fieldNamesArray = mapFieldNames(true);
            $localizedDropDownFieldsArray = array();
            if (isset($_SESSION['loginEmail']) and !empty($defaultDropDownFieldsLogin)) {
                // if a user is logged in -AND- there were any additional fields specified...
                $dropDownFieldsArray = array_merge($defaultDropDownFieldsEveryone, $defaultDropDownFieldsLogin);
            } else {
                $dropDownFieldsArray = $defaultDropDownFieldsEveryone;
            }
            foreach ($dropDownFieldsArray as $field) {
                if (isset($fieldNamesArray[$field])) {
                    $localizedDropDownFieldsArray[$field] = $fieldNamesArray[$field];
                } else {
                    // no localized field name exists, so we use the original field name
                    $localizedDropDownFieldsArray[$field] = $field;
                }
            }
            // Get all citation styles for the current user:
            if (!isset($_SESSION['user_styles'])) {
                $citationStylesArray = array($defaultCiteStyle);
            } else {
                $citationStylesArray = array();
                $citationStylesTempArray = preg_split("/ *; */", $_SESSION['user_styles']);
                // get the user's list of citation styles
                foreach ($citationStylesTempArray as $citationStyle) {
                    $citationStylesArray[$citationStyle] = $citationStyle;
                }
            }
            // 2) Build forms containing options to show the user's groups, refine the search results or change the displayed columns:
            //    TODO for 2b+2c: should we allow users to choose via the web interface which columns are included in the popup menus?
            //    2a) Build a FORM with a popup containing the user's groups:
            $formElementsGroup = buildGroupSearchElements("search.php", $queryURL, $query, $showQuery, $showLinks, $showRows, $citeStyle, $citeOrder, $displayType);
            // function 'buildGroupSearchElements()' is defined in 'include.inc.php'
            //    2b) Build a FORM containing options to refine the search results:
            //        Call the 'buildRefineSearchElements()' function (defined in 'include.inc.php') which does the actual work:
            $formElementsRefine = buildRefineSearchElements("search.php", $queryURL, $showQuery, $showLinks, $showRows, $citeStyle, $citeOrder, $localizedDropDownFieldsArray, $selectedField, $displayType);
            //    2c) Build a FORM containing display options (change citation style & sort order, or change the number of records displayed per page):
            //        Call the 'buildDisplayOptionsElements()' function (defined in 'include.inc.php') which does the actual work:
            $formElementsDisplayOptions = buildDisplayOptionsElements("search.php", $queryURL, $showQuery, $showLinks, $rowOffset, $showRows, $citeStyle, $citeOrder, $citationStylesArray, $citeStyle, 2, $displayType, $headerMsg);
            $htmlData .= displayResultsHeader("search.php", $formElementsGroup, $formElementsRefine, $formElementsDisplayOptions, $displayType);
            // function 'displayResultsHeader()' is defined in 'results_header.inc.php'
            //    and insert a divider line (which separates the results header from the browse links & results data below):
            $htmlData .= "\n<hr class=\"resultsheader\" align=\"center\" width=\"93%\">";
        }
        // Build a TABLE with links for "previous" & "next" browsing, as well as links to intermediate pages
        // call the 'buildBrowseLinks()' function (defined in 'include.inc.php'):
        $BrowseLinks = buildBrowseLinks("search.php", $query, $NoColumns, $rowsFound, $showQuery, $showLinks, $showRows, $rowOffset, $previousOffset, $nextOffset, $wrapResults, $maximumBrowseLinks, "sqlSearch", "Cite", $citeStyle, $citeOrder, $orderBy, $headerMsg, $viewType);
        $htmlData .= $BrowseLinks;
        if (preg_match("/^Mobile\$/i", $viewType)) {
            // Extract the original OpenSearch/CQL query that was saved by 'opensearch.php' as a session variable:
            if (isset($_SESSION['cqlQuery'])) {
                $cqlQuery = $_SESSION['cqlQuery'];
            } else {
                $cqlQuery = "";
            }
            // Include an OpenSearch-style (CQL) query form:
            $htmlData .= "\n<div id=\"queryform\">" . "\n\t<form action=\"opensearch.php\" method=\"GET\" name=\"openSearch\">" . "\n\t\t<input type=\"hidden\" name=\"formType\" value=\"openSearch\">" . "\n\t\t<input type=\"hidden\" name=\"submit\" value=\"" . $loc["ButtonTitle_Search"] . "\">" . "\n\t\t<input type=\"hidden\" name=\"viewType\" value=\"" . $viewType . "\">" . "\n\t\t<input type=\"hidden\" name=\"startRecord\" value=\"1\">" . "\n\t\t<input type=\"hidden\" name=\"maximumRecords\" value=\"" . $showRows . "\">" . "\n\t\t<input type=\"hidden\" name=\"recordSchema\" value=\"html\">" . "\n\t\t<input type=\"text\" name=\"query\" value=\"" . $cqlQuery . "\" size=\"25\" title=\"" . $loc["DescriptionEnterSearchString"] . "\">" . "\n\t\t<input type=\"submit\" name=\"submit\" value=\"" . $loc["ButtonTitle_Search"] . "\" title=\"" . $loc["DescriptionSearchDB"] . "\">" . "\n\t</form>" . "\n</div>";
        } elseif (!preg_match("/^Print\$/i", $viewType) and (!isset($displayResultsFooterDefault[$displayType]) or isset($displayResultsFooterDefault[$displayType]) and $displayResultsFooterDefault[$displayType] != "hidden")) {
            // Include the 'queryResults' form:
            $htmlData .= "\n<form action=\"search.php\" method=\"GET\" name=\"queryResults\">" . "\n<input type=\"hidden\" name=\"formType\" value=\"queryResults\">" . "\n<input type=\"hidden\" name=\"submit\" value=\"Cite\">" . "\n<input type=\"hidden\" name=\"originalDisplayType\" value=\"" . $displayType . "\">" . "\n<input type=\"hidden\" name=\"orderBy\" value=\"" . rawurlencode($orderBy) . "\">" . "\n<input type=\"hidden\" name=\"showQuery\" value=\"" . $showQuery . "\">" . "\n<input type=\"hidden\" name=\"showLinks\" value=\"" . $showLinks . "\">" . "\n<input type=\"hidden\" name=\"showRows\" value=\"" . $showRows . "\">" . "\n<input type=\"hidden\" name=\"rowOffset\" value=\"" . $rowOffset . "\">" . "\n<input type=\"hidden\" name=\"sqlQuery\" value=\"" . $queryURL . "\">";
            // embed the current sqlQuery so that it can be re-applied after the user pressed either of the 'Add' or 'Remove' buttons within the 'queryResults' form
        }
    }
    // Output query results:
    if (preg_match("/^Mobile\$/i", $viewType)) {
        $htmlData .= "\n<div id=\"citations\" class=\"results\">" . $recordData . "\n</div>";
    } else {
        $htmlData .= "\n<table id=\"citations\" class=\"results\" align=\"center\" width=\"100%\" summary=\"This table holds the database results for your query\">" . $recordData . "\n</table>";
    }
    // Append the footer:
    // Note: we omit the results footer & browse links in print/mobile view ('viewType=Print' or 'viewType=Mobile'), for CLI clients, and when outputting only a partial document structure ('wrapResults=0')!
    if (!preg_match("/^(Print|Mobile)\$/i", $viewType) and !preg_match("/^cli/i", $client) and $wrapResults != "0") {
        // Again, insert the (already constructed) BROWSE LINKS
        // (i.e., a TABLE with links for "previous" & "next" browsing, as well as links to intermediate pages)
        $htmlData .= $BrowseLinks;
        // Build a results footer with form elements to cite, group or export all/selected records:
        if (!isset($displayResultsFooterDefault[$displayType]) or isset($displayResultsFooterDefault[$displayType]) and $displayResultsFooterDefault[$displayType] != "hidden") {
            if (isset($_SESSION['user_permissions']) and (isset($_SESSION['loginEmail']) and preg_match("/allow_cite|allow_user_groups|allow_export|allow_batch_export/", $_SESSION['user_permissions']) or !isset($_SESSION['loginEmail']) and preg_match("/allow_cite/", $_SESSION['user_permissions']))) {
                // if the 'user_permissions' session variable does contain any of the following: 'allow_cite' -AND- if logged in, aditionally: 'allow_user_groups', 'allow_export', 'allow_batch_export'...
                // ...Insert a divider line (which separates the results data from the forms in the footer):
                $htmlData .= "\n<hr class=\"resultsfooter\" align=\"center\">";
            }
            // Call the 'buildResultsFooter()' function (which does the actual work):
            $htmlData .= buildResultsFooter($showRows, $citeStyle, $citeOrder, $displayType, $headerMsg);
        }
    }
    if (!preg_match("/^(Print|Mobile)\$/i", $viewType) and !preg_match("/^cli/i", $client) and $wrapResults != "0" and (!isset($displayResultsFooterDefault[$displayType]) or isset($displayResultsFooterDefault[$displayType]) and $displayResultsFooterDefault[$displayType] != "hidden")) {
        // Finish the form:
        $htmlData .= "\n</form>";
    }
    return $htmlData;
}