first init
authorSteve Sutton <steve@gaslightmedia.com>
Thu, 20 Dec 2018 14:24:33 +0000 (09:24 -0500)
committerSteve Sutton <steve@gaslightmedia.com>
Thu, 20 Dec 2018 14:24:33 +0000 (09:24 -0500)
15 files changed:
XML_Sitemap.php [new file with mode: 0644]
docs/GLMSearch.php [new file with mode: 0644]
docs/Install.txt [new file with mode: 0644]
docs/SitesUsing.txt [new file with mode: 0644]
docs/XML_Sitemap.php [new file with mode: 0644]
docs/remoteSearch.inc [new file with mode: 0644]
glmSearch.inc [new file with mode: 0644]
recrawl.php [new file with mode: 0644]
remoteSearchSupport.php [new file with mode: 0644]
templates/Sitemap_XML_0.9.html [new file with mode: 0644]
templates/default.html [new file with mode: 0644]
test/XML_Sitemap_Test.php [new file with mode: 0644]
test/crawlUrlTest.php [new file with mode: 0644]
test/remoteTest.php [new file with mode: 0644]
test/test.php [new file with mode: 0644]

diff --git a/XML_Sitemap.php b/XML_Sitemap.php
new file mode 100644 (file)
index 0000000..65ef654
--- /dev/null
@@ -0,0 +1,31 @@
+<?PHP
+/**
+ * PHP Executable to create an XML Sitemap for search engines
+ *
+ * Copy this file to the root of a Web site, edit the parameters
+ * $site, and if needed $login and $key, then kick off with a
+ * Cron job periodically using the following syntax
+ *
+ * php /var/www/server/{site}/XML_Sitemap.php > /dev/null 2>&1
+ */
+
+define('BASE_PATH', '/var/www/server/CommonApps/GLMSearch/V1.1/');
+define('BASE_URL', ''); // Not needed
+
+$index = 'Index_1';
+$site = '{site URL goes here}';
+$login = 'WebsiteServices';
+$key = '829800701e8440b67a78e3afbefa1049';
+
+define('XML_SITEMAP_FILE', '/var/www/server/'.$site.'/sitemap.xml');
+
+require(BASE_PATH.'glmSearch.inc');
+$glmSearch = new glmSearch($site, $login, $key, false, $index);
+
+$sitemap = $glmSearch->xmlSitemap('Sitemap_XML_0.9.html');
+
+file_put_contents(XML_SITEMAP_FILE, $sitemap);
+
+exit;
+
+?>
diff --git a/docs/GLMSearch.php b/docs/GLMSearch.php
new file mode 100644 (file)
index 0000000..400f445
--- /dev/null
@@ -0,0 +1,45 @@
+<?php
+/**
+ * GLMSearch.php
+ *
+ * PHP version 5
+ *
+ * @category  Toolkit
+ * @package   Template/Page
+ * @author    Chuck Scott <cscott@gaslightmedia.com>
+ * @copyright 2013 Gaslight Media
+ * @license   Gaslight Media
+ * @version   CVS: $Id: GLMSearch.php,v 1.5 2010/05/25 14:07:22 cscott Exp $
+ * @link      <>
+ */
+
+/**
+ * Toolkit_Template_Page_GLMSearch
+ *
+ * Description of Toolkit_Template_Page_GLMSearch
+ *
+ * @category  Toolkit
+ * @package   Template/Page
+ * @author    Chuck Scott <cscott@gaslightmedia.com>
+ * @copyright 2013 Gaslight Media
+ * @license   Gaslight Media
+ * @release   Release: $id$
+ * @link      <>
+ */
+class Toolkit_Template_Page_GLMSearch
+{
+        /**
+        * Description for getContent()
+        *
+        * @return string
+        * @access public
+        */
+        public function getContent()
+        {
+            require('/var/www/server/CommonApps/GLMSearch/V1.1/glmSearch.inc');
+            $glmSearch = new glmSearch(GLM_SEARCH_SITE, GLM_SEARCH_LOGIN, GLM_SEARCH_KEY, false, GLM_SEARCH_INDEX, true, GLM_SEARCH_FILTER_TYPE, GLM_SEARCH_FILTER_VALUE);
+            $page = $glmSearch->doSearch();
+            return $page;
+        }
+}
+?>
diff --git a/docs/Install.txt b/docs/Install.txt
new file mode 100644 (file)
index 0000000..cea9995
--- /dev/null
@@ -0,0 +1,300 @@
+Installation Information
+------------------------
+
+Search Engine Access for Websites
+
+    Search Engine URL:      http://dev53.gaslightmedia.com:9090
+    login:                  WebsiteServices
+    key:                    3cd270eda427d55874aafa45919f7026
+
+    Search Engine URL:      http://stats.gaslightmedia.com:9090
+    login:                  WebsiteServices
+    key:                    829800701e8440b67a78e3afbefa1049
+    
+Admin User Access    
+    
+    User            Initial Password    Admin   Monitor
+    --------------- ------------------- ------- -------
+    cscott                              X       X
+    dave                                X       X
+    steve           ossSteve            X       X
+
+    WebsiteServices (username for indexing and Web searches)
+    
+
+
+    
+Search Engine Prep for a New Website
+------------------------------------
+
+* Log into search engine admin interface.
+    
+* Add Website to OpenSearchServer - Currently the following but should change.
+
+   http://stats.gaslightmedia.com:9090
+
+* Select "Indices" or "Index" tab at top (depends on if one is selected).
+
+* Enter Website host name (i.e. "demo.gaslightmedia.com") in "Index name:" field.
+
+* Select "web crawler" in "Template:" field.
+
+* Click "Create" - That index should be selected (show in "Index:" tab). If not
+  select the index line below.
+  
+* Click on "Crawler" tab at top then "Crawl process" tab below.
+
+* Change "Fetch interval between re-fetches:" to 1 day. This will ensure that all
+  pages will be re-indexed each time the site is crawled.
+  
+* Change "Maximum number of URLs per host:" to 10000. This will make sure that all
+  pages in the site will be crawled in each session.
+  
+* Note that "Number of simultaneous threads:" is irrelevant because the engine will
+  only assign one thread per indexed host.
+  
+* Make sure that "Delay between each successive access, in seconds:" is 10. Setting
+  this too short will cause unnecessary loading. At 10 seconds the engine will index
+  360 pages per hour for the selected index. 
+
+* If site requires authentication for access, do the following
+
+    * Select "Authentication" tab
+    * Enter a "URL Pattern:". To apply to entire site, use something like the following.
+        http://demo.gaslightmedia.com/*
+    * Select "Basic or Digest" for "Type:"
+    * Enter Username and Password    
+    * Click the "Create" button
+    
+* Set crawl url pattern
+
+    * Click on the "Pattern list" tab (using "Crawler" main tab)
+    * Enter a pattern. To apply to entire site, use something like the following.
+        http://demo.gaslightmedia.com/*
+    * Click the "Add" button.
+
+* Click on "Privileges" tab at top
+
+* Select "WebsiteServices" in the "List of existing users"
+
+* In the "Add privileges on following index:" picklist, select the new Website index.
+
+* Select "Index: query the index" and click the "Add" button.
+
+* Select "Web crawler: start and stop" and click the "Add" button.
+
+* Click the "Save" button below the Index list.
+    
+* Start crawler for the first time.
+
+    * Click on the "Crawler" tab at the top then click the "Crawl process" tab below.
+    * Under "Current status" select "RunOnce" from the picklist.
+    * Click the "Not running - Click to run" button once. 
+        NOTE: Button will change back to "Not running..." when done.
+        Check that process ran and that it indexed a rational number of pages.
+        This process may need to be run a few times before it indexes all of
+        the pages and "New url" shows 0 in the stats. (Need to look into this.)
+        If it only indexed 1 page, try again. If it still does only 1 page
+        check the "Pattern list" to make sure the URL pattern ends in "/*".
+    * Stats for the current crawl session will display at the bottom.
+    
+    (NOTE: Crawler will continue even if you leave this screen.)
+    
+* Select the "Scheduler" tab at the top.
+
+* Click "Create new scheduler job" button.
+
+* Set "Job name:" to be the same as the Website host name. (i.e. demo.gaslightmedia.com)
+
+* Click "Active:" to enable this scheduler job.
+
+* Set date/time to run. *** Need to sort out what we want here *** For now use
+  the settings below for 2:30 AM each Mon and Thur. We may need to space these out at some point.
+
+    Use:    0       30      2       ?       *       mon,thu     *
+    
+* Select "Web crawler - start" in the "Task" picklist (near bottom of list).
+
+* Make sure "Run once" is set to "true".
+
+* Click the "+" button under "action" to the right. 
+
+* Click the "Create" button at the bottom.
+
+
+
+
+Installation on servers that can't support CommonApps (WS1)
+-----------------------------------------------------------
+
+* Copy remoteSearch.inc from docs directory to root of site and
+  edit "Setup Parameters" near top of file.
+
+    $glmsThisSite       Hostname of Website. This should be what's set as the
+                        "index" name in the OpenSearchServer.  
+                        
+    $glmsUrl            URL to the remote search support code in the GLMSearch
+                        common app on a server that has that installed.
+                        
+    $glmPageUrl         URL that should be used for links in the search results
+                        page. This will normally be the site index page.
+    
+* Add test for search request where toolbox content goes 
+
+    if ($_REQUEST['GLMSearch'] == 'true') {
+            require_once('remoteSearch.inc');
+            echo $glmsResults;
+    }
+    elseif(.....rest of toolbox output...
+
+* Add search form to site.
+
+    <form action="{URL back to site index}" name="search" method="post">
+        <input type="hidden" name="GLMSearch" value="true">
+        <input type="hidden" name="start" value="0">
+        <input type="hidden" name="rows" value="10">
+        <input type="text" name="query" value="">
+        <input type="checkbox" name="matchAll"> Match all words
+        <input type="submit" id="submit" value="Search">
+    </form>
+
+* Note at this time that there is no remote support for re-indexing specific pages.
+
+
+Installation on servers that support CommonApps
+-----------------------------------------------
+
+* Make sure both GLMSearch and Smarty are installed in the CommonApps directory
+
+* NOTE: This requires that both BASE_PATH and BASE_URL are set.
+
+* NOTE: All new sites based on current Demo from repository should have the rest of this done already.
+
+* Add to config/application.ini - might replace Google search application. 
+  (we'll turn this on later)
+
+    ; Turn on Gaslight Media Search application On or Off
+    glmsearch.application = Off
+    glmsearch.site = "demo.gaslightmedia.com"
+    glmsearch.login = "WebsiteServices"
+    glmsearch.key = "829800701e8440b67a78e3afbefa1049"
+    
+* Edit "glmsearch.site" parameter above to be the hostname of the site being setup.    
+  Note: login and key should be the same for all sites until further notice.
+
+* Add the following to /setup.phtml (near Google search or might be replacing Google search)
+
+    /**
+     * Site has CommonApps GLMSearch application?
+     */
+    define('GLM_SEARCH', $applicationConfig->glmsearch->application);
+    define('GLM_SEARCH_SITE', $applicationConfig->glmsearch->site);
+    define('GLM_SEARCH_LOGIN', $applicationConfig->glmsearch->login);
+    define('GLM_SEARCH_KEY', $applicationConfig->glmsearch->key);
+    
+* Add the following to /Toolkit/Page.php under fetchPage() method
+  Place below similar code for GOOGLE_SEARCH.
+
+    // check if define for GLM_SEARCH is set
+    if (defined("GLM_SEARCH")
+        && GLM_SEARCH
+    ) {
+        $this->glmSearch = GLM_SEARCH;
+        $this->glmSearchSite = GLM_SEARCH_SITE;
+        $this->glmSearchLogin = GLM_SEARCH_LOGIN;
+        $this->glmSearchKey = GLM_SEARCH_KEY;
+        
+        // Check if GLMSearch page called
+        if ($_REQUEST['GLMSearch'] == 'true') {
+            $this->isHomePage = false;
+        }
+    }
+
+* Add search form to templates/template.html somewhere appropriate. 
+  May replace google search form. May be multiple instances for 
+  responsive sites.
+
+    <section flexy:if="glmSearch">
+        <form action="{homePageUrl:h}" name="search" method="post" flexy:ignore="yes">
+            <input type="hidden" name="GLMSearch" value="true">
+            <input type="hidden" name="start" value="0">
+            <input type="hidden" name="rows" value="10">
+            <input type="text" name="query" value="" size="12">
+            <!-- <input type="checkbox" name="matchAll"> Match all words -->
+            <input type="submit" value="Search Site">
+        </form>
+    </section><!-- /#glmsearch -->
+
+    Notes:
+        Form "action" should be the site index page.
+        The "matchAll" parameter is optional.
+        Adjust "size" for "query" as needed or replace with style.
+        Style form accordingly.
+        
+* Add these code pieces to /Toolkit/Template/Page/BodyFactory.php 
+  
+  Near top of getPageBodyBuilder() place...
+
+        $glmSearch = (defined('GLM_SEARCH')
+            && GLM_SEARCH
+            && isset($_REQUEST['GLMSearch'])
+            && $_REQUEST['GLMSearch'] == 'true');
+
+  In if/else chain below that place...
+  
+        } elseif ($glmSearch) {
+            return new Toolkit_Template_Page_GLMSearch();
+                
+* Copy docs/GLMSearch.php file to /Toolkit/Template/Page/GLMSearch.php
+
+* Update toHtml() method at bottom of Toolkit/Template/BreadCrumbs.php to the following
+  to stop indexing of bread-crumb nav in pages.
+
+        return !empty($breadCrumbsArray)
+            ? '<div id="breadcrumbs" class="opensearchserver.ignore">' . $breadCrumbs . '</div>'
+            : '';
+
+
+* *** NEED TO ADD INFO ON RE-INDEXING SPECIFIC PAGES WHEN UPDATED IN THE TOOLBOX. ***
+  Will do this when Steve has sorted this out. 
+
+
+OpenSearchServer Controls
+-------------------------
+
+* To tell engine to ignore certain parts of a Web site enclose that section in
+  the following. Use this to tell the engine to ignore things like page headers
+  navigation and such that always show up on all pages. Can also just add the
+  "opensearchserver.ignore" class to existing divs. (not tested)
+
+    <div class="opensearchserver.ignore"> ... </div><!-- opensearchserver.ignore -->   
+    
+    
+Other Notes
+----------------------
+    
+    To produce debug output from the GLMSearch class, set the
+    class parameter "debug" to true before calling 
+    $GLMSearch->render().
+    
+    $GLMSearch->debug
+    
+    To see all parameters sent to the Smarty template, enable
+    the Smarty console by setting the class parameter "smartyConsole"
+    to true before calling render() or search().
+    
+    $GLMSearch->smartyConsole = true;
+    
+    Note that parameters delivered to Smarty are not escaped 
+    or encoded--they are un-altered. To use them in a URL, 
+    use the following Smarty syntax.
+    
+    {$param|escape:'url'}
+    
+    To override the default template (to use a template local
+    to the site), call render() or doSearch() with the following 
+    parameters.
+    
+    $GLMSearch->render($templateName, $templateBasePath)
+    $GLMSearch->doSearch($templateName, $templateBasePath)
+    
\ No newline at end of file
diff --git a/docs/SitesUsing.txt b/docs/SitesUsing.txt
new file mode 100644 (file)
index 0000000..0cd9bce
--- /dev/null
@@ -0,0 +1,65 @@
+GLMSearch Common App Deployment Status
+
+Server      Status          Version     Smarty          Notes
+----------- --------------- ----------- --------------- ---------------------------
+DEV53       Deployed        V1,V1.1     3.1
+DEV52       Deployed        V1,V1.1     3.1             Not Tested
+WS0         Not Deployable
+WS1         Not Deployable
+WS3         Deployed        V1,V1.1     3.1             Tested with Demo
+WS4         Deployed        V1,V1.1     3.1             Not Tested
+WS6         Deployed        V1          3.1             GLM OpenSearchServer - Remote search server
+
+Application     Location                                    Versions available
+--------------- ------------------------------------------- ----------------------
+GLMSearch       /var/www/server/CommonApps/GLMSearch        V1, V1.1
+Smarty          /var/www/server/CommonApps/Smarty           3.1
+
+
+Sites Using GLMSearch
+
+Site                                Server  Status      Version     Method*     Remote Server   Search Server       Notes
+----------------------------------- ------- ----------- ----------- ----------- --------------- ------------------- ---------------
+www.alpenacvb.com                   WS0     Deployed    V1.1        Integrated                  stats.gas...
+www.cadillacmichigan.com            WS6     Deployed    V1.1        Integrated                  stats.gas...
+www.circlemichigan.com              WS0     Deployed    V1.1        Integrated                  stats.gas...
+www.cityofboynecity.com             WS0     Deployed    V1.1        Integrated                  stats.gas...
+www.cityofwoodward.com              WS3     Deployed    V1.1        Integrated                  stats.gas...
+www.dclinc.com                      WS3     Deployed    V1.1        Remote      www6            stats.gas...
+www.dioceseofgaylord.org            WS6     Deployed    V1.1        Integrated                  stats.gas...   
+www.discoverkalamazoo.com           WS6     Deployed    V1.1        Integrated                  stats.gas...
+www.explorewesternup.com            WS0     Deployed    V1.1        Integrated                  stats.gas...
+www.gaylordchamber.com              WS3     Deployed    V1.1        Remote      www6            stats.gas...        
+www.gaylordgolfmecca.com            WS3     Deployed    V1.1        Remote      www6            stats.gas...    
+www.gaylordmichigan.net             WS6     Deployed    V1.1        Integrated                  stats.gas...
+www.gaylordschools.com              WS0     Deployed    V1.1        Remote      www6            stats.gas...
+www.harborcountry.org               WS0     Deployed    V1.1        Integrated                  stats.gas...
+www.ironmountain.org                WS0     Deployed    V1.1        Integrated                  stats.gas...
+www.mackinawcity.com                WS6     Deployed    V1.1        Integrated                  stats.gas...
+www.michiganmaritimemuseum.org      WS0     Deployed    V1.1        Remote      www6            stats.gas...
+www.migcsa.org                      WS3     Deployed    V1.1        Remote      www6            stats.gas...
+www.miseniorcenters.org             WS0     Deployed    V1.1        Integrated                  stats.gas...
+www.mountpleasantwow.com            WS6     Deployed    V1.1        Integrated                  stats.gas...
+www.n8dnx.org                       WS1     Deployed    V1.1        Remote      www6            stats.gas...
+www.petoskeyarea.com                WS6     Deployed    V1.1        Integrated                  stats.gas...
+www.phsacf.org                      WS6     Deployed    V1.1        Remote      www6            stats.gas...
+www.saultedc.com                    WS0     Deployed    V1.1        Integrated                  stats.gas...
+www.saultstemarie.com               WS6     Deployed    V1.1        Integrated                  stats.gas...
+www.shipwreckmuseum.com             WS3     Deployed    V1.1        Remote      www6            stats.gas...
+www.staffords.com                   WS6     Deployed    V1.1        Integrated                  stats.gas...
+www.thinkdunes.com                  WS3     Deployed    V1.1        Integrated                  stats.gas...
+www.traversecity.com                WS4     Deployed    V1.1        Integrated                  stats.gas...
+www.visitbenzie.com                 WS3     Deployed    V1.1        Integrated                  stats.gas...
+www.visitescanaba.com               WS6     Deployed    V1.1        Integrated                  stats.gas...
+www.warmemorialhospital.org         WS6     Deployed    V1.1        Integrated                  stats.gas...
+www.wmta.org                        WS3     Deployed    V1.1        Integrated                  stats.gas...
+www.wojan.com                       WS3     Deployed    V1.1        Integrated                  stats.gas...
+
+demo.gaslightmedia.com              WS3     Deployed    V1          Integrated                  2:30 AM Mon,Thu
+
+
+*   "Integrated" uses direct reference to glmSearch class. 
+    "Remote" uses remote access to GLMSearch on another server.
+
+
+Web Site
\ No newline at end of file
diff --git a/docs/XML_Sitemap.php b/docs/XML_Sitemap.php
new file mode 100644 (file)
index 0000000..70a594c
--- /dev/null
@@ -0,0 +1,24 @@
+<?PHP
+/**
+ * PHP Executable to create an XML Sitemap for search engines
+ */
+
+define('BASE_PATH', '/var/www/server/CommonApps/GLMSearch/V1.1/');
+define('BASE_URL', ''); // Not needed
+
+$site = 'www.n8dnx.org';
+$login = 'WebsiteServices';
+$key = '829800701e8440b67a78e3afbefa1049';
+
+define('XML_SITEMAP_FILE', '/var/www/server/'.$site.'/sitemap.xml');
+
+require(BASE_PATH.'glmSearch.inc');
+$glmSearch = new glmSearch($site, $login, $key);
+
+$sitemap = $glmSearch->xmlSitemap('Sitemap_XML_0.9.html');
+
+file_put_contents(XML_SITEMAP_FILE, $sitemap);
+
+exit;
+
+?>
\ No newline at end of file
diff --git a/docs/remoteSearch.inc b/docs/remoteSearch.inc
new file mode 100644 (file)
index 0000000..9493163
--- /dev/null
@@ -0,0 +1,56 @@
+<?
+/**
+ * Remote Search Query
+ *
+ * Use this when the Web site is not on a server that
+ * includes the GLMSearch class or that can't run it.
+ *
+ * Include this if search request is being processed
+ * (if "GLMSearch" post parameter exists and is set
+ * to 'true').
+ */
+
+/*
+ * Setup Parameters - MUST CONFIGURE THESE PER Website
+ */
+
+// Site we're going to search - Must be setup as an Index in the GLM OpenSearchServer
+$glmsThisSite = 'http://www.n8dnx.org';
+
+// URL to the remote search support code on a server that supports GLMSearch class
+$glmsUrl = 'http://www6.gaslightmedia.com/GLMSearch/V1.1/remoteSearchSupport.php';
+
+// URL that should be used for links in the search results page - Normally site index page.
+$glmsPageUrl = 'http://www.website.com/index.php';
+
+/*
+ *  End of setup parameters
+ */
+
+$glmsStart = ($_REQUEST['start'] - 0);
+$glmsRows = ($_REQUEST['rows'] - 0);
+
+$glmsRequest = array(
+    'index'        => 'Index_1',
+       'website'      => $glmsThisSite,
+    'query'        => $_REQUEST['query'],
+    'returnUrl'    => $glmsPageUrl,
+    'start'        => $glmsStart,
+    'rows'         => $glmsRows,
+    'matchAll'     => $_REQUEST['matchAll']
+);
+
+// Create curl instance - and set to return response
+$glmsCurl = curl_init();
+curl_setopt($glmsCurl, CURLOPT_RETURNTRANSFER, TRUE);
+curl_setopt($glmsCurl, CURLOPT_URL, $glmsUrl);
+curl_setopt($glmsCurl, CURLOPT_POST, true);
+curl_setopt($glmsCurl, CURLOPT_POSTFIELDS, $glmsRequest);
+
+try {
+    $glmsResults = curl_exec($glmsCurl);
+} catch (Exception $e) {
+    $glmsResults = "GLMSearch Error: Curl failure.";
+}
+
+?>
\ No newline at end of file
diff --git a/glmSearch.inc b/glmSearch.inc
new file mode 100644 (file)
index 0000000..daaba6e
--- /dev/null
@@ -0,0 +1,966 @@
+<?php
+/**
+ * GLM Search Engine - Support Classes
+ *
+ * PHP version 5
+ *
+ * @category Support_Services
+ * @package  GLMSearch
+ * @author   Chuck Scott <cscott@gaslightmedia.com>
+ * @license  http://www.gaslightmedia.com Gaslightmedia
+ * @release  SVN: $Id: glmSearch.inc,v 1.0 2011/01/25 19:31:47 cscott Exp $
+ * @link
+ */
+
+/*
+ *  Debug and Smarty console controls
+ *
+ *  These are the default values for all sites using this class. To
+ *  override these for a specific site, set the following class
+ *  parameters to true;
+ *
+ *  $GLMSearch->debug = true;
+ *  $GLMSearch->smartyConsole = true;
+ *
+ *  Setting smartyConsole to true will display the Smarty Console
+ *  and all parameters provided to the template.
+ */
+define('GLMSearch_DEBUG', false);
+define('GLMSearch_SMARTY_CONSOLE', false);
+
+/*
+ * Set OpenSearchServer base URL and port
+ */
+define('OpenSearchServer', 'http://stats.gaslightmedia.com:9090');
+//define('OpenSearchServer', 'http://oss.gaslightmedia.com:9090');
+
+/*
+ * Default template that comes with GLMSearch, may be overridden with
+ * render() or doSearch() call.
+ */
+define('GLMSearch_TEMPLATE', 'default.html');
+define('GLMSearch_TEMPLATE_PATH', '/var/www/server/CommonApps/GLMSearch/V1.1/templates');
+
+/*
+ * Bring in Smarty to parse the template
+ */
+require('/var/www/server/CommonApps/Smarty/3.1/Smarty.class.php');
+
+/**
+ * GLM Search - Web Site Search Support Class
+ *
+ * PHP version 5
+ *
+ * @category Support_Services
+ * @package  EventManagement
+ * @author   Chuck Scott <cscott@gaslightmedia.com>
+ * @license  http://www.gaslightmedia.com Gaslightmedia
+ * @release  SVN: $Id: GeoCalculations.php,v 1.0 2011/01/25 19:31:47 cscott Exp $
+ * @link     http://housing.gaslightmedia.com/admin/
+ */
+class GLMSearch
+{
+
+    /**
+     * Name of the index an instance of this class will search.
+     * An index can have multiple Websites in it. If when calling
+     * the constructor no $index is specified, the code will assume
+     * that the index name and website name are the same. Otherwise
+     * it will use $index as the index name.
+     *
+     * @var    $index
+     * @access private
+     */
+    private $index;
+    /**
+     * Name of the Web site an instance of this class will work on
+     *
+     * @var    $website
+     * @access private
+     */
+    private $website;
+    /**
+     * Authentication paramters for all requests
+     *
+     * @var    $auth
+     * @access private
+     */
+    private $auth;
+    /**
+     * General error message describing any failure
+     *
+     * @var    $curlError
+     * @access public
+     */
+    public $errorMessage;
+    /**
+     * Exception object caused by curl or other failure
+     *
+     * @var    $error
+     * @access public
+     */
+    public $error;
+    /**
+     * Request array
+     *
+     * This should be the most common request configuration
+     * we'll be using for our Web sites. It's public so it
+     * can be easily customized for a particular Web site
+     * once the class has been instantiated.
+     *
+     * See clearResults() method for default data
+     *
+     * @var    $request Array of request information
+     * @access public
+     */
+    public $request = false;
+    /**
+     * Search type
+     *
+     * This selects whether a search will be a 'field' search or 'pattern' search
+     *
+     * @var    $type    String Either 'field' or 'pattern'
+     * @access private
+     */
+    private $type = 'field';
+    /**
+     * Curl instance
+     *
+     * @var    $curl
+     * @access private
+     */
+    private $curl = false;
+     /**
+     * HTTP Status from curl
+     *
+     * @var    $httpStatus
+     * @access public
+     */
+    public $httpStatus = false;
+    /**
+     * HTTP Header from curl
+     *
+     * @var    $httpHeader
+     * @access public
+     */
+    public $httpHeader = false;
+     /**
+     * Raw Result of curl request
+     *
+     * Public so it can easily be examined
+     *
+     * @var    $rawResult
+     * @access public
+     */
+    public $rawResults = false;
+    /**
+     * Full results as an array
+     *
+     * @var    $resultArray
+     * @access private
+     */
+    private $resultArray = false;
+    /**
+     * Compressed results array
+     *
+     * This array has better processed data for output
+     * and has trimmed levels for document data for
+     * easier use.
+     *
+     * @var    $result
+     * @access private
+     */
+    private $result = false;
+    /**
+     * Host Filter flag
+     *
+     * @var    $filter
+     * @access public
+     */
+    public $filter;
+    /**
+     * Host Filter Type
+     *
+     * @var    $filterType
+     * @access public
+     */
+    public $filterType = false;
+    /**
+     * Host Filter Value
+     *
+     * @var    $filterValue
+     * @access public
+     */
+    public $filterValue = false;
+    /**
+     * Debug flag
+     *
+     * @var    $debug
+     * @access public
+     */
+    public $debug;
+    /**
+     * Smarty Console Flag
+     *
+     * @var    $smartyConsole
+     * @access public
+     */
+    public $smartyConsole;
+
+    /**
+     * Constructor
+     *
+     * @param string $website   Name of the Web site
+     * @param string $login     Login to OpenSearchServer
+     * @param string $key       Key for login
+     * @param bool $debug       True to set debug on
+     * @param text $index       Optional index name if Web site is part of a larger index
+     * @param bool $filter      Optionally disable host filter using supplied $website (false = disable)
+     * @param text $filterType  Optional filter type (when $filter is true).
+     *                          Filter types are "title", "titleExact", "titlePhonetic", "content",
+     *                          "contentExact", "contactPhonetic", "urlSplit", "urlExact", "urlPhonetic",
+     *                          "full", "fullExact", "fullPhonetic"
+     * @param text $filterValue Filter value to use with $filterType.
+     *
+     * @return void
+     * @access public
+     */
+    public function __construct($website, $login, $key, $debug = false, $index = false, $filter = true, $filterType = "host", $filterValue = '')
+    {
+
+        // Set debug and Smarty console status. Can be overridden once instance is created.
+        $this->debug = GLMSearch_DEBUG;
+        if ($debug) {
+            $this->debug = true;
+        }
+        $this->smartyConsole = GLMSearch_SMARTY_CONSOLE;
+
+        $this->filter = $filter;
+        $this->filterType = $filterType;
+        $this->filterValue = $filterValue;
+
+        // Check for required site parameters
+        if (!defined('BASE_PATH') || !defined('BASE_URL')) {
+            echo "ERROR: GLMsearch class requires BASE_PATH and BASE_URL to be set.";
+            exit;
+        }
+
+        // Filter and validate supplied parameters
+        if (
+            ($website = filter_var($website, FILTER_SANITIZE_STRING, FILTER_FLAG_STRIP_HIGH)) == false ||
+            ($login = filter_var($login, FILTER_SANITIZE_STRING, FILTER_FLAG_STRIP_HIGH)) == false ||
+            ($key = filter_var($key, FILTER_SANITIZE_STRING, FILTER_FLAG_STRIP_HIGH)) == false
+        ) {
+            $this->errorMessage = '__contruct() - $website, $login, or $key did not validate.';
+            $this->debug();
+            return false;
+        }
+
+        // Store the index name. If not specified, assume it's same as the website
+        if ($index) {
+            $this->index = $index;
+        } else {
+            $this->index = $website;
+        }
+
+        // Store the Web site name
+        $this->website = $website;
+
+        // Build authentication parameters for submissions
+        $this->auth = "login=$login&key=$key";
+
+        // Create curl instance - and set to return response
+        $this->curl = curl_init();
+        curl_setopt($this->curl, CURLOPT_RETURNTRANSFER, TRUE);
+
+        $this->errorMessage = '__construct() - Completed successfully.';
+        $this->debug("Index: ".$this->index."<br>Website: ".$this->website."<br>Authentication: ".$this->auth);
+
+    }
+
+    /**
+     * Perform a search on the Web site
+     *
+     * @param string    $query      The user's search string
+     * @param string    $operator   Operator for the query terms (AND, OR)
+     *                                  Default = 'OR'
+     * @param integer   $start      Starting result number
+     *                                  Default = 0 (first page)
+     * @param integer   $rows       Number of rows per result page
+     *                                  Default = 10
+     *
+     * @return string   JSON of results or false if a failure
+     *
+     * @access public
+     */
+    public function search($query, $operator = 'OR', $start = 0, $rows = 10)
+    {
+
+        // Clear all the results data
+        $this->clearResults();
+
+        // Filter and validate supplied parameters
+        if (
+            (filter_var($query, FILTER_SANITIZE_STRING, FILTER_FLAG_STRIP_HIGH)) == false ||
+            (in_array($operator, array('OR', 'AND'))) == false
+        ) {
+            $this->errorMessage = 'search() - $query or $operator did not validate.';
+            $this->debug();
+            return false;
+        }
+
+        // strip any characters that cause a problem. Add more characters to array if needed.
+        $remove = array("'");
+        $query = htmlspecialchars_decode($query, ENT_QUOTES);
+        $query = str_replace("'", "", $query);
+
+        $start = ($start - 0);
+        $rows = ($rows - 0);
+
+
+        // Check if we have a valid query
+        if (trim($query) == '') {
+            $this->errorMessage = 'search() - No query supplied';
+            $this->debug();
+            return false;
+        }
+
+        // Create request URL
+        switch ($this->type) {
+               case 'field':
+                $url = OpenSearchServer.'/services/rest/index/'.$this->index.'/search/field/?'.$this->auth;
+                break;
+               case 'pattern':
+                   $url = OpenSearchServer.'/services/rest/index/'.$this->index.'/search/pattern/?'.$this->auth;
+                   break;
+        }
+        $this->debug('Request URL: '.$url);
+
+        // Update query and operator in request
+        $this->request['query'] = $query;
+        $this->request['start'] = $start;
+        $this->request['rows'] = $rows;
+        $this->request['operator'] = $operator;
+
+        // If host filter has not been turned off, set filter to only search the specified Website in the index
+        if ($this->filter) {
+
+            // Determine if there's a specific filter type and value - Default to host:
+            $query = 'host:"'.$this->website.'"';
+            if ($this->filterType) {
+               if ($this->filterValue) {
+                    $query = $this->filterType.':"'.$this->filterValue.'"';
+                } else {
+                    $query = $this->filterType.':"'.$this->website.'"';
+                }
+            }
+
+            // Set filter
+            $this->request['filters'] = array(
+               array(
+                    "type" => "QueryFilter",
+                    "negative" => false,
+                    "query" => $query
+               )
+            );
+
+        } else {
+            unset($this->request['filters']);
+        }
+
+        // Set curl options
+        curl_setopt_array($this->curl, array(
+            CURLOPT_URL => $url,
+            CURLOPT_POST => true,
+            CURLOPT_POSTFIELDS => json_encode($this->request),
+            CURLOPT_HTTPHEADER => array("Content-type: application/json; charset=utf-8"),
+            CURLOPT_VERBOSE => 1,
+            CURLOPT_HEADER => 1
+        ));
+
+        $this->debug('Post fields: <br><pre>'.print_r($this->request,1)."</pre>");
+
+        // Do curl call and get result;
+        try {
+            $res = curl_exec($this->curl);
+        } catch (Exception $e) {
+
+            // Problem doing curl call - return failure information
+            $this->error = $e;
+            $this->errorMessage = 'search() - '.curl_error($this->curl);
+            $this->debug($e);
+
+            // Log the error in the server error log
+            error_log('GLMSearch: search() - '.curl_error($this->curl));
+
+            return false;
+        }
+
+        // Parse out results elements
+        $this->httpStatus = curl_getinfo($this->curl, CURLINFO_HTTP_CODE);
+        $header_size = curl_getinfo($this->curl, CURLINFO_HEADER_SIZE);
+        $this->httpHeader = substr($res, 0, $header_size);
+        $this->rawResults = substr($res, $header_size);
+
+        // Curl result debug
+        $this->debug(
+            "crawlURL() - Curl response\n"
+            .'HTTP Status: '.$this->httpStatus."\n"
+            ."HTTP Header\n".$this->httpHeader."\n\n"
+        );
+
+        // Check HTTP status code
+            if ($this->httpStatus != 200) {
+            $this->errorMessage = 'search() - Received bad status code: '.$this->httpStatus."<br>RawResults: <br><pre>".print_r($res,1)."</pre><br>";
+            $this->debug();
+            return false;
+        }
+
+        // Debug information
+        $this->errorMessage = 'search() - Completed successfully.';
+        $this->debug($this->rawResults);
+
+        return $this->rawResults;
+    }
+
+    /**
+     * Convert raw search results JSON to a associative array
+     *
+     * @return array    Array of results or false if a failure
+     *
+     * @access public
+     */
+    public function results2array()
+    {
+
+        // Check if we don't have any search results
+        if ($this->rawResults == false) {
+            $this->errorMessage = 'results2array() - No search results to convert.';
+            $this->debug();
+            return false;
+        }
+
+        // Response should be a json - convert to associative array
+        $this->resultArray = json_decode($this->rawResults, true);
+        if ($this->resultArray == null) {
+            // Problem decoding json - return failure information
+            $this->errorMessage = 'results2array() - '.$this->jsonErrorMsg();
+            $this->debug();
+            return false;
+        }
+
+        // Check if result "successful" flag isn't true
+        if (!$this->resultArray['successful']) {
+            $this->errorMessage = 'resuts2array() - Search result marked as not successful.';
+            $this->debug();
+            return false;
+        }
+
+        $this->errorMessage = 'results2array() - Completed successfully.';
+        $this->debug($this->resultArray);
+
+        return $this->resultArray;
+
+    }
+
+    /**
+     * Compress search results as associative array into
+     * more succinct result array for use with output template.
+     *
+     * @param $res Uncompressed search results array
+     *
+     * @return array Array of results or false if a failure
+     *
+     * @access public
+     */
+    public function compressResults()
+    {
+
+        // Check if we don't have valid input
+        if (!is_array($this->resultArray) || !$this->resultArray['successful']) {
+            $this->errorMessage = 'compressResults() - Successful search results not supplied.';
+            $this->debug();
+            return false;
+        }
+
+        // Calculate certain paging values
+        $rowsPerPage = $this->resultArray['rows'];
+        $thisPageStartIndex = $this->resultArray['start'];                  // Based on first result being 0
+        $thisPageStart = $thisPageStartIndex + 1;                           // Displayed first result number
+        $numbResults = $this->resultArray['numFound'];
+        $numbResultsOnPage = count($this->resultArray['documents']);
+        $lastResultOnPage = $thisPageStart + $numbResultsOnPage - 1;
+        $previousPageStartIndex = $thisPageStartIndex - $rowsPerPage;
+        if ($previousPageStartIndex < 0) {
+            $previousPageStartIndex = false;
+        }
+        $nextPageStartIndex = $thisPageStartIndex + $rowsPerPage;
+        if ($nextPageStartIndex > ($numbResults - 1)) {
+            $nextPageStartIndex = false;
+        }
+
+        // Build basic search results array
+        $this->result = array(
+            'resultsPerPage' => $this->resultArray['rows'],
+            'operator' => $this->request['operator'],
+            'totalResults' => $numbResults,
+            'firstResultOnPage' => $thisPageStart,
+            'resultsOnPage' => $numbResultsOnPage,
+            'lastResultOnPage' => $lastResultOnPage,
+            'previousPageStartIndex' => $previousPageStartIndex,
+            'nextPageStartIndex' => $nextPageStartIndex,
+            'documents' => array()
+        );
+
+        // Add in results for each document
+        foreach ($this->resultArray['documents'] as $d) {
+
+            // Base document information
+            $doc = array(
+               'score' => $d['score'],
+                'collapseCount' => $d['collapseCount']
+            );
+
+            // Document fields (simple text fields)
+            foreach ($d['fields'] as $df) {
+                $doc[$df['fieldName']] = array(
+                    'type' => 'field',
+                    'name' => $df['fieldName'],
+                    'value' => (isset($df['values'][0]) ? $df['values'][0] : '')
+                );
+
+            }
+
+            // Document snippets (possible multiple snippets per each)
+            foreach ($d['snippets'] as $ds) {
+                $doc[$ds['fieldName']] = array(
+                    'type' => 'snippets',
+                       'name' => $ds['fieldName'],
+                    'snippets' => array()
+                );
+
+                // Process possible multiple snippet values
+                if (is_array($ds['values']) && count($ds['values']) > 0) {
+                    foreach ($ds['values'] as $sv) {
+                        $doc[$ds['fieldName']]['snippets'][] = $sv;
+                    }
+                }
+
+            }
+
+            // Need to add processing of "functions" also here
+
+            // Look for null or blank title
+            if (empty($doc['title']['value']) && !empty($doc['url']['value'])) {
+                $doc['title']['value'] = $doc['url']['value'];
+            }
+
+            // Clean up lastModifiedDate if included
+            if (isset($doc['lastModifiedDate']) && isset($doc['lastModifiedDate']['value'])) {
+                $d = $doc['lastModifiedDate']['value'];
+                $doc['lastModifiedDate']['textValue'] = '';
+                if (trim($d) != '') {
+                    $doc['lastModifiedDate']['textValue'] = substr($d, 0, 4).'-'.substr($d,4,2).'-'.substr($d,6,2);
+                }
+            }
+
+            // Add this document to result documents array
+            $this->result['documents'][] = $doc;
+
+        }
+
+        $this->errorMessage = 'compressResults() - Completed successfully.';
+        $this->debug($this->result);
+
+        return $this->result;
+    }
+
+    /**
+     * Render result using Smarty template
+     *
+     * NOTE: This does not use an OpenSearchServer Template.
+     * We can consider adding that functionality later.
+     *
+     * @param string $template Template to use for producing results (def
+     * @param string $base     Base path to template
+     *
+     * @return void
+     * @access public
+     */
+    public function render($templateName = GLMSearch_TEMPLATE, $templateBasePath = GLMSearch_TEMPLATE_PATH)
+    {
+
+        $smarty = new Smarty();
+
+        // Setup required Smarty paths - Assumes that BASE_PATH for site is properly defined
+        $smarty->setTemplateDir($templateBasePath);
+        $smarty->setCompileDir(BASE_PATH.'/smarty/templates_c');
+        $smarty->setCacheDir(BASE_PATH.'/smarty/cache');
+
+        // If we have a result, add it to Smarty
+        $haveResult = false;
+        if ($this->result != false) {
+
+            $haveResult = true;
+
+            // Convert compressed result array to an object for Smarty
+            $result = json_decode(json_encode($this->result));
+            $smarty->assign('result', $result);
+
+        }
+
+        // Tell template whether we have a result
+        $smarty->assign('haveResult', $haveResult);
+
+        // Script URI
+        $smarty->assign('thisScript', BASE_URL);
+
+        // Some other parameters
+        $smarty->assign('matchAll', ($this->request['operator'] == 'AND' ? 'on' : ''));
+        // Note: use {$query|escape:'url'} in Smarty to use this parameter in a URL
+        $smarty->assign('query', $this->request['query']);
+
+        // Display Smarty Console if requested
+        if ($this->smartyConsole) {
+            Smarty_Internal_Debug::display_debug($smarty);
+        }
+
+        // Generate the page
+        $page = $smarty->fetch($templateName);
+
+        $this->errorMessage = 'render() - Completed successfully.';
+        $this->debug($smarty->tpl_vars);
+
+        return $page;
+    }
+
+    /**
+     * Do entire search and display process
+     *
+     * Uses the following POST/GET parameters
+     *      query       User's search string
+     *      matchAll    Optional checkbox to specify use of "AND" operator
+     *
+     * @param string $template Template to use for producing results (override default)
+     * @param string $base     Base path to template (override default)
+     *
+     * @return void
+     * @access public
+     */
+    public function doSearch($templateName = GLMSearch_TEMPLATE, $templateBasePath = GLMSearch_TEMPLATE_PATH, $request = false)
+    {
+
+        $this->errorMessage = 'doSearch() called.';
+        $this->debug("Template name: ".$templateName."<br>Template base path: ".$templateBasePath."<br>Request: ".print_r($request,1));
+
+        // Check if receiving an array of parameters rather than REQUEST parameters
+        if (is_array($request) && count($request) > 0) {
+
+            // Look for query string
+            $query = '';
+            if (isset($request['query'])) {
+                $query = trim($request['query']);
+            }
+
+            // Look for matchAll (operator) flag
+            $operator = '';
+            if (isset($request['matchAll'])) {
+                $operator = $request['matchAll'];
+            }
+
+            // Look for start row
+            $start = 0;
+            if (isset($request['start'])) {
+                $start = ($request['start']-0);
+            }
+
+            // Look for rows - Default is maximium allowable for sitemaps
+            $rows = 50000;
+            if (isset($request['rows'])) {
+                $rows = ($request['rows']-0);
+            }
+
+        } else {
+
+            // get query string - try POST, but if that fails try GET
+            $query = filter_input(INPUT_POST, 'query', FILTER_SANITIZE_STRING, FILTER_FLAG_STRIP_HIGH);
+            if ($query == null) {
+                $query = filter_input(INPUT_GET, 'query', FILTER_SANITIZE_STRING, FILTER_FLAG_STRIP_HIGH);
+            }
+            $operator = ($_REQUEST['matchAll'] != '' ? 'AND' : 'OR');
+            $start = ($_REQUEST['start'] - 0);
+            $rows = ($_REQUEST['rows'] - 0);
+
+        }
+
+        // Try to do the query and process the results
+        if (
+            trim($query) != '' &&
+            $this->search($query, $operator, $start, $rows) &&
+            $this->results2array() &&
+            $this->compressResults()
+        ) { }
+
+        $page = $this->render($templateName, $templateBasePath);
+
+        return $page;
+    }
+
+    /**
+     * Create an XML Sitemap from search results
+     *
+     * @param string $template Template to use for producing results (override default)
+     * @param array $request Array of request parameters
+     *      'query'         Required - Search String
+     *      'matchAll'      Optional - Match all words option ('AND', 'OR')
+     *      'start'         Optional - Start index
+     *      'rows'          Optional - Results per page
+     *
+     * @return void
+     * @access public
+     */
+    public function xmlSitemap($templateName = 'Sitemap_XML_0.9.html')
+    {
+
+        // Search for * (matches everything)
+        $request = array(
+               'query' => 'a b c d e f g h i j k l m n o p q r s t u v w x y z 0 1 2 3 4 5 6 7 8 9',
+            'matchAll' => 'OR',
+            'start' => 0,
+            'rows' => 50000
+        );
+        $page = $this->doSearch($templateName, GLMSearch_TEMPLATE_PATH, $request);
+        $this->debug($page);
+        return $page;
+    }
+
+    /**
+     * Tell OpenSearchServer to crawl a particular URL pattern
+     *
+     * @param integer   $pattern  URL Pattern
+     *
+     * @return array    Object    Results from Search Engine or false if failure.
+     *
+     * @access public
+     */
+    public function crawlURL($pattern)
+    {
+
+        // Clear all the results data
+        $this->clearResults();
+
+        // Filter and validate supplied parameters
+        if (($pattern = filter_var($pattern, FILTER_SANITIZE_STRING, FILTER_FLAG_STRIP_HIGH)) == false) {
+            $this->errorMessage = 'crawlURL() - $pattern did not validate';
+            $this->debug();
+            return false;
+        }
+
+        // Create request URL
+        $param = 'url='.$pattern;
+        $url = OpenSearchServer.'/services/rest/index/'.$this->index.'/crawler/web/crawl?'.$this->auth.'&'.$param;
+
+        // Set curl options
+        curl_setopt_array($this->curl, array(
+            CURLOPT_URL => $url,
+            CURLOPT_POST => false,
+            CURLOPT_VERBOSE => 1,
+            CURLOPT_HEADER => 1
+        ));
+
+        // Do curl call and get result;
+        try {
+            $res = curl_exec($this->curl);
+        } catch (Exception $e) {
+            // Problem doing curl call - return failure information
+            $this->error = $e;
+            $this->errorMessage = 'crawlURL() - '.curl_error($this->curl);
+            $this->debug($e);
+            return false;
+        }
+
+        // Parse out results elements
+        $this->httpStatus = curl_getinfo($this->curl, CURLINFO_HTTP_CODE);
+        $header_size = curl_getinfo($this->curl, CURLINFO_HEADER_SIZE);
+        $this->httpHeader = substr($res, 0, $header_size);
+        $this->rawResults = substr($res, $header_size);
+
+        // Curl result debug
+        $this->debug(
+            "crawlURL() - Curl response\n"
+            .'HTTP Status: '.$this->httpStatus."\n"
+            ."HTTP Header\n".$this->httpHeader."\n\n"
+        );
+
+        // Check HTTP status code
+        if ($this->httpStatus != 200) {
+            $this->errorMessage = 'crawlURL() - Received bad status code: '.$this->httpStatus;
+            $this->debug($this->rawResults);
+            return false;
+        }
+
+        // Debug information
+        $this->errorMessage = 'crawlURL() - Completed successfully.';
+        $this->debug($this->rawResults);
+
+        return json_decode($this->rawResults);
+    }
+
+    /**
+     * Get text message for last JSON error
+     *
+     * @return void
+     * @access private
+     */
+    private function jsonErrorMsg()
+    {
+
+        // Get running version of PHP
+        if (defined('PHP_VERSION_ID')) {
+            $php = PHP_VERSION_ID;
+        } else {
+            $version = explode('.', PHP_VERSION);
+            $php = ($version[0] * 10000 + $version[1] * 100 + $version[2]);
+        }
+
+        // If PHP version 5.5 or later
+        if ($php >= 50500) {
+
+            // Just ask for the last json error message
+            $msg = json_last_error_msg();
+
+        } else {
+
+            // Running ealier PHP so set message based on last json error type
+            switch (json_last_error()) {
+
+                case JSON_ERROR_NONE:
+                    $msg = 'No errors';
+                    break;
+
+                case JSON_ERROR_DEPTH:
+                    $msg = 'Maximum stack depth exceeded';
+                    break;
+
+                case JSON_ERROR_STATE_MISMATCH:
+                    $msg = 'Underflow or the modes mismatch';
+                    break;
+
+                case JSON_ERROR_CTRL_CHAR:
+                    $msg = 'Unexpected control character found';
+                    break;
+
+                case JSON_ERROR_SYNTAX:
+                    $msg = 'Syntax error, malformed JSON';
+                    break;
+
+                case JSON_ERROR_UTF8:
+                    $msg = 'Malformed UTF-8 characters, possibly incorrectly encoded';
+                    break;
+
+                default:
+                    $msg = 'Unknown error';
+                    break;
+            }
+        }
+
+        return $msg;
+
+    }
+
+    /**
+     * Clear all request and results data - used before a new curl call
+     *
+     * @return void
+     * @access private
+     */
+    private function clearResults()
+    {
+
+        /*
+         * Reset request to default
+         * (Note: Need to add more explanation for this data.)
+         */
+        $this->request = array(
+            'query' => false,                       // Query String
+            'start' => 0,                           // Result number for start of page
+            'rows' => 10,                           // Number of rows to display per page
+            'lang' => 'ENGLISH',                    // Language (in all caps)
+            'operator' => 'AND',                    // Either AND or OR - And matches pages containing all words
+            'collapsing' => array(
+                'max' => 2,
+                'mode' => 'OFF',
+                'type' => 'OPTIMIZED'
+            ),
+            'geo' => null,
+            'filters' => null,
+            'sorts' => null,
+            'returnedFields' => array(
+                'url',
+                'title',
+                'lastModifiedDate'
+            ),
+            'snippets' => array(
+                array(
+                    'field' => 'content',
+                    'tag' => 'b',
+                    'separator' => '...',
+                    'maxSize' => 300,
+                    'maxNumber' => 1,
+                    'fragmenter' => 'SENTENCE'
+                )
+            ),
+            'facets' => null,
+            'joins' => null,
+            'enableLog' => null,
+            'customLogs' => null,
+            'searchFields' => array(
+                array(
+                    'field' => 'title',
+                    'boost'=> 10
+                ),
+                array(
+                    'field' => 'content',
+                    'boost'=> 1
+                ),
+                array(
+                    'field' => 'titleExact',
+                    'boost'=> 10
+                ),
+                array(
+                    'field' => 'contentExact',
+                    'boost'=> 1
+                )
+            )
+        );
+        // Clear results
+        $this->httpStatus = false;
+        $this->httpHeader = false;
+        $this->rawResults = false;
+        $this->resultArray = false;
+        $this->result = false;
+        $this->errorMessage = false;
+        $this->error = false;
+
+    }
+
+    /**
+     * Display debug information if debug is on
+     *
+     * @return void
+     * @access private
+     */
+    public function debug($d = false)
+    {
+        if ($this->debug) {
+            echo $this->errorMessage."<br>";
+
+            if ($d != false) {
+                echo "<pre>".print_r($d,1)."</pre>";
+            }
+        }
+    }
+
+}
+
+?>
diff --git a/recrawl.php b/recrawl.php
new file mode 100644 (file)
index 0000000..14024be
--- /dev/null
@@ -0,0 +1,77 @@
+<html>
+       <head>
+       </head>
+       <body>
+               <h1>Index or re-index a specific Web page for site search engine.</h1>
+<?
+
+define('BASE_PATH', '/var/www/server/CommonApps/GLMSearch/V1.1/');
+
+switch ($_ENV['GLM_HOST_ID']) {
+    case 'PRODUCTION' :
+    case 'DEVELOPMENT' :
+    case 'STEVE' :
+        define('BASE_URL', 'http://stats.gaslightmedia.com/GLMSearch/V1.1/recrawl.php');
+        break;
+    case 'CHUCK' :
+        define('BASE_URL', 'http://192.168.44.7/CommonApps/GLMSearch/V1.1/recrawl.php');
+        break;
+    default :
+        die('<p>Your request could not be completed at this time, please try again later!</p>');
+        break;
+}
+
+$debug = false;
+
+
+$pattern = $_REQUEST['pattern'];
+
+echo '
+               <form action="'.BASE_URL.'">
+                       <p>Address of page to re-index: <input type="text" name="pattern" value="'.$pattern.'" size="60"><input type="submit" name="Submit"></p>
+
+               </form>
+';
+
+if ($pattern != '') {
+
+
+    /***** This is the part that would be needed to add this feature to other code *****/
+
+    $index = 'Index_1';
+    $site = '*';               //  <<<<---- Put a specific host name here to only permit indexing in that site. (i.e.  www.n8dnx.org)
+    $login = 'WebsiteServices';
+    $key = '829800701e8440b67a78e3afbefa1049';
+
+    require('/var/www/server/CommonApps/GLMSearch/V1.1/glmSearch.inc');
+       $glmSearch = new glmSearch($site, $login, $key, $debug, $index);
+       $res = $glmSearch->crawlURL($pattern);
+
+       /***********************************************************************************/
+
+    if ($debug) {
+        echo "<p>Searcing<br>Index: $index<br>Site: $site<br>Pattern: $pattern<br>Login: $login<br>Key: $key<br>Debug: ".($debug ? 'Yes' : 'No')."</p>";
+    }
+
+       echo '<p>
+              <table>
+                  <tr><th align="left">Index of page: </th><td>'.$pattern.'</td></tr>';
+
+       if ($res != false && $res->successful && preg_match('/Fetched - Parsed - Indexed/',$res->info)) {
+           echo '<tr><th align="left" valign="top">Response: </th><td>'.$res->info.'</td></tr>';
+       } else {
+           echo '<tr><th align="left" valign="top">Error information: </th><td><pre>'.print_r($res,1).'</pre></td></tr>
+              <tr><td colspan="2" align="left">
+                  Please check the address you\'re supplying above. If you believe the address is a valid
+                  Web page and you continue to have problems, please contact Gaslight Media for support
+                  and provide the information supplied above.
+              </td></tr>
+           ';
+       }
+
+       echo "</table></p>";
+
+}
+?>
+       </body>
+</html>
diff --git a/remoteSearchSupport.php b/remoteSearchSupport.php
new file mode 100644 (file)
index 0000000..78f1476
--- /dev/null
@@ -0,0 +1,56 @@
+<?
+/**
+ * Remote Search Facility for GLMSearch Application
+ */
+
+define('BASE_PATH', '/var/www/server/CommonApps/GLMSearch/V1.1/');
+
+// Get site to search
+$website = filter_input(INPUT_POST, 'website', FILTER_SANITIZE_STRING, FILTER_FLAG_STRIP_HIGH);
+if ($website == false) {
+    $website = filter_input(INPUT_GET, 'website', FILTER_SANITIZE_STRING, FILTER_FLAG_STRIP_HIGH);
+}
+if ($website == false) {
+    echo "GLMSearch ERROR: Site not specified.";
+    exit;
+}
+
+// Get index to use - if not provided, then use the website name
+$index = filter_input(INPUT_POST, 'index', FILTER_SANITIZE_STRING, FILTER_FLAG_STRIP_HIGH);
+if ($index == false) {
+    $index = filter_input(INPUT_GET, 'index', FILTER_SANITIZE_STRING, FILTER_FLAG_STRIP_HIGH);
+}
+if ($index == false) {
+    $index = $website;
+}
+
+// Get URL for form action
+$returnUrl = filter_input(INPUT_POST, 'returnUrl', FILTER_SANITIZE_STRING, FILTER_FLAG_STRIP_HIGH);
+if ($returnUrl == false) {
+    echo "GLMSearch ERROR: Return URL not specified.";
+    exit;
+}
+define('BASE_URL', $returnUrl);
+
+$login = 'WebsiteServices';
+$key = '829800701e8440b67a78e3afbefa1049';
+
+// Load and instantiate search class
+require('glmSearch.inc');
+$glmSearch = new glmSearch($website, $login, $key, false, $index);
+
+// Add in returnUrl override
+//$glmSearch-> =
+
+// Turn on GLMSearch class debug or Smarty console - if desired
+// $glmSearch->debug = true;
+// $glmSearch->smartyConsole = true;
+
+$searchPage = $glmSearch->doSearch();
+
+// Display the produced page
+echo $searchPage;
+
+exit;
+
+?>
\ No newline at end of file
diff --git a/templates/Sitemap_XML_0.9.html b/templates/Sitemap_XML_0.9.html
new file mode 100644 (file)
index 0000000..76b93de
--- /dev/null
@@ -0,0 +1,12 @@
+{if $haveResult}<?xml version="1.0" encoding="UTF-8"?>
+<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
+{foreach $result->documents as $doc}
+    <url>
+        <loc>{$doc->url->value|escape:'html'}</loc>
+{if $doc->lastModifiedDate->textValue}
+        <lastmod>{$doc->lastModifiedDate->textValue}</lastmod>
+{/if}
+        <changefreq>weekly</changefreq>
+    </url>
+{/foreach}
+</urlset>{else}Sitemap Error: No results available{/if}
diff --git a/templates/default.html b/templates/default.html
new file mode 100644 (file)
index 0000000..5e8cd57
--- /dev/null
@@ -0,0 +1,153 @@
+<!-- 
+    GLM OpenSearchServer Default Display Page
+-->
+       
+       <style type="text/css">
+           #GLMSearch {
+               padding: 1em;
+           }
+           #GLMSformContainer {}
+           #GLMSformContainer input {}
+           .GLMSresultsHeader {
+               margin-top: 1em;
+               margin-bottom: 2em;
+           }
+           .GLMSresultsSummary {}
+           .GLMSresultsNavContainer {}
+           .GLMSresultsNavContainer a {}
+           .GLMSresultsNavInactive {
+               color: lightgray;
+           }
+           #GLMSresultsContainer {
+           }
+           .GLMSresultContainer {
+               color: #1E130A;
+               font-family: Arial,Helvetica,sans-serif;
+               font-size: 12px;
+               margin-bottom: 2em;
+           }
+           .GLMSresultTitle {
+               color: #0000CC;
+               text-decoration: underline;
+               font-weight: bold;
+               margin-bottom: .3em;
+           }
+           .GLMSresultText {}
+           .GLMSresultSnippets {}
+           .GLMSresultSnippets b {
+               border: solid lightgray 1px;
+               padding: .1em;
+           }
+           .GLMSresultUrl {
+               color: #008000;
+               margin-top: .2em;
+           }
+           #slideshow {
+               display: none;
+           }
+       </style>
+
+        <div id="GLMSearch">
+
+               <div id="GLMSformContainer">
+                   <h1>Search this Website</h1>
+                               <form action="{$thisScript}" name="search" method="get">
+                       <input type="hidden" name="GLMSearch" value="true">
+                                   <input type="hidden" name="start" value="0">
+                                   <input type="hidden" name="rows" value="10">
+                                   <input type="text" name="query" value="{$query}">
+                                   <input type="checkbox" name="matchAll" {if $result->operator eq 'AND'}checked{/if}> Match all words
+                       <input type="submit" id="submit" value="Search">
+                               </form>
+               </div>
+
+{if $haveResult}
+
+  {if $result->totalResults > 0}
+  
+            <!-- Results Header - Top -->
+            
+            <div class="GLMSresultsHeader">
+
+                   <div class="GLMSresultsSummary">
+                       Showing {$result->firstResultOnPage} through {$result->lastResultOnPage} of {$result->totalResults} results.
+                   </div> 
+                   
+                   <!-- Results Navigation -->
+                       
+                       <div class="GLMSresultsNavContainer">
+
+           {if $result->previousPageStartIndex !== false} 
+                       <a href="{$thisScript}?GLMSearch=true&query={$query|escape:'url'}&matchAll={$matchAll}&start={$result->previousPageStartIndex}&rows={$result->resultsPerPage}">Previous Results</a>
+           {else}
+                       <span class="GLMSresultsNavInactive">Previous Results</span>
+           {/if}
+                       -
+           {if $result->nextPageStartIndex !== false}
+                       <a href="{$thisScript}?GLMSearch=true&query={$query|escape:'url'}&matchAll={$matchAll}&start={$result->nextPageStartIndex}&rows={$result->resultsPerPage}">Next Results</a>    
+           {else}
+                       <span class="GLMSresultsNavInactive">Next Results</span>
+           {/if}
+                       </div>
+       
+            </div>
+                        
+            <!-- Search results -->
+            
+            <div id="GLMSresultsContainer">
+
+           {foreach $result->documents as $doc}
+                   <div class="GLMSresultContainer">
+                   
+                       <div class="GLMSresultTitle">
+                           <a href="{$doc->url->value}">{$doc->title->value}</a>
+                       </div>
+                       
+                       <div class="GLMSresultSnippets">
+            {foreach from=$doc->content->snippets item="snip" name="snip"}                     
+                           {$snip}
+                  {if (!$smarty.foreach.snip.last)}<br>----<br>{/if} 
+               {/foreach}
+                       </div>
+                       <div class="GLMSresultUrl">{$doc->url->value}</div>
+                   </div>                     
+           {/foreach}
+                   
+               </div>
+
+            <!-- Results Header - Bottom -->
+            
+            <div class="GLMSresultsHeader">
+
+                <div class="GLMSresultsSummary">
+                    Showing {$result->firstResultOnPage} through {$result->lastResultOnPage} of {$result->totalResults} results.
+                </div> 
+                
+                <!-- Results Navigation -->
+                
+                <div class="GLMSresultsNavContainer">
+
+        {if $result->previousPageStartIndex !== false} 
+                    <a href="{$thisScript}?GLMSearch=true&query={$query|escape:'url'}&matchAll={$matchAll}&start={$result->previousPageStartIndex}&rows={$result->resultsPerPage}">Previous Results</a>
+        {else}
+                    <span class="GLMSresultsNavInactive">Previous Results</span>
+        {/if}
+                    -
+        {if $result->nextPageStartIndex !== false}
+                    <a href="{$thisScript}?GLMSearch=true&query={$query|escape:'url'}&matchAll={$matchAll}&start={$result->nextPageStartIndex}&rows={$result->resultsPerPage}">Next Results</a>    
+        {else}
+                    <span class="GLMSresultsNavInactive">Next Results</span>
+        {/if}
+                </div>
+    
+            </div>
+                        
+                   
+  {else}
+            <h3>No results matching your search.</h3>
+  {/if}
+
+{/if}
+
+
+        </div> <!-- GLMSearch -->
diff --git a/test/XML_Sitemap_Test.php b/test/XML_Sitemap_Test.php
new file mode 100644 (file)
index 0000000..9a09148
--- /dev/null
@@ -0,0 +1,34 @@
+<?
+/**
+ * Test production of an XML Sitemap
+ */
+
+define('BASE_PATH', '/var/www/server/CommonApps/GLMSearch/V1.1/');
+define('BASE_URL', 'http://192.168.44.7/CommonApps/GLMSearch/V1.1/test/test.php');
+
+$site = 'www.n8dnx.org';
+$login = 'WebsiteServices';
+$key = '829800701e8440b67a78e3afbefa1049';
+
+// File location for created sitemap - Normally the following
+// define('XML_SITEMAP_FILE', '/var/www/server/'.$site.'/sitemap.xml');
+define('XML_SITEMAP_FILE', '/tmp/sitemap.xml');
+
+// Tell the glmSearch class whether you want debug output.
+$debug = true;
+
+require('../glmSearch.inc');
+$glmSearch = new glmSearch($site, $login, $key, $debug);
+
+$sitemap = $glmSearch->xmlSitemap('Sitemap_XML_0.9.html');
+
+// Save the sitemap file
+file_put_contents(XML_SITEMAP_FILE, $sitemap);
+
+// Display the sitemap - not normally done for creating sitemaps
+//header('Content-Type: text/xml');
+echo $sitemap;
+
+exit;
+
+?>
\ No newline at end of file
diff --git a/test/crawlUrlTest.php b/test/crawlUrlTest.php
new file mode 100644 (file)
index 0000000..e8e1c9c
--- /dev/null
@@ -0,0 +1,83 @@
+<?
+/**
+ * Test GLMSearch Class - Crawl specified URL pattern
+ *
+ * Can be used by the Toolbox to re-index a page when the page is updated.
+ */
+
+/*
+ * *** BE SURE TO SETUP THESE PARAMETERS BEFORE RUNNING TEST ***
+ *
+ * These defined parameters are usually provided by the site.
+ *
+ * Note that BASE_PATH would normally be the for the site. This
+ * is used to find the Smarty compile directory for the site,
+ * which should be created automatically.
+ */
+define('BASE_PATH', '/var/www/server/CommonApps/GLMSearch/V1.1/');
+define('BASE_URL', 'http://192.168.44.7/CommonApps/GLMSearch/V1.1/test/crawlUrlTest.php');
+
+/*
+ * These are required parameters to use the search server.
+ *
+ * $site    The "index" as created by "Create a new indes"
+ *          in the OpenSearchServer administrative interface.
+ * $login   Login for access to the API as created under "Privileges"
+ *          in the OpenSearchServer administrative interface.
+ *          Use 'WebsiteServices' for all sites. (Sites are
+ *          separated by "index".)
+ * $key     API Key created along with login. The key below
+ *          is for use with all sites.
+ *
+ * These parameters should normally be specified in the
+ * config/application.ini file as follows.
+ *
+ * glmsearch.site = "demo.gaslightmedia.com"
+ * glmsearch.login = "WebsiteServices"
+ * glmsearch.key = "3cd270eda427d55874aafa45919f7026"
+ *
+ */
+$index = 'Index_1';
+$site = 'www.wmta.org';
+$pattern = "http://www.wmta.org/member-profile/649/1572/";
+$login = 'WebsiteServices';
+$key = '829800701e8440b67a78e3afbefa1049';
+
+// Tell the glmSearch class whether you want debug output.
+$debug = true;
+
+/*
+ * Load and instantiate search class
+ *
+ * The file included is normally '/var/www/server/CommonApps/GLMSearch/V1.1/glmSearch.inc'.
+ * You may have to change this to test on your own machine.
+ *
+ * $debug is optional.
+ */
+require('/var/www/server/CommonApps/GLMSearch/V1.1/glmSearch.inc');
+$glmSearch = new glmSearch($site, $login, $key, $debug, $index);
+
+/*
+ * Run crawlURL() method to crawl the specified URL pattern.
+ *
+ * The URL pattern must be within the specified site. Wild-card
+ * characters should be permitted but haven't tested this.
+ */
+echo "<p>Re-Crawling using a URL pattern<br>Site: $site<br>URL Pattern: $pattern</p>";
+$res = $glmSearch->crawlURL($pattern);
+
+/*
+ * Check for success
+ *
+ *  1) If result is false, then a fatal error with no good return data.
+ *  2) Good return data will have $res->successful set to true if API completed request.
+ *  3)
+ *
+ */
+if ($res != false && $res->successful && preg_match('/Fetched - Parsed - Indexed/',$res->info)) {
+    echo "Successfull crawl of specified URL pattern.<pre>".print_r($res,1)."</pre>";
+} else {
+    echo "Craw was not successful.<pre>".print_r($res,1)."</pre>";
+}
+
+?>
diff --git a/test/remoteTest.php b/test/remoteTest.php
new file mode 100644 (file)
index 0000000..5b1a704
--- /dev/null
@@ -0,0 +1,4 @@
+<?
+include '../docs/remoteSearch.inc';
+echo $glmsResults;
+?>
\ No newline at end of file
diff --git a/test/test.php b/test/test.php
new file mode 100644 (file)
index 0000000..c31c870
--- /dev/null
@@ -0,0 +1,126 @@
+<?
+/**
+ * Test GLMSearch Class
+ */
+
+/*
+ * *** BE SURE TO SETUP THESE PARAMETERS BEFORE RUNNING TEST ***
+ *
+ * These defined parameters are usually provided by the site.
+ *
+ * Note that BASE_PATH would normally be the for the site. This
+ * is used to find the Smarty compile directory for the site,
+ * which should be created automatically.
+ */
+define('BASE_PATH', '/var/www/server/CommonApps/GLMSearch/V1.1/');
+define('BASE_URL', 'http://192.168.44.7/CommonApps/GLMSearch/V1.1/test/test.php');
+
+/*
+ * These are required parameters to use the search server.
+ *
+ * $site    The "index" as created by "Create a new indes"
+ *          in the OpenSearchServer administrative interface.
+ * $login   Login for access to the API as created under "Privileges"
+ *          in the OpenSearchServer administrative interface.
+ *          Use 'WebsiteServices' for all sites. (Sites are
+ *          separated by "index".)
+ * $key     API Key created along with login. The key below
+ *          is for use with all sites.
+ *
+ * These parameters should normally be specified in the
+ * config/application.ini file as follows.
+ *
+ * glmsearch.site = "demo.gaslightmedia.com"
+ * glmsearch.login = "WebsiteServices"
+ * glmsearch.key = "3cd270eda427d55874aafa45919f7026"
+ *
+ */
+$index = 'Index_1';
+$site = 'www.wmta.org';
+$login = 'WebsiteServices';
+$key = '829800701e8440b67a78e3afbefa1049';
+
+
+$debug = true;          // Tell the glmSearch class whether you want debug output.
+$filter = true;         // Tell the glmSearch class whether to use $site as a host filter.
+
+/*
+ * Load and instantiate search class
+ *
+ * The file included is normally '/var/www/server/CommonApps/GLMSearch/V1.1/glmSearch.inc'.
+ *
+ * $debug is optional.
+ */
+require('../glmSearch.inc');
+$glmSearch = new glmSearch($site, $login, $key, $debug, $index, $filter);
+
+/*
+ * This will turn on the Smarty console for GLMSearch.
+ * The Smarty console will show in a separate window and
+ * should contain all parameters available to the template.
+ */
+// $glmSearch->smartyConsole = true;
+
+/*
+ * Here's the easy way using the default template.
+ */
+$searchPage = $glmSearch->doSearch();
+
+// Display the produced page
+echo $searchPage;
+
+exit;
+
+
+
+/* The hard way to do all this.
+ * The easy way is to use the doSearch() method shown above.
+
+// Check if we have a query string
+if (trim($_REQUEST['query']) != '') {
+
+    // Check for match all terms
+    $operator = 'OR';
+    if ($_REQUEST['matchAll'] != '') {
+        $operator = 'AND';
+    }
+
+    //echo "Performing search...<br>";
+    $r = $glmSearch->search($_REQUEST['query'], $operator);
+    if ($r == false) {
+        echo $glmSearch->errorMessage;
+        exit;
+    }
+    //echo "<pre>".$r."</pre>";
+
+    //echo "Converting raw results to array...<br>";
+    $r = $glmSearch->results2array();
+    if ($r == false) {
+        echo $glmSearch->errorMessage;
+        exit;
+    }
+    //echo "<pre>".print_r($r,1)."</pre>";
+
+    //echo "Compressing results into better organized array...<br>";
+    $r = $glmSearch->compressResults();
+    if ($r == false) {
+        echo $glmSearch->errorMessage;
+        exit;
+    }
+    //echo "<pre>".print_r($r,1)."</pre>";
+
+} // if have a query
+
+//echo "Rendering results with Smarty...<br>";
+$page = $glmSearch->render();
+if ($page == false) {
+    echo $glmSearch->errorMessage;
+    exit;
+}
+
+echo "<html><body>$page</body></html>";
+
+*/
+
+
+?>
\ No newline at end of file