├── cache
└── index.php
├── alma_hours_widget.css
├── LICENSE
├── alma_hours_widget.js
├── readme.md
└── alma_hours_widget.php
/cache/index.php:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/alma_hours_widget.css:
--------------------------------------------------------------------------------
1 | .alma_hours_widget {display:none; float:left; border-top-left-radius: 5px; border-top-right-radius: 5px;}
2 | .alma_hours_widget_title {background-color:darkred; color:white; text-align:center; padding:10px; font-size:24px; border-top-left-radius: 5px; border-top-right-radius: 5px;}
3 | .alma_hours_list {list-style-type: none; padding:0; margin:0;}
4 | .alma_hours_row {background-color:brown; color:white; padding:4px 10px; margin:1px 0;}
5 | .alma_hours_row_date {margin-right:10px;}
6 | .alma_hours_row_open {margin-right:5px;}
7 | .alma_hours_row_close {margin-left:5px;}
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2015 Portland State University Library
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
23 |
--------------------------------------------------------------------------------
/alma_hours_widget.js:
--------------------------------------------------------------------------------
1 | /* ALMA HOURS WIDGET */
2 |
3 | /* requires jQuery library */
4 |
5 | var script_path = "alma_hours_widget.php";
6 |
7 | jQuery(document).ready(function(){
8 | // load all widgets
9 | jQuery(".alma_hours_widget").each(function(){
10 |
11 | // extract html5 parameters for widgets
12 | var input_library = jQuery(this).attr("data-library");
13 | var input_title = jQuery(this).attr("data-title");
14 | var input_start_date = jQuery(this).attr("data-start-date");
15 | var input_end_date = jQuery(this).attr("data-end-date");
16 | var input_date_format = jQuery(this).attr("data-date-format");
17 | var input_time_format = jQuery(this).attr("data-time-format");
18 | var widget = $(this);
19 |
20 | // console.log(" | " + input_library + " | " + input_start_date + " | " + input_end_date + " | " + input_date_format + " | " + input_time_format);
21 |
22 | // load hours
23 | $.getJSON( script_path, { library: input_library, from: input_start_date, to: input_end_date, date_format: input_date_format, time_format: input_time_format } )
24 | .done(function( json ) {
25 | var widget_days = [];
26 | $.each(json,function(date,day) {
27 | if(day.closed)
28 | widget_days.push( "
").show();
44 | })
45 | .fail(function( jqxhr, textStatus, error ) {
46 | var err = textStatus + ", " + error;
47 | console.log( "Request Failed: " + err );
48 | });
49 | });
50 | });
51 |
52 |
--------------------------------------------------------------------------------
/readme.md:
--------------------------------------------------------------------------------
1 | # Alma Hours Widget
2 |
3 | ## Description
4 | This application uses the Ex Libris Alma Hours API to create a dynamic HTML hours widget to be used on external websites to display a library's upcoming hours. Users simply have include the JavaScript and CSS files and add a placeholder DIV tag where they want their library's hours to display and the application will handle all the commuication with the Alma API, formatting of the results and generation of the HTML output via a dynamic AJAX request.
5 |
6 | ## Configuration
7 | ### Create an Alma Hours API Key
8 | You will need to go to the Alma Developer Network and create an Application. The Application Name can be anything (For example: Alma Hours Widget). The Platfrom should be "Web application". Under the API Management tab, add the Configuration API with read-only access. Once you have added the application, an API Key will be created. Enter this API Key in the alma_hours_widget.php file in the configuration section at the top of the file:
9 | ```php
10 | // alma_hours_widget.php
11 | // set your Alma Hours API Key - Replace XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX with your Alma API Key
12 | define("ALMA_HOURS_API_KEY","XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX");
13 | ```
14 |
15 | ### Caching (recommended)
16 | Without caching, the Alma API would need to be queried every time the widget is displayed. This can put a heavy and unneccessary load on the API server. This his application uses disk based caching to update the hours for each unique API request to a static file once per day by default. The CACHE_FREQUENCY setting can be changed from "Daily" to "Hourly" or "None"
17 | ```php
18 | // alma_hours_widget.php
19 | // set the Caching Frequency - Daily, Hourly or None (default: Daily)
20 | define("CACHE_FREQUENCY","Daily");
21 | ```
22 | *For caching to function correctly, the "cache" folder must have write-access enabled.*
23 |
24 | ### Cross-Site Script Access (optional)
25 | If you will be including your hours widget on a site other than the location where the alma_hours_widget.php file will be hosted, then you will need to enable XSS access. Simply add the list of domains where you will be displaying the hours widget in the $allowed_domains array in the alma_hours_widget.php in the configuration section at the top of the file:
26 | ```php
27 | // alma_hours_widget.php
28 | // example setting for allowing cross-site scripting (XSS)
29 | $allowed_domains = array("http://www.allowed-website.edu","https://secure.allowed-website.edu");
30 | ```
31 |
32 | ## CSS
33 | CSS can be used to completely change the styles of the widget design. Every part of the widget has a relevant class that can be targeted with CSS. The default stylesheet alma_hours_widget.css can be used as a starting point for your widget's design.
34 | ```html
35 |
36 | ```
37 |
38 | ## JS
39 | Creates the widget using AJAX to query the API script
40 | ```html
41 |
42 | ```
43 | ### jQuery
44 | The Alma Hours Widget requires jQuery to be loaded on the page where the widget is to be displayed.
45 |
46 | ## PHP
47 | A PHP script is used to query the REST API interface, cleanup/format the output and feedback the results as JSON. Caching can also be easily added at this layer to speed up loading time and reduce API requests to Ex Libris.
48 |
49 | ## HTML
50 | Each widget is added by adding a DIV tag with the class "alma_hours_widget".
51 |
52 |
53 | ### Basic Widget (displays next 7 days of hours):
54 | ```html
55 |
56 | ```
57 | - The **data-library** and **data-title** attributes are required attributes.
58 |
59 | ### data-library
60 | The value for data-library can be found in Alma by navigating to the Fulfillment Configuration - Configuration Menu. In the "You are configuring:" dropdown menu, select the library for which you would like to create an Hours Widget. Then select "Opening Hours" under Library. Select the "Summary" tab to reveal the library's "Code". The value for the Library Code should be used for the data-library attribute to create a widget for that library.
61 |
62 | ### Full Usage Example:
63 | ```html
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 | ```
76 |
77 |
78 | ### Optional HTML5 Attributes:
79 | - **data-start-date** – Used to set the start date for the widget
80 | - **data-end-date** – Used to set the end date for the widget
81 | - **data-date-format** – PHP standard date format options (e.g. "m/d/Y", "m/d/y", "m-d-y", etc…)
82 | - **data-time-format** – PHP standard time format options (e.g. "g:ia", "H:i:s", etc…)
83 |
84 | These optional HTML5 attributes may be added to the DIV tag placeholder as seen in the following examples:
85 |
86 | ### Custom Time/Date Formats:
87 | ```html
88 |
89 | ```
90 |
91 |
92 | ### Custom Date Range:
93 | ```html
94 |
95 | ```
96 |
--------------------------------------------------------------------------------
/alma_hours_widget.php:
--------------------------------------------------------------------------------
1 | \n");
34 | exit();
35 | }
36 |
37 | // OPTIONAL PARAMETERS
38 | if(isset($_GET['date_format']))
39 | $date_format = $_GET['date_format'];
40 | else
41 | $date_format = "m/d/Y";
42 |
43 | if(isset($_GET['time_format']))
44 | $time_format = $_GET['time_format'];
45 | else
46 | $time_format = "g:ia";
47 |
48 | if(isset($_GET['from']))
49 | $from = date("Y-m-d",strtotime("+1 day",strtotime($_GET['from'])));
50 | else
51 | $from = date("Y-m-d",strtotime("+1 day"));
52 |
53 | if(isset($_GET['to']))
54 | $to = date("Y-m-d",strtotime("+1 day",strtotime($_GET['to']))); // need to increase by one day, because Alma hours API is not inclusive of range
55 | else
56 | $to = date("Y-m-d",strtotime("+7 days"));
57 |
58 |
59 | // each date must be queried by itself to work-around an issue with the API returning invalid data for multi-day queries
60 | for($date = date("Y-m-d",strtotime($from)); strtotime($date) <= strtotime($to); $date = date("Y-m-d",strtotime("+1 day",strtotime($date))))
61 | {
62 | $xml_result = false;
63 |
64 | // BUILD REST REQUEST URL
65 | $url = "https://api-ap.hosted.exlibrisgroup.com/almaws/v1/conf/libraries/".$library."/open-hours?apikey=".ALMA_HOURS_API_KEY;
66 | if(strcmp($from,''))
67 | $url .= "&from=".$date;
68 | if(strcmp($to,''))
69 | $url .= "&to=".$date;
70 |
71 | if(isset($_GET['debug']))
72 | print("URL: $url \n");
73 |
74 | if(strcmp(CACHE_FREQUENCY,"None"))
75 | {
76 | // check cache for hours
77 | if(file_exists("cache/".$library."_".$date.".xml"))
78 | {
79 | // check last modified datestamp
80 | $cache_expired = false;
81 | switch(CACHE_FREQUENCY)
82 | {
83 | case 'Hourly': if(filemtime("cache/".$library."_".$date.".xml") < strtotime(date("Y-m-d H:00:00",strtotime("now")))) $cache_expired = true;
84 | default: if(filemtime("cache/".$library."_".$date.".xml") < strtotime(date("Y-m-d 00:00:00",strtotime("now")))) $cache_expired = true;
85 | }
86 | // $cache_expired = true;
87 | if(!$cache_expired)
88 | {
89 | $xml_result = simplexml_load_file("cache/".$library."_".$date.".xml");
90 | if(isset($_GET['debug'])) print("loaded data from cache file: cache/".$library."_".$date.".xml \n");
91 | }
92 | }
93 | }
94 |
95 | // if no cache data available, query the Alma API
96 | if(!$xml_result)
97 | {
98 | // use curl to make the API request
99 | curl_setopt($ch,CURLOPT_URL, $url);
100 | $result = curl_exec($ch);
101 |
102 | if(isset($_GET['debug']))
103 | {
104 | print("xml result from API \n");
105 | print("