Compare commits

..

42 Commits

Author SHA1 Message Date
Paul Pound adac1fca75 remove non upei guest links for off campus users 4 weeks ago
Paul Pound 3c6a627b10 updated body substring code 7 months ago
Paul Pound 222a8f83d0 updated eds js files to get profile from drupal settings 9 months ago
Paul Pound d965873e4c enclose bestbet searches in quotes if it isnt already 10 months ago
Paul Pound a5202d3719 limit bestbet searchs to title_1 field 10 months ago
Paul Pound 29d6951b42 add encoding for eds articles query string 1 year ago
Paul Pound f01db8fe1e adding no cache to the search route 1 year ago
Paul Pound 6145608666 better query checking before redirect 1 year ago
Paul Pound 9a8ac932a1 removed vim command string 1 year ago
Paul Pound 48ec54f7ee no block caching for anonymous 1 year ago
Paul Pound 32166bdddd use link field title instead of node title for bestbet results 1 year ago
Paul Pound 2757e95490 fix link to all solr results when query in quotes 1 year ago
Paul Pound d76a9d875a less encoding decoding 1 year ago
Paul Pound 629ab184dc match the d7 versions search results by not escapting brackets 1 year ago
Paul Pound 0b52c19cd3 no guest access 1 year ago
Paul Pound 3dd4c3f665 hide the bestbet bento if there are no results 2 years ago
Paul Pound d8405b0b83 fixed a double quote typo in twig template 2 years ago
Paul Pound c4318e1f90 added some divs with classes to mimic old site 2 years ago
Paul Pound 3a1a8db0ff add alternate path for use case of users embedding form elements directly in pages 2 years ago
ppound f702f1bed2 updates to solr results for drupal10 2 years ago
ppound abc328ebd9 leave block caching at default for now 2 years ago
ppound df0438b164 disabled the block caching 2 years ago
ppound d4aad3318f updates for drupal 10 2 years ago
ppound 57ba9f413c corrected settings name 3 years ago
ppound 59b5d8657d added composer json file 3 years ago
ppound 752fbaaa04 eliminate bestbet content from general searches 3 years ago
ppound 751b2691a3 added solr bestbet bento box 3 years ago
ppound 8aa0fb4239 added readme 3 years ago
ppound 39f1e34384 added configs required for messages 3 years ago
ppound 84d67b1095 fix issues that occured on deployment to test server mostly current path related 3 years ago
ppound f94c4fbc1e bento solr site now returns results to the block 3 years ago
ppound efd1161717 solr site search module installs successfully and admin form works 3 years ago
ppound cc368749d7 EDS Articles block now works and code cleanup 3 years ago
ppound 4096f9808b tidied up comments in controller 3 years ago
ppound 2de44ce697 ebsco eds book block is now working results match the d7 version as well 3 years ago
ppound 1b8f5e8180 initial commit of ebsco php library files 3 years ago
ppound ee95dfff70 EDS target module can now be enabled and blocks and form display 3 years ago
ppound f24f3de869 start eds port port settings form info yml and routing yml 3 years ago
ppound ae2f7960ac added dependancy on the message module so we can log search requests 3 years ago
ppound 7ab0c77868 added themeing so search form can pass query to landing page of main module 3 years ago
ppound a59a9a7261 top level module now installs and can display search block 3 years ago
ppound f517b52050 removed the cufts target module cufts no longer exists 3 years ago
  1. 25
      composer.json
  2. 46
      config/optional/core.entity_form_display.message.roblib_search_message_template.default.yml
  3. 42
      config/optional/core.entity_view_display.message.roblib_search_message_template.default.yml
  4. 24
      config/optional/field.field.message.roblib_search_message_template.field_date_of_search.yml
  5. 19
      config/optional/field.field.message.roblib_search_message_template.field_ip_address.yml
  6. 19
      config/optional/field.field.message.roblib_search_message_template.field_search_string.yml
  7. 20
      config/optional/field.storage.message.field_date_of_search.yml
  8. 21
      config/optional/field.storage.message.field_ip_address.yml
  9. 19
      config/optional/field.storage.message.field_search_string.yml
  10. 14
      config/optional/message.template.roblib_search_message_template.yml
  11. 795
      config/optional/views.view.message.yml
  12. 0
      modules/Readme.txt
  13. 0
      modules/evergreen/css/roblib_search_evergreen.css
  14. 0
      modules/evergreen/js/evergreen_results.js
  15. 0
      modules/evergreen/roblib_search_evergreen.info
  16. 0
      modules/evergreen/roblib_search_evergreen.install
  17. 0
      modules/evergreen/roblib_search_evergreen.module
  18. 0
      modules/evergreen/theme/roblib-search-evergreen.tpl.php
  19. 0
      modules/evergreen/theme/theme.inc
  20. 0
      modules/islandscholar/css/roblib_search_islandscholar.css
  21. 0
      modules/islandscholar/js/islandscholar_results.js
  22. 0
      modules/islandscholar/roblib_search_islandscholar.info
  23. 0
      modules/islandscholar/roblib_search_islandscholar.install
  24. 0
      modules/islandscholar/roblib_search_islandscholar.module
  25. 0
      modules/islandscholar/theme/roblib-search-islandscholar.tpl.php
  26. 0
      modules/islandscholar/theme/theme.inc
  27. 0
      modules/passthru_results/css/roblib_search_passthru.css
  28. 0
      modules/passthru_results/js/passthru_results.js
  29. 0
      modules/passthru_results/roblib_search_passthru.info
  30. 0
      modules/passthru_results/roblib_search_passthru.install
  31. 0
      modules/passthru_results/roblib_search_passthru.module
  32. 0
      modules/passthru_results/theme/roblib-search-passthru.tpl.php
  33. 0
      modules/passthru_results/theme/theme.inc
  34. 0
      modules/roblib_search_eds/css/roblib_search_eds.css
  35. 89
      modules/roblib_search_eds/js/eds_results_article.js
  36. 112
      modules/roblib_search_eds/js/eds_results_book.js
  37. 8
      modules/roblib_search_eds/roblib_search_eds.info.yml
  38. 19
      modules/roblib_search_eds/roblib_search_eds.libraries.yml
  39. 43
      modules/roblib_search_eds/roblib_search_eds.module
  40. 25
      modules/roblib_search_eds/roblib_search_eds.routing.yml
  41. 117
      modules/roblib_search_eds/src/Controller/RoblibSearchEdsController.php
  42. 146
      modules/roblib_search_eds/src/Form/EdsSettingsForm.php
  43. 822
      modules/roblib_search_eds/src/Lib/EBSCOAPI.php
  44. 580
      modules/roblib_search_eds/src/Lib/EBSCOConnector.php
  45. 1050
      modules/roblib_search_eds/src/Lib/EBSCODocument.php
  46. 528
      modules/roblib_search_eds/src/Lib/EBSCORecord.php
  47. 1056
      modules/roblib_search_eds/src/Lib/EBSCOResponse.php
  48. 14
      modules/roblib_search_eds/src/Lib/RoblibEBSCOAPI.php
  49. 446
      modules/roblib_search_eds/src/Lib/sanitizer.class.php
  50. 53
      modules/roblib_search_eds/src/Plugin/Block/RoblibSearchEdsArticles.php
  51. 54
      modules/roblib_search_eds/src/Plugin/Block/RoblibSearchEdsBooks.php
  52. 12
      modules/roblib_search_eds/templates/roblib-search-eds-articles.html.twig
  53. 13
      modules/roblib_search_eds/templates/roblib-search-eds-books.html.twig
  54. 38
      modules/solr_site/README.md
  55. 0
      modules/solr_site/css/roblib_search_solr_site.css
  56. 35
      modules/solr_site/js/solr_site_bestbet.js
  57. 0
      modules/solr_site/js/solr_site_databases.js
  58. 0
      modules/solr_site/js/solr_site_guides.js
  59. 0
      modules/solr_site/js/solr_site_reserves.js
  60. 44
      modules/solr_site/js/solr_site_results.js
  61. 8
      modules/solr_site/roblib_search_solr_site.info.yml
  62. 15
      modules/solr_site/roblib_search_solr_site.libraries.yml
  63. 100
      modules/solr_site/roblib_search_solr_site.module
  64. 24
      modules/solr_site/roblib_search_solr_site.routing.yml
  65. 124
      modules/solr_site/src/Controller/RoblibSearchSolrsiteController.php
  66. 67
      modules/solr_site/src/Form/SolrsiteSettingsForm.php
  67. 51
      modules/solr_site/src/Plugin/Block/RoblibSearchSolrsiteBestbet.php
  68. 53
      modules/solr_site/src/Plugin/Block/RoblibSearchSolrsiteGeneral.php
  69. 10
      modules/solr_site/templates/roblib-search-solr-site-bestbet.html.twig
  70. 10
      modules/solr_site/templates/roblib-search-solr-site-results.html.twig
  71. 9
      roblib_search.info
  72. 10
      roblib_search.info.yml
  73. 44
      roblib_search.install
  74. 339
      roblib_search.module
  75. 18
      roblib_search.routing.yml
  76. 39
      src/Controller/RoblibSearchController.php
  77. 80
      src/Form/RoblibSearchForm.php
  78. 57
      src/Form/RoblibSearchSettingsForm.php
  79. 26
      src/Plugin/Block/RoblibSearchBoxBlock.php
  80. 39
      src/Plugin/Block/RoblibSearchOtherSourcesBlock.php
  81. 12
      targets/cufts/css/roblib_search_cufts.base.css
  82. 61
      targets/cufts/js/cufts_results.js
  83. 8
      targets/cufts/roblib_search_cufts.info
  84. 2
      targets/cufts/roblib_search_cufts.install
  85. 203
      targets/cufts/roblib_search_cufts.module
  86. 12
      targets/cufts/theme/roblib-search-cufts.tpl.php
  87. 28
      targets/cufts/theme/theme.inc
  88. 108
      targets/eds/js/eds_results.js
  89. 85
      targets/eds/js/eds_results_article.js
  90. 10
      targets/eds/roblib_search_eds.info
  91. 2
      targets/eds/roblib_search_eds.install
  92. 365
      targets/eds/roblib_search_eds.module
  93. 35
      targets/eds/theme/roblib-search-eds-articles.tpl.php
  94. 58
      targets/eds/theme/theme.inc
  95. 37
      targets/solr_site/js/solr_site_bestbet.js
  96. 47
      targets/solr_site/js/solr_site_results.js
  97. 8
      targets/solr_site/roblib_search_solr_site.info
  98. 2
      targets/solr_site/roblib_search_solr_site.install
  99. 383
      targets/solr_site/roblib_search_solr_site.module
  100. 24
      targets/solr_site/theme/roblib-search-solr-site-results.tpl.php
  101. Some files were not shown because too many files have changed in this diff Show More

25
composer.json

@ -0,0 +1,25 @@
{
"name": "roblib/roblib_search",
"description": "Searches various enpoints and displays results from each endpoint.",
"type": "drupal-module",
"license": "GPL-2.0-or-later",
"homepage": "https://git.library.upei.ca/Code/upei_roblib_search",
"authors": [
{
"name": "Paul Pound",
"role": "Maintainer"
}
],
"support": {
"issues": "https://git.library.upei.ca/Code/upei_roblib_search/issues",
"source": "https://git.library.upei.ca/Code/upei_roblib_search"
},
"repositories": [
{
"type": "git",
"url": "git@git.library.upei.ca:Code/upei_roblib_search.git",
"reference": "2.x"
}
],
"require": { }
}

46
config/optional/core.entity_form_display.message.roblib_search_message_template.default.yml

@ -0,0 +1,46 @@
uuid: 96af51d7-c8b2-432f-b518-d9d5c1111d16
langcode: en
status: true
dependencies:
config:
- field.field.message.roblib_search_message_template.field_date_of_search
- field.field.message.roblib_search_message_template.field_ip_address
- field.field.message.roblib_search_message_template.field_search_string
- message.template.roblib_search_message_template
module:
- datetime
- field_layout
- layout_discovery
third_party_settings:
field_layout:
id: layout_onecol
settings:
label: ''
id: message.roblib_search_message_template.default
targetEntityType: message
bundle: roblib_search_message_template
mode: default
content:
field_date_of_search:
weight: 2
settings: { }
third_party_settings: { }
type: datetime_default
region: content
field_ip_address:
weight: 0
settings:
size: 60
placeholder: ''
third_party_settings: { }
type: string_textfield
region: content
field_search_string:
weight: 1
settings:
rows: 5
placeholder: ''
third_party_settings: { }
type: string_textarea
region: content
hidden: { }

42
config/optional/core.entity_view_display.message.roblib_search_message_template.default.yml

@ -0,0 +1,42 @@
uuid: 5f78d121-62f6-42c2-ba67-428f8e6e3697
langcode: en
status: true
dependencies:
config:
- field.field.message.roblib_search_message_template.field_date_of_search
- field.field.message.roblib_search_message_template.field_ip_address
- field.field.message.roblib_search_message_template.field_search_string
- message.template.roblib_search_message_template
module:
- datetime
id: message.roblib_search_message_template.default
targetEntityType: message
bundle: roblib_search_message_template
mode: default
content:
field_date_of_search:
weight: 2
label: above
settings:
format_type: medium
timezone_override: ''
third_party_settings: { }
type: datetime_default
region: content
field_ip_address:
weight: 0
label: above
settings:
link_to_entity: false
third_party_settings: { }
type: string
region: content
field_search_string:
weight: 1
label: above
settings: { }
third_party_settings: { }
type: basic_string
region: content
hidden:
search_api_excerpt: true

24
config/optional/field.field.message.roblib_search_message_template.field_date_of_search.yml

@ -0,0 +1,24 @@
uuid: b24b3a7d-7879-4537-aa99-a91c7671c878
langcode: en
status: true
dependencies:
config:
- field.storage.message.field_date_of_search
- message.template.roblib_search_message_template
module:
- datetime
id: message.roblib_search_message_template.field_date_of_search
field_name: field_date_of_search
entity_type: message
bundle: roblib_search_message_template
label: 'Date of Search'
description: ''
required: false
translatable: false
default_value:
-
default_date_type: now
default_date: now
default_value_callback: ''
settings: { }
field_type: datetime

19
config/optional/field.field.message.roblib_search_message_template.field_ip_address.yml

@ -0,0 +1,19 @@
uuid: 4c6bd727-b776-4d9d-bd85-0604717ae9f9
langcode: en
status: true
dependencies:
config:
- field.storage.message.field_ip_address
- message.template.roblib_search_message_template
id: message.roblib_search_message_template.field_ip_address
field_name: field_ip_address
entity_type: message
bundle: roblib_search_message_template
label: 'IP Address'
description: ''
required: false
translatable: false
default_value: { }
default_value_callback: ''
settings: { }
field_type: string

19
config/optional/field.field.message.roblib_search_message_template.field_search_string.yml

@ -0,0 +1,19 @@
uuid: 13fa3cff-6623-4c65-a972-d4be109c8a29
langcode: en
status: true
dependencies:
config:
- field.storage.message.field_search_string
- message.template.roblib_search_message_template
id: message.roblib_search_message_template.field_search_string
field_name: field_search_string
entity_type: message
bundle: roblib_search_message_template
label: 'Search String'
description: ''
required: false
translatable: false
default_value: { }
default_value_callback: ''
settings: { }
field_type: string_long

20
config/optional/field.storage.message.field_date_of_search.yml

@ -0,0 +1,20 @@
uuid: e74ffe34-45e7-4c65-aed6-62bfef0137a6
langcode: en
status: true
dependencies:
module:
- datetime
- message
id: message.field_date_of_search
field_name: field_date_of_search
entity_type: message
type: datetime
settings:
datetime_type: datetime
module: datetime
locked: false
cardinality: 1
translatable: true
indexes: { }
persist_with_no_fields: false
custom_storage: false

21
config/optional/field.storage.message.field_ip_address.yml

@ -0,0 +1,21 @@
uuid: dbe56ed6-2949-420b-b8fe-0875c3e74871
langcode: en
status: true
dependencies:
module:
- message
id: message.field_ip_address
field_name: field_ip_address
entity_type: message
type: string
settings:
max_length: 255
is_ascii: false
case_sensitive: false
module: core
locked: false
cardinality: 1
translatable: true
indexes: { }
persist_with_no_fields: false
custom_storage: false

19
config/optional/field.storage.message.field_search_string.yml

@ -0,0 +1,19 @@
uuid: e53387c2-b1a3-4149-9106-2039bc3b50ed
langcode: en
status: true
dependencies:
module:
- message
id: message.field_search_string
field_name: field_search_string
entity_type: message
type: string_long
settings:
case_sensitive: false
module: core
locked: false
cardinality: 1
translatable: true
indexes: { }
persist_with_no_fields: false
custom_storage: false

14
config/optional/message.template.roblib_search_message_template.yml

@ -0,0 +1,14 @@
uuid: e179cbc1-4268-4fe4-abce-fc64cccbc1a2
langcode: en
status: true
dependencies: { }
template: roblib_search_message_template
label: 'Roblib Search Message Template'
description: 'Log messages for the Roblib Search module'
text: { }
settings:
'token options':
clear: false
'token replace': true
purge_override: false
purge_methods: { }

795
config/optional/views.view.message.yml

@ -0,0 +1,795 @@
uuid: 746ddbc4-4082-4754-bf00-dd6fe24048d5
langcode: en
status: true
dependencies:
config:
- field.storage.message.field_date_of_search
- field.storage.message.field_ip_address
- field.storage.message.field_search_string
module:
- datetime
- message
- user
_core:
default_config_hash: 2Up5NUvwF4aBVoO6eFTPeBXtnpUw_yiexv9I5u6ZD-g
id: message
label: Message
module: views
description: ''
tag: ''
base_table: message_field_data
base_field: mid
display:
default:
display_plugin: default
id: default
display_title: Master
position: 0
display_options:
access:
type: perm
options:
perm: 'overview messages'
cache:
type: none
options: { }
query:
type: views_query
options:
disable_sql_rewrite: false
distinct: false
replica: false
query_comment: ''
query_tags: { }
exposed_form:
type: basic
options:
submit_button: Apply
reset_button: false
reset_button_label: Reset
exposed_sorts_label: 'Sort by'
expose_sort_order: true
sort_asc_label: Asc
sort_desc_label: Desc
pager:
type: full
options:
items_per_page: 25
offset: 0
id: 0
total_pages: null
expose:
items_per_page: false
items_per_page_label: 'Items per page'
items_per_page_options: '5, 10, 25, 50'
items_per_page_options_all: false
items_per_page_options_all_label: '- All -'
offset: false
offset_label: Offset
tags:
previous: '‹ previous'
next: 'next ›'
first: '« first'
last: 'last »'
quantity: 9
style:
type: table
options:
grouping: { }
row_class: ''
default_row_class: true
override: true
sticky: false
caption: ''
summary: ''
description: ''
columns:
message_bulk_form_1: message_bulk_form_1
mid: mid
template: template
get_text: get_text
uid: uid
created: created
info:
message_bulk_form_1:
align: ''
separator: ''
empty_column: false
responsive: ''
mid:
sortable: true
default_sort_order: desc
align: ''
separator: ''
empty_column: false
responsive: ''
template:
sortable: true
default_sort_order: asc
align: ''
separator: ''
empty_column: false
responsive: priority-medium
get_text:
sortable: false
default_sort_order: desc
align: ''
separator: ''
empty_column: false
responsive: ''
uid:
sortable: true
default_sort_order: asc
align: ''
separator: ''
empty_column: false
responsive: priority-medium
created:
sortable: true
default_sort_order: desc
align: ''
separator: ''
empty_column: false
responsive: priority-low
default: mid
empty_table: false
row:
type: fields
fields:
message_bulk_form_1:
id: message_bulk_form_1
table: message
field: message_bulk_form
relationship: none
group_type: group
admin_label: ''
label: 'Message operations bulk form'
exclude: false
alter:
alter_text: false
text: ''
make_link: false
path: ''
absolute: false
external: false
replace_spaces: false
path_case: none
trim_whitespace: false
alt: ''
rel: ''
link_class: ''
prefix: ''
suffix: ''
target: ''
nl2br: false
max_length: 0
word_boundary: true
ellipsis: true
more_link: false
more_link_text: ''
more_link_path: ''
strip_tags: false
trim: false
preserve_tags: ''
html: false
element_type: ''
element_class: ''
element_label_type: ''
element_label_class: ''
element_label_colon: true
element_wrapper_type: ''
element_wrapper_class: ''
element_default_classes: true
empty: ''
hide_empty: false
empty_zero: false
hide_alter_empty: true
action_title: 'With selection'
include_exclude: include
selected_actions:
- message_delete_action
entity_type: message
plugin_id: bulk_form
mid:
id: mid
table: message_field_data
field: mid
relationship: none
group_type: group
admin_label: ''
label: 'Message ID'
exclude: false
alter:
alter_text: false
text: ''
make_link: false
path: ''
absolute: false
external: false
replace_spaces: false
path_case: none
trim_whitespace: false
alt: ''
rel: ''
link_class: ''
prefix: ''
suffix: ''
target: ''
nl2br: false
max_length: 0
word_boundary: true
ellipsis: true
more_link: false
more_link_text: ''
more_link_path: ''
strip_tags: false
trim: false
preserve_tags: ''
html: false
element_type: ''
element_class: ''
element_label_type: ''
element_label_class: ''
element_label_colon: true
element_wrapper_type: ''
element_wrapper_class: ''
element_default_classes: true
empty: ''
hide_empty: false
empty_zero: false
hide_alter_empty: true
click_sort_column: value
type: number_integer
settings:
thousand_separator: ''
prefix_suffix: true
group_column: value
group_columns: { }
group_rows: true
delta_limit: 0
delta_offset: 0
delta_reversed: false
delta_first_last: false
multi_type: separator
separator: ', '
field_api_classes: false
entity_type: null
entity_field: mid
plugin_id: field
template:
id: template
table: message_field_data
field: template
relationship: none
group_type: group
admin_label: ''
label: 'Message template'
exclude: false
alter:
alter_text: false
text: ''
make_link: false
path: ''
absolute: false
external: false
replace_spaces: false
path_case: none
trim_whitespace: false
alt: ''
rel: ''
link_class: ''
prefix: ''
suffix: ''
target: ''
nl2br: false
max_length: 0
word_boundary: true
ellipsis: true
more_link: false
more_link_text: ''
more_link_path: ''
strip_tags: false
trim: false
preserve_tags: ''
html: false
element_type: ''
element_class: ''
element_label_type: ''
element_label_class: ''
element_label_colon: false
element_wrapper_type: ''
element_wrapper_class: ''
element_default_classes: true
empty: ''
hide_empty: false
empty_zero: false
hide_alter_empty: true
click_sort_column: target_id
type: entity_reference_label
settings:
link: true
group_column: target_id
group_columns: { }
group_rows: true
delta_limit: 0
delta_offset: 0
delta_reversed: false
delta_first_last: false
multi_type: separator
separator: ', '
field_api_classes: false
entity_type: message
entity_field: template
plugin_id: field
get_text:
id: get_text
table: message
field: get_text
relationship: none
group_type: group
admin_label: ''
label: 'Message text'
exclude: false
alter:
alter_text: false
text: ''
make_link: false
path: ''
absolute: false
external: false
replace_spaces: false
path_case: none
trim_whitespace: false
alt: ''
rel: ''
link_class: ''
prefix: ''
suffix: ''
target: ''
nl2br: false
max_length: 500
word_boundary: true
ellipsis: false
more_link: false
more_link_text: ''
more_link_path: ''
strip_tags: false
trim: false
preserve_tags: ''
html: true
element_type: ''
element_class: ''
element_label_type: ''
element_label_class: ''
element_label_colon: true
element_wrapper_type: ''
element_wrapper_class: ''
element_default_classes: true
empty: ''
hide_empty: false
empty_zero: false
hide_alter_empty: true
entity_type: message
plugin_id: get_text
uid:
id: uid
table: message_field_data
field: uid
relationship: none
group_type: group
admin_label: ''
label: Author
exclude: false
alter:
alter_text: false
text: ''
make_link: false
path: ''
absolute: false
external: false
replace_spaces: false
path_case: none
trim_whitespace: false
alt: ''
rel: ''
link_class: ''
prefix: ''
suffix: ''
target: ''
nl2br: false
max_length: 0
word_boundary: true
ellipsis: true
more_link: false
more_link_text: ''
more_link_path: ''
strip_tags: false
trim: false
preserve_tags: ''
html: false
element_type: ''
element_class: ''
element_label_type: ''
element_label_class: ''
element_label_colon: false
element_wrapper_type: ''
element_wrapper_class: ''
element_default_classes: true
empty: ''
hide_empty: false
empty_zero: false
hide_alter_empty: true
click_sort_column: target_id
type: entity_reference_label
settings:
link: true
group_column: target_id
group_columns: { }
group_rows: true
delta_limit: 0
delta_offset: 0
delta_reversed: false
delta_first_last: false
multi_type: separator
separator: ', '
field_api_classes: false
entity_type: message
entity_field: uid
plugin_id: field
created:
id: created
table: message_field_data
field: created
relationship: none
group_type: group
admin_label: ''
label: 'Published date'
exclude: false
alter:
alter_text: false
text: ''
make_link: false
path: ''
absolute: false
external: false
replace_spaces: false
path_case: none
trim_whitespace: false
alt: ''
rel: ''
link_class: ''
prefix: ''
suffix: ''
target: ''
nl2br: false
max_length: 0
word_boundary: true
ellipsis: true
more_link: false
more_link_text: ''
more_link_path: ''
strip_tags: false
trim: false
preserve_tags: ''
html: false
element_type: ''
element_class: ''
element_label_type: ''
element_label_class: ''
element_label_colon: false
element_wrapper_type: ''
element_wrapper_class: ''
element_default_classes: true
empty: ''
hide_empty: false
empty_zero: false
hide_alter_empty: true
date_format: fallback
custom_date_format: ''
timezone: ''
entity_type: message
entity_field: created
plugin_id: date
field_date_of_search:
id: field_date_of_search
table: message__field_date_of_search
field: field_date_of_search
relationship: none
group_type: group
admin_label: ''
label: 'Date of Search'
exclude: false
alter:
alter_text: false
text: ''
make_link: false
path: ''
absolute: false
external: false
replace_spaces: false
path_case: none
trim_whitespace: false
alt: ''
rel: ''
link_class: ''
prefix: ''
suffix: ''
target: ''
nl2br: false
max_length: 0
word_boundary: true
ellipsis: true
more_link: false
more_link_text: ''
more_link_path: ''
strip_tags: false
trim: false
preserve_tags: ''
html: false
element_type: ''
element_class: ''
element_label_type: ''
element_label_class: ''
element_label_colon: true
element_wrapper_type: ''
element_wrapper_class: ''
element_default_classes: true
empty: ''
hide_empty: false
empty_zero: false
hide_alter_empty: true
click_sort_column: value
type: datetime_default
settings:
timezone_override: ''
format_type: medium
group_column: value
group_columns: { }
group_rows: true
delta_limit: 0
delta_offset: 0
delta_reversed: false
delta_first_last: false
multi_type: separator
separator: ', '
field_api_classes: false
plugin_id: field
field_ip_address:
id: field_ip_address
table: message__field_ip_address
field: field_ip_address
relationship: none
group_type: group
admin_label: ''
label: 'IP Address'
exclude: false
alter:
alter_text: false
text: ''
make_link: false
path: ''
absolute: false
external: false
replace_spaces: false
path_case: none
trim_whitespace: false
alt: ''
rel: ''
link_class: ''
prefix: ''
suffix: ''
target: ''
nl2br: false
max_length: 0
word_boundary: true
ellipsis: true
more_link: false
more_link_text: ''
more_link_path: ''
strip_tags: false
trim: false
preserve_tags: ''
html: false
element_type: ''
element_class: ''
element_label_type: ''
element_label_class: ''
element_label_colon: true
element_wrapper_type: ''
element_wrapper_class: ''
element_default_classes: true
empty: ''
hide_empty: false
empty_zero: false
hide_alter_empty: true
click_sort_column: value
type: string
settings: { }
group_column: value
group_columns: { }
group_rows: true
delta_limit: 0
delta_offset: 0
delta_reversed: false
delta_first_last: false
multi_type: separator
separator: ', '
field_api_classes: false
plugin_id: field
field_search_string:
id: field_search_string
table: message__field_search_string
field: field_search_string
relationship: none
group_type: group
admin_label: ''
label: 'Search String'
exclude: false
alter:
alter_text: false
text: ''
make_link: false
path: ''
absolute: false
external: false
replace_spaces: false
path_case: none
trim_whitespace: false
alt: ''
rel: ''
link_class: ''
prefix: ''
suffix: ''
target: ''
nl2br: false
max_length: 0
word_boundary: true
ellipsis: true
more_link: false
more_link_text: ''
more_link_path: ''
strip_tags: false
trim: false
preserve_tags: ''
html: false
element_type: ''
element_class: ''
element_label_type: ''
element_label_class: ''
element_label_colon: true
element_wrapper_type: ''
element_wrapper_class: ''
element_default_classes: true
empty: ''
hide_empty: false
empty_zero: false
hide_alter_empty: true
click_sort_column: value
type: basic_string
settings: { }
group_column: value
group_columns: { }
group_rows: true
delta_limit: 0
delta_offset: 0
delta_reversed: false
delta_first_last: false
multi_type: separator
separator: ', '
field_api_classes: false
plugin_id: field
filters:
template:
id: template
table: message_field_data
field: template
relationship: none
group_type: group
admin_label: ''
operator: in
value: { }
group: 1
exposed: true
expose:
operator_id: template_op
label: Template
description: ''
use_operator: false
operator: template_op
identifier: template
required: false
remember: false
multiple: false
remember_roles:
authenticated: authenticated
anonymous: '0'
administrator: '0'
reduce: false
operator_limit_selection: false
operator_list: { }
is_grouped: false
group_info:
label: ''
description: ''
identifier: ''
optional: true
widget: select
multiple: false
remember: false
default_group: All
default_group_multiple: { }
group_items: { }
entity_type: message
entity_field: template
plugin_id: bundle
sorts: { }
title: Message
header: { }
footer: { }
empty:
area:
id: area
table: views
field: area
relationship: none
group_type: group
admin_label: ''
empty: true
tokenize: false
content:
value: 'No messages created yet'
format: basic_html
plugin_id: text
relationships: { }
arguments: { }
display_extenders: { }
filter_groups:
operator: AND
groups: { }
cache_metadata:
contexts:
- 'languages:language_content'
- 'languages:language_interface'
- url
- url.query_args
- user.permissions
cacheable: false
max-age: 0
tags:
- 'config:field.storage.message.field_date_of_search'
- 'config:field.storage.message.field_ip_address'
- 'config:field.storage.message.field_search_string'
page_1:
display_plugin: page
id: page_1
display_title: Page
position: 1
display_options:
display_extenders: { }
path: admin/content/messages
menu:
type: tab
title: Message
description: ''
parent: system.admin_content
weight: 0
context: '0'
menu_name: admin
tab_options:
type: none
title: ''
description: ''
weight: 0
cache_metadata:
contexts:
- 'languages:language_content'
- 'languages:language_interface'
- url
- url.query_args
- user.permissions
cacheable: false
max-age: 0
tags:
- 'config:field.storage.message.field_date_of_search'
- 'config:field.storage.message.field_ip_address'
- 'config:field.storage.message.field_search_string'

0
targets/Readme.txt → modules/Readme.txt

0
targets/evergreen/css/roblib_search_evergreen.css → modules/evergreen/css/roblib_search_evergreen.css

0
targets/evergreen/js/evergreen_results.js → modules/evergreen/js/evergreen_results.js

0
targets/evergreen/roblib_search_evergreen.info → modules/evergreen/roblib_search_evergreen.info

0
targets/evergreen/roblib_search_evergreen.install → modules/evergreen/roblib_search_evergreen.install

0
targets/evergreen/roblib_search_evergreen.module → modules/evergreen/roblib_search_evergreen.module

0
targets/evergreen/theme/roblib-search-evergreen.tpl.php → modules/evergreen/theme/roblib-search-evergreen.tpl.php

0
targets/evergreen/theme/theme.inc → modules/evergreen/theme/theme.inc

0
targets/islandscholar/css/roblib_search_islandscholar.css → modules/islandscholar/css/roblib_search_islandscholar.css

0
targets/islandscholar/js/islandscholar_results.js → modules/islandscholar/js/islandscholar_results.js

0
targets/islandscholar/roblib_search_islandscholar.info → modules/islandscholar/roblib_search_islandscholar.info

0
targets/islandscholar/roblib_search_islandscholar.install → modules/islandscholar/roblib_search_islandscholar.install

0
targets/islandscholar/roblib_search_islandscholar.module → modules/islandscholar/roblib_search_islandscholar.module

0
targets/islandscholar/theme/roblib-search-islandscholar.tpl.php → modules/islandscholar/theme/roblib-search-islandscholar.tpl.php

0
targets/islandscholar/theme/theme.inc → modules/islandscholar/theme/theme.inc

0
targets/passthru_results/css/roblib_search_passthru.css → modules/passthru_results/css/roblib_search_passthru.css

0
targets/passthru_results/js/passthru_results.js → modules/passthru_results/js/passthru_results.js

0
targets/passthru_results/roblib_search_passthru.info → modules/passthru_results/roblib_search_passthru.info

0
targets/passthru_results/roblib_search_passthru.install → modules/passthru_results/roblib_search_passthru.install

0
targets/passthru_results/roblib_search_passthru.module → modules/passthru_results/roblib_search_passthru.module

0
targets/passthru_results/theme/roblib-search-passthru.tpl.php → modules/passthru_results/theme/roblib-search-passthru.tpl.php

0
targets/passthru_results/theme/theme.inc → modules/passthru_results/theme/theme.inc

0
targets/eds/css/roblib_search_eds.css → modules/roblib_search_eds/css/roblib_search_eds.css

89
modules/roblib_search_eds/js/eds_results_article.js

@ -0,0 +1,89 @@
Drupal.behaviors.roblib_search_eds_articles = {
attach: function (context, settings) {
if (context == document) {
$query = drupalSettings.path.currentPath.replace('roblib_search/', '');
$url = settings.eds_article_search_url + $query;
article_profile = settings.eds_article_profile;
proxy_url = "https://proxy.library.upei.ca/login?url=";
jQuery.getJSON($url, function (data) {
var items = [];
var numberOfDocs = 0;
try {
numberOfDocs = data.numFound;
} catch (err) {
// do nothing leave docLength at 0
}
if (numberOfDocs < 1) {
jQuery('#' + 'roblib-search-content-eds').empty().append('No Results');
jQuery('.' + 'pane-roblib-search-eds-roblib-search-eds-articles').hide();
} else {
var counter = 0;
var divs = new Array();
var content = new Array();
var queries = [];
jQuery.each(data.queries, function (key7, query) {
queries.push(query.query);
})
var query_str = encodeURI(data.queries[0].query);
var href_str = 'https://search.ebscohost.com/login.aspx?direct=true&site=eds-live&scope=site&type=1&custid=uprince&groupid=main&profid=' + article_profile + '&mode=bool&lang=en&bquery=';
jQuery.each(data.documents, function (key, val) {
id = 'roblib-search-eds-article-' + counter;
divs[counter++] = id;
if (typeof val.Items !== 'undefined') {
items.push('<div class ="roblib-search-row" id="' + id + '">');
if (typeof val.Items.Title !== 'undefined') {
items.push('<div class="roblib-title eds">');
items.push('<a href="' + proxy_url + val.PLink + '&scope=site">' + val.Items.Title.Data + '</a></div>');
}
pubType = val.PubType;
pubYear = val.RecordInfo.BibRelationships.IsPartOfRelationships["date"];
!pubYear ? pubYear = " " : pubYear = pubYear[0]["Y"];
items.push('<div class="eds-type"><span class="eds-pubyear">' + pubYear + '</span> - ' + pubType + '</div>');
var roblib_authors = [];
jQuery.each(val.RecordInfo.BibRelationships.HasContributorRelationships, function (key3, author) {
roblib_authors.push(author.NameFull);
})
items.push('<div class="eds-sor">');
roblib_authors = roblib_shorten(roblib_authors.join('; '), 50, " ");
items.push(roblib_authors);
items.push('</div>');
if (typeof val.Items.TitleSource !== 'undefined') {
items.push('<div class="eds-src"><span class="eds-label">In:</span> ' + val.Items.TitleSource.Data + '</div>');
}
if (typeof val.PLink !== 'undefined' && typeof val.PDF !== 'undefined' && val.PDF == 'pdflink') {
items.push('<div class="eds-db eds-pdf-link"><a href="' + proxy_url + val.PLink + '&scope=site">PDF Full Text</a></div>');
}
if (typeof val.PLink !== 'undefined' && typeof val.HTML !== 'undefined' && val.HTML == '1') {
items.push('<div class="eds-db eds-pdf-link"><a href="' + proxy_url + val.PLink + '&scope=site">HTML Full Text</a></div>');
}
items.push('</div>');
} else {
items.push('<div class ="roblib-search-row roblib-eds-unauthorized" id="\' + id + \'">You must login to view this result, <a href="https://proxy.library.upei.ca/login?url=' + href_str + query_str + '" id="eds-unauthorized-result">click here to login</a></div>');
}
});
jQuery('#' + 'roblib-search-content-eds-articles').empty().append(items.join(''));
}
var non_upei_link = '';
var upei_link = '<a href="' + proxy_url + href_str + query_str + '" id="eds-article-see-all-results">SEE ALL (' + data.recordCount + ')</a> ';
// if (!data.is_local_ip) {
// non_upei_link = '<a href="' + href_str + query_str + '&authtype=ip,guest" id="eds-article-non-upei-see_all_results">[Non-UPEI]</a>';
// upei_link = upei_link + non_upei_link;
// }
jQuery('#roblib-search-eds-article-more').empty().append(upei_link);
jQuery('#roblib-eds-articles-more-results').empty().append(upei_link);
jQuery('#roblib-eds-articles-toc').empty().append('<a href="' + proxy_url + href_str + query_str + '" id="eds-article-see-all-results-toc">Articles (' + data.recordCount + ')</a>');
});
}
}
}

112
modules/roblib_search_eds/js/eds_results_book.js

@ -0,0 +1,112 @@
Drupal.behaviors.roblib_search_eds = {
attach: function (context, settings) {
if (context == document) {
$query = drupalSettings.path.currentPath.replace('roblib_search/', '');
$url = settings.eds_book_search_url + $query;
book_profile = settings.eds_book_profile;
proxy_url = "https://proxy.library.upei.ca/login?url=";
jQuery.getJSON($url, function (data) {
var items = [];
var numberOfDocs = 0;
try {
numberOfDocs = data.numFound;
} catch (err) {
// do nothing leave docLength at 0
}
if (numberOfDocs < 1) {
jQuery('#' + 'roblib-search-content-eds').empty().append('No Results');
jQuery('.' + 'pane-roblib-search-eds-roblib-search-eds-results').hide();
} else {
var counter = 0;
var divs = new Array();
var content = new Array();
var queries = [];
jQuery.each(data.queries, function (key7, query) {
queries.push(query.query);
})
var query_str = encodeURI(data.queries[0].query);
var href_str = 'https://search.ebscohost.com/login.aspx?direct=true&site=eds-live&scope=site&type=1&custid=uprince&groupid=main&profid='+ book_profile + '&mode=bool&lang=en&bquery=';
jQuery.each(data.documents, function (key, val) {
id = 'roblib-search-eds-' + counter;
divs[counter++] = id;
if (typeof val.Items !== 'undefined') {
items.push('<div class ="roblib-search-row" id="' + id + '">');
if (typeof val.Items.Title !== 'undefined') {
items.push('<div class="roblib-title eds">');
items.push('<a href="' + proxy_url + val.PLink + '&scope=site">' + val.Items.Title.Data + '</a></div>');
}
val.PubType == 'Book' ? pubType = 'Print Book' : pubType = val.PubType;
pubYear = val.RecordInfo.BibRelationships.IsPartOfRelationships["date"];
!pubYear ? pubYear = " " : pubYear = pubYear[0]["Y"];
items.push('<div class="eds-type"><span class="eds-pubyear">' + pubYear + '</span> - ' + pubType + '</div>');
var roblib_authors = [];
jQuery.each(val.RecordInfo.BibRelationships.HasContributorRelationships, function (key3, author) {
roblib_authors.push(author.NameFull);
})
items.push('<div class="eds-sor">');
roblib_authors = roblib_shorten(roblib_authors.join('; '), 50, " ");
items.push(roblib_authors);
items.push('</div>');
var url;
!val.Items.URL ? url = " " : url = val.Items.URL.Data;
if (url) {
items.push('<div class="eds-url">' + url + '</div>');
}
if (pubType == "Print Book") {
anNumber = val.An.split(".");
if (anNumber[0] && anNumber[0] == 'upei') {
catalogUrl = '<a href="http://islandpines.roblib.upei.ca/eg/opac/record/' + anNumber[1] +
'">View in UPEI Catalogue</a>';
items.push('<div class="eds-catalog-link">' + catalogUrl + '</div>');
}
}
items.push('</div>');
} else {
items.push('<div class ="roblib-search-row roblib-eds-unauthorized" id="\' + id + \'">You must login to view this result, <a href="https://proxy.library.upei.ca/login?url=' + href_str + query_str + '" id="eds-unauthorized-result">click here to login</a></div>');
}
});
jQuery('#' + 'roblib-search-content-eds').empty().append(items.join(''));
}
var non_upei_link = '';
var upei_link = '<a href="' + proxy_url + href_str + query_str + '" id="eds-see-all-results">SEE ALL (' + data.recordCount + ')</a> ';
// if (!data.is_local_ip) {
// non_upei_link = '<a href="' + href_str + query_str + '&authtype=ip,guest" id="eds-non-upei-see_all_results">[Non-UPEI]</a>';
// upei_link = upei_link + non_upei_link;
// }
jQuery('#roblib-search-eds-more').empty().append(upei_link);
jQuery('#roblib-eds-books-more-results').empty().append(upei_link);
jQuery('#roblib-eds-books-toc').empty().append('<a href="' + proxy_url + href_str + query_str + '" id="eds-see-all-results-toc">Books (' + data.recordCount + ')</a>');
});
}
}
}
function roblib_intersects(a, b) {
var d = {};
var results = [];
for (var i = 0; i < b.length; i++) {
d[b[i]] = true;
}
for (var j = 0; j < a.length; j++) {
if (d[a[j]])
results.push(a[j]);
}
return results;
}
function roblib_shorten(str, maxLen, separator) {
if (str.length <= maxLen)
return str;
return str.substr(0, str.lastIndexOf(separator, maxLen)) + ' et al.';
}

8
modules/roblib_search_eds/roblib_search_eds.info.yml

@ -0,0 +1,8 @@
name: Roblib Search EDS
type: module
configure: roblib_search_eds.settings
description: Implements the Roblib Search EDS book and article results
package: Roblib Search
core_version_requirement: ^9 || ^10
dependancies:
- roblib_search

19
modules/roblib_search_eds/roblib_search_eds.libraries.yml

@ -0,0 +1,19 @@
eds-book:
version: 1.x
css:
base:
css/roblib_search_eds.css: {}
js:
js/eds_results_book.js: {}
dependencies:
- core/drupal
eds-article:
version: 1.x
css:
base:
css/roblib_search_eds.css: {}
js:
js/eds_results_article.js: {}
dependencies:
- core/drupal

43
modules/roblib_search_eds/roblib_search_eds.module

@ -0,0 +1,43 @@
<?php
/**
* @file
* Implementation of Roblib search for searching EDSAPI (EBSCO) targets.
*/
/**
* Implements hook_theme().
*/
function roblib_search_eds_theme($existing, $type, $theme, $path) {
$modulePath = \Drupal::service('module_handler')->getModule('roblib_search')
->getPath();
$spinner_path = '/' . $modulePath . "/img/spinner.gif";
return [
'roblib_search_eds_books' => [
'variables' => ['query' => NULL, 'spinner_path' => $spinner_path],
],
'roblib_search_eds_articles' => [
'variables' => ['query' => NULL, 'spinner_path' => $spinner_path],
],
];
}
/**
* Implements hook_help().
*
* @param type $path
* @param type $arg
* @return type
*/
function roblib_search_eds_help($path, $arg) {
switch ($path) {
case 'admin/help#roblib_search_eds':
return t(
'<p>
provides a EDSAPI target for the Roblib search module. This target uses javascript
to render the results.
</p>'
);
}
}

25
modules/roblib_search_eds/roblib_search_eds.routing.yml

@ -0,0 +1,25 @@
roblib_search_eds.settings:
path: '/admin/config/system/roblib_search_eds_settings'
defaults:
_form: '\Drupal\roblib_search_eds\Form\EdsSettingsForm'
_title: 'Roblib Search EDS Settings Form'
requirements:
_permission: 'administer site configuration'
roblib_search_eds.article_search:
path: '/roblib_search/eds/articles/{query}'
defaults:
_controller: '\Drupal\roblib_search_eds\Controller\RoblibSearchEdsController::articleResults'
_title: 'Roblib Search EDS Articles'
query: '[a-zA-Z\s]+'
requirements:
_permission: 'access content'
roblib_search_eds.book_search:
path: '/roblib_search/eds/book/{query}'
defaults:
_controller: '\Drupal\roblib_search_eds\Controller\RoblibSearchEdsController::bookResults'
_title: 'Roblib Search EDS Articles'
query: '[a-zA-Z\s]+'
requirements:
_permission: 'access content'

117
modules/roblib_search_eds/src/Controller/RoblibSearchEdsController.php

@ -0,0 +1,117 @@
<?php
namespace Drupal\roblib_search_eds\Controller;
use Drupal\Core\Controller\ControllerBase;
use Drupal\roblib_search_eds\Lib\EBSCOAPI;
/**
* Controller for d3 graphs.
*/
class RoblibSearchEdsController extends ControllerBase {
/**
* Print JSON.
*
*/
public function articleResults($query = NULL) {
print $this->eds_get_results($query, 'Articles');
exit();
}
/**
* Print JSON.
*
*/
public function bookResults($query = NULL) {
print $this->eds_get_results($query, 'Books');
exit();
}
/**
* Query EBSCO using the EDS API.
* @param string $query
* The search term(s) to send to EBSCO.
* @param string type
* The type of search, either Books or Articles.
* @return string
* A JSON string
*/
function eds_get_results($query = NULL, $type = 'Articles') {
//drupal_add_css(drupal_get_path('module', 'roblib_search_eds') . '/css/roblib_search_eds.theme.css');
$config = \Drupal::config('roblib_search_eds.settings');
// Url parameters.
if (!isset($query)) {
if (isset($_GET['roblib_query'])) {
$query = $_GET['roblib_query'];
}
else {
return '';
}
}
$limiters = '';
if ($type != NULL) {
$limiters = $this->get_eds_query_limiters($type);
}
// hardcoding "available in library collection" limiter as we can't pass it the
// same way we passed other limiters
$filters = ($type === 'Books') ? array("addlimiter(FT1:y)") : array();
$eds_config = $this->build_eds_config_arr($type);
$number_per_page = $config->get('eds_num_results');
$query = '(' . $query . ') ' . $limiters;
$search = array('lookfor' => $query, 'type' => 'ALLFields', 'index' => 'AllFields', 'q' => 'ebsco/results', 'op' => 'Search');
$eds_api = new EBSCOAPI($eds_config);
$is_local_ip = $eds_api->connector()->isGuestIPAddress($_SERVER["REMOTE_ADDR"]);
$eds_api->isGuest(FALSE);
$output = $eds_api->apiSearch($search, $filters, 1, $number_per_page);
$output['is_local_ip'] = $is_local_ip;
return json_encode($output);
}
/**
* Creates the limiter string to append to the end of a query.
*
* @param string $type
* The type of search we want (Articles or Books)
*
* @return string
* The limiters to append to the query.
*/
function get_eds_query_limiters($type) {
$config = \Drupal::config('roblib_search_eds.settings');
$limiters = 'n';
switch ($type) {
case 'Articles':
//example 'facetfilter=1,SourceType:Magazines,SourceType:News,SourceType:Academic+Journals,SourceType:Conference+Materials';
$limiters = ' ' . $config->get('eds_article_limiters');
break;
case 'Books':
// example '+AND+(PT+book)';
// example 'facetfilter=1,PublicationType:Books,PublicationType:Audio,PublicationType:Videos';
$limiters = ' ' . $config->get('eds_book_limiters');
break;
}
return $limiters;
}
function build_eds_config_arr($type) {
$ebsco_config = array();
$roblib_search_config = \Drupal::config('roblib_search_eds.settings');
$ebsco_config['user'] = $roblib_search_config->get('eds_user');
$ebsco_config['password'] = $roblib_search_config->get('eds_pass');
//get the local ips allowed from ebsco
//TODO move this to a variable
$ebsco_config['local_ip_address'] = $roblib_search_config->get('eds_local_ip');
$ebsco_config['profile'] = ($type === 'Books') ? $roblib_search_config->get
('eds_book_profile') : $roblib_search_config->get('eds_article_profile');
$ebsco_config['auth_url'] = $roblib_search_config->get('eds_auth_url');
$ebsco_config['rest_url'] = $roblib_search_config->get('eds_rest_url');
$ebsco_config['guest'] = $roblib_search_config->get('eds_guest');
$ebsco_config['autocomplete'] = '';
return $ebsco_config;
}
}

146
modules/roblib_search_eds/src/Form/EdsSettingsForm.php

@ -0,0 +1,146 @@
<?php
namespace Drupal\roblib_search_eds\Form;
use Drupal\Core\Form\FormBase;
use Drupal\Core\Form\FormStateInterface;
/**
* Settings form for module
*
* @author ppound
*/
class EdsSettingsForm extends FormBase {
/**
* {@inheritdoc}
*/
public function getFormId() {
return 'roblib_search_eds_settings_form';
}
/**
* {@inheritdoc}
*/
public function buildForm(array $form, FormStateInterface $form_state) {
$config = \Drupal::config('roblib_search_eds.settings');
/* $form['eds_rest_url'] = array(
'#type' => 'textfield',
'#title' => t('EDS Rest endpoint'),
'#default_value' => $config->get('eds_rest_url'),
'#description' => t('The base EDS URL, for example https://eds-api.ebscohost.com/edsapi/rest'),
'#required' => TRUE,
);
$form['eds_auth_url'] = array(
'#type' => 'textfield',
'#title' => t('EDS Auth endpoint'),
'#default_value' => $config->get('eds_auth_url'),
'#description' => t('The EDS Auth endpoint, for example https://eds-api.ebscohost.com/Authservice/rest'),
'#required' => TRUE,
);
$form['eds_user'] = array(
'#type' => 'textfield',
'#title' => t('EDS user'),
'#default_value' => $config->get('eds_user'),
'#description' => t('EDS user, for example username'),
'#required' => TRUE,
);
$form['eds_pass'] = array(
'#type' => 'textfield',
'#title' => t('EDS password'),
'#default_value' => $config->get('eds_pass'),
'#description' => t('EDS password, for example password'),
'#required' => TRUE,
);
$form['eds_guest'] = array(
'#type' => 'textfield',
'#title' => t('EDS Guest access'),
'#default_value' => $config->get('eds_guest'),
'#description' => t('EDS Guest access, y = guest access, n = not a guest'),
'#required' => TRUE,
);*/
$form['eds_local_ip'] = array(
'#type' => 'textfield',
'#title' => t('EDS Local IP'),
'#default_value' => $config->get('eds_local_ip'),
'#description' => t('Local IP address prefix, i. 137.149.'),
'#required' => TRUE,
);
$form['eds_article_profile'] = array(
'#type' => 'textfield',
'#title' => t('EDS Article profile'),
'#default_value' => $config->get('eds_article_profile'),
'#description' => t('EDS profile, for example edsapi'),
'#required' => TRUE,
);
$form['eds_book_profile'] = array(
'#type' => 'textfield',
'#title' => t('EDS Book profile'),
'#default_value' => $config->get('eds_book_profile'),
'#description' => t('EDS Book profile, for example apilite'),
'#required' => TRUE,
);
$form['eds_num_results'] = array(
'#type' => 'textfield',
'#title' => t('Number of results to return'),
'#default_value' => $config->get('eds_num_results'),
'#description' => t('The number of results to display in the Bento box, usurally 5'),
'#required' => TRUE,
);
$form['eds_article_limiters'] = array(
'#type' => 'textarea',
'#title' => t('The limiters for Article searches'),
'#default_value' => $config->get('eds_article_limiters'),
'#description' => t('Specify the Publication Types to use as limiters for Article searches. Formatted similar to
AND (PT Article OR PT Magazines OR PT News OR PT Academic Journals OR PT Conference Materials)'),
'#required' => TRUE,
);
$form['eds_book_limiters'] = array(
'#type' => 'textarea',
'#title' => t('The limiters for Books and Media searches'),
'#default_value' => $config->get('eds_book_limiters'),
'#description' => t('Specify the Publication Types to use as limiters for Article searches. Formatted similar to
AND (PT Book OR PT Video OR PT Audio'),
'#required' => TRUE,
);
$form['actions']['submit'] = [
'#type' => 'submit',
'#value' => t('Save'),
'#button_type' => 'primary',
];
return $form;
}
/**
* {@inheritdoc}
*/
public function validateForm(array &$form, FormStateInterface $form_state) {
}
/**
* {@inheritdoc}
*/
public function submitForm(array &$form, FormStateInterface $form_state) {
$config = \Drupal::configFactory()->getEditable('roblib_search_eds.settings');
//$config->set('eds_rest_url', $form_state->getValue('eds_rest_url'))->save();
//$config->set('eds_auth_url', $form_state->getValue('eds_auth_url'))->save();
//$config->set('eds_user', $form_state->getValue('eds_user'))->save();
//$config->set('eds_pass', $form_state->getValue('eds_pass'))->save();
//$config->set('eds_guest', $form_state->getValue('eds_guest'))->save();
$config->set('eds_local_ip', $form_state->getValue('eds_local_ip'))->save();
$config->set('eds_article_profile', $form_state->getValue('eds_article_profile'))->save();
$config->set('eds_book_profile', $form_state->getValue('eds_book_profile'))->save();
$config->set('eds_num_results', $form_state->getValue('eds_num_results'))->save();
$config->set('eds_article_limiters', $form_state->getValue('eds_article_limiters'))->save();
$config->set('eds_book_limiters', $form_state->getValue('eds_book_limiters'))->save();
}
}

822
modules/roblib_search_eds/src/Lib/EBSCOAPI.php

@ -0,0 +1,822 @@
<?php
namespace Drupal\roblib_search_eds\Lib;
/**
* @file
* The EBSCO EDS API class.
*
* PHP version 5
*
*
* Copyright [2017] [EBSCO Information Services]
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
use Drupal\roblib_search_eds\Lib\EBSCOConnector;
use Drupal\roblib_search_eds\Lib\EBSCOResponse;
/**
* EBSCO API class.
*/
class EBSCOAPI {
/**
* The authentication token used for API transactions.
*
* @global string
*/
private $authenticationToken;
/**
* The session token for API transactions.
*
* @global string
*/
private $sessionToken;
/**
* The EBSCOConnector object used for API transactions.
*
* @global object EBSCOConnector
*/
private $connector;
/**
* Configuration options.
*/
protected $config;
/**
* VuFind search types mapped to EBSCO search types
* used for urls in search results / detailed result.
*
* @global array
*/
private static $search_tags = array(
'' => '',
'AllFields' => '',
'Abstract' => 'AB',
'Author' => 'AU',
'Source' => 'SO',
'Subject' => 'SU',
'Title' => 'TI',
'ISBN' => 'IB',
'ISSN' => 'IS',
);
/**
* EBSCO sort options .
*
* @global array
*/
private static $sort_options = array(
'relevance',
'date',
'date2',
'source',
);
/**
* VuFind sort types mapped to EBSCO sort types
* used for urls in Search results / Detailed view.
*
* @global array
*/
private static $mapped_sort_options = array(
'' => 'relevance',
'relevance' => 'relevance',
'subject' => 'date',
'date' => 'date2',
'date_asc' => 'date2',
'date_desc' => 'date',
'callnumber' => 'date',
'author' => 'author',
'title' => 'date',
);
/**
* Constructor.
*
* @param array config
*
* @access public
*/
public function __construct($config) {
$this->config = $config;
}
/**
* Setter / Getter for authentication token.
*
* @param string The authentication token
*
* @return string or none
*
* @access public
*/
public function authenticationToken(){
$autocompleteTokenTimeOut = time();
$authenticationTimeout = 0;
//$authenticationTimeout;
// $autocompleteUrl = '';
// $token = '';
// $timeout = '';
// $autoToken = '';
// //$autocompleteTokenTimeOut = '';
// //$autocompleteTokenTimeOut;
// $autocompleteTokenTimeOut = 0;
// $autocompleteCustId ='';
if (isset($_SESSION["authenticationToken"])){
$token = $_SESSION["authenticationToken"];
$authenticationTimeout = $_SESSION["authenticationTimeout"]-600;
$timeout = $_SESSION["authenticationTimeout"];
$autocompleteUrl = $_SESSION["autocompleteUrl"];
$autoToken = $_SESSION["autocompleteToken"];
$autocompleteTokenTimeOut = $_SESSION["autocompleteTokenTimeOut"];
$autocompleteCustId = $_SESSION["autocompleteCustId"];
}else{
$result = $this->apiAuthenticationToken();
$_SESSION["authenticationToken"]= $result['authenticationToken'];
$_SESSION["authenticationTimeout"]= $result['authenticationTimeout'];
$_SESSION['autocompleteUrl'] = $result['autocompleteUrl'];
$_SESSION['autocompleteToken'] = $result['autocompleteToken'];
$_SESSION["autocompleteTokenTimeOut"]= $result['autocompleteTokenTimeOut'];
$_SESSION['autocompleteCustId'] = $result['autocompleteCustId'];
}
if(time()-$autocompleteTokenTimeOut >= $authenticationTimeout){
$result = $this->apiAuthenticationToken();
$_SESSION["authenticationToken"]= $result['authenticationToken'];
$_SESSION["authenticationTimeout"]= $result['authenticationTimeout'];
$_SESSION['autocompleteUrl'] = $result['autocompleteUrl'];
$_SESSION['autocompleteToken'] = $result['autocompleteToken'];
$_SESSION["autocompleteTokenTimeOut"]= $result['autocompleteTokenTimeOut'];
$_SESSION['autocompleteCustId'] = $result['autocompleteCustId'];
$result = array(
'authenticationToken' => $token,
'authenticationTimeout' => $timeout,
'autocompleteUrl' => $autocompleteUrl,
'autocompleteToken' => $autoToken,
'autocompleteTokenTimeOut' => $autocompleteTokenTimeOut,
'autocompleteCustId' => $autocompleteCustId
);
return $result['authenticationToken'];
}else{
return $this->token;
}
}
/**
* Setter / Getter for session token.
*
* @param string The session token
*
* @return string or none
*
* @access public
*/
public function sessionToken($token = NULL) {
if (empty($token)) {
$token = $this->readSession('sessionToken');
return !empty($token) ? $token : $this->sessionToken;
}
else {
$this->sessionToken = $token;
$this->writeSession('sessionToken', $token);
}
}
/**
* Getter for isGuest.
*
* @param string 'y' or 'n'
*
* @return string or none
*
* @access public
*/
public function isGuest($boolean = NULL) {
if (empty($boolean)) {
return $this->readSession('isGuest');
}
else {
$this->writeSession('isGuest', $boolean);
}
}
/**
* Create a new EBSCOConnector object or reuse an existing one.
*
* @param none
*
* @return EBSCOConnector object
*
* @access public
*/
public function connector() {
if (empty($this->connector)) {
$this->connector = new EBSCOConnector($this->config);
}
return $this->connector;
}
/**
* Create a new EBSCOResponse object.
*
* @param object $response
*
* @return EBSCOResponse object
*
* @access public
*/
public function response($response) {
$responseObj = new EBSCOResponse($response);
return $responseObj;
}
/**
* Request authentication and session tokens, then send the API request.
* Retry the request if authentication errors occur.
*
* @param string $action
* The EBSCOConnector method name.
* @param array $params
* The parameters of the HTTP request.
* @param int $attempts
* The number of retries.
*
* @return object SimpleXml DOM or PEAR Error
*
* @access protected
*/
protected function request($action, $params = NULL, $attempts = 5) {
//$authenticationToken = $this->authenticationToken();
$sessionToken = $this->apiSessionToken();//$this->sessionToken();
// If authentication token is missing then the session token is missing too, so get both tokens
// If session token is missing then the authentication token may be invalid, so get both tokens.
if (empty($sessionToken)) {
//$result = $this->apiAuthenticationAndSessionToken();
$result = $this->apiSessionToken();
if ($this->isError($result)) {
// Any error should terminate the request immediately
// in order to prevent infinite recursion.
return $result;
}
}
// Any change of the isGuest should request a new session
// (and don't terminate the current request if there was an error during the session request
// since it's not that important)
if ($this->isGuest() != $this->connector()->isGuest()) {
$this->apiSessionToken();
}
$headers = array(
// 'x-authenticationToken: '.$this->authenticationToken(),
'x-sessionToken: '.$this->sessionToken(),
);
$response = call_user_func_array(array($this->connector(), "request{$action}"), array($params, $headers));
if ($this->isError($response)) {
// Retry the request if there were authentication errors.
$code = $response->getCode();
switch ($code) {
// If authentication token is invalid then the session token is invalid too, so get both tokens
// If session token is invalid then the authentication token may be invalid too, so get both tokens.
case EBSCOConnector::EDS_AUTH_TOKEN_INVALID:
$result = $this->apiAuthenticationToken();
if ($this->isError($result)) {
// Any error should terminate the request immediately
// in order to prevent infinite recursion.
return $result;
}
if ($attempts > 0) {
$result = $this->request($action, $params, --$attempts);
}
break;
case EBSCOConnector::EDS_SESSION_TOKEN_INVALID:
$result = $this->apiAuthenticationAndSessionToken();
if ($this->isError($result)) {
// Any error should terminate the request immediately
// in order to prevent infinite recursion.
return $result;
}
if ($attempts > 0) {
$result = $this->request($action, $params, --$attempts);
}
break;
default:
$result = $this->handleError($response);
break;
}
}
else {
$result = $this->response($response)->result();
}
return $result;
}
/**
* Wrapper for authentication API call.
*
* @param none
*
* @access public
*/
public function apiAuthenticationToken() {
$response = $this->connector()->requestAuthenticationToken();
$result = $this->response($response)->result();
return $result;
}
/**
* Wrapper for session API call.
*
* @param none
*
* @access public
*/
public function apiSessionToken() {
// Add authentication tokens to headers.
//$headers = array(
// 'x-authenticationToken: '.$this->authenticationToken(),
//);
$response = $this->connector()->requestSessionToken($headers);
// Raise the exception so that any code running this method should exit immediately.
if ($this->isError($response)) {
return $response;
}
else {
$result = $this->response($response)->result();
if (is_string($result)) {
$this->sessionToken($result);
return $result;
}
else {
return new EBSCOException("No session token was found in the response.");
}
}
}
/**
* Initialize the authentication and session tokens.
*
* @param none
*
* @access public
*/
public function apiAuthenticationAndSessionToken() {
$authenticationToken = $this->apiAuthenticationToken();
if ($this->isError($authenticationToken)) {
// An authentication error should terminate the request immediately.
return $authenticationToken;
}
$sessionToken = $this->apiSessionToken();
if ($this->isError($sessionToken)) {
// A session error should terminate the request immediately.
return $sessionToken;
}
// We don't have to return anything, both tokens can be accessed using the getters.
return TRUE;
}
/**
* Wrapper for search API call.
*
* @param array $search
* The search terms.
* @param array $filters
* The facet filters.
* @param string $start
* The page to start with.
* @param string $limit
* The number of records to return.
* @param string $sortBy
* The value to be used by for sorting.
* @param string $amount
* The amount of data to be returned.
* @param string $mode
* The search mode.
*
* @throws object PEAR Error
*
* @return array An array of query results
*
* @access public
*/
public function apiSearch($search,
$filters,
$start = 1,
$limit = 10,
$sortBy = 'relevance',
$amount = 'detailed',
$mode = 'all',
$rs = FALSE,
$emp = FALSE,
$autosuggest = FALSE,
$includeimagequickview = FALSE,
$styles = '',
$IllustrationInfo = FALSE,
$autoComplete = FALSE
) {
$query = array();
// Basic search.
if (!empty($search['lookfor'])) {
$lookfor = $search['lookfor'];
$type = isset($search['index']) && !empty($search['index']) ? $search['index'] : 'AllFields';
// Escape some characters from lookfor term.
//$term = str_replace(array(',', ':', '(', ')'), array('\,', '\:', '\(', '\)'), $lookfor);
// The below version of the above matches the drupal 7 searches but the above may give less but better results
// and be worth testing down the road.
$term = str_replace(array(',', ':'), array('\,', '\:'), $lookfor);
// Replace multiple consecutive empty spaces with one empty space.
$term = preg_replace("/\s+/", ' ', $term);
// Search terms
// Complex search term.
if (preg_match('/(.*) (AND|OR) (.*)/i', $term)) {
$query['query'] = $term;
}
else {
$tag = self::$search_tags[$type];
$op = 'AND';
$query_str = implode(',', array($op, $tag));
$query_str = implode(($tag ? ':' : ''), array($query_str, $term));
$query['query-1'] = $query_str;
}
// Advanced search.
}
elseif (!empty($search['group'])) {
$counter = 1;
foreach ($search['group'] as $group) {
$type = $group['type'];
if (isset($group['lookfor'])) {
$term = $group['lookfor'];
$op = isset($group['bool'])?$group['bool']:"AND";
$tag = $type && isset(self::$search_tags[$type]) ? self::$search_tags[$type] : '';
// Escape some characters from lookfor term.
$term = str_replace(array(',', ':', '(', ')'), array('\,', '\:', '\(', '\)'), $term);
// Replace multiple consecutive empty spaces with one empty space.
$term = preg_replace("/\s+/", ' ', $term);
if (!empty($term)) {
$query_str = implode(',', array($op, $tag));
$query_str = implode(($tag ? ':' : ''), array($query_str, $term));
$query["query-$counter"] = $query_str;
$counter++;
}
}
}
// No search term, return an empty array.
}
else {
$results = array(
'recordCount' => 0,
'numFound' => 0,
'start' => 0,
'documents' => array(),
'facets' => array(),
);
return $results;
}
// Add filters.
$limiters = array(); $expanders = array(); $facets = array();
foreach ($filters as $filter) {
if (preg_match('/addlimiter/', $filter)) {
list($action, $str) = explode('(', $filter, 2);
// e.g. FT:y or GZ:Student Research, Projects and Publications.
$field_and_value = substr($str, 0, -1);
list($field, $value) = explode(':', $field_and_value, 2);
$limiters[$field][] = $value;
}
elseif (preg_match('/addexpander/', $filter)) {
list($action, $str) = explode('(', $filter, 2);
// Expanders don't have value.
$field = substr($str, 0, -1);
$expanders[] = $field;
}
elseif (preg_match('/addfacetfilter/', $filter)) {
list($action, $str) = explode('(', $filter, 2);
// e.g. ZG:FRANCE.
$field_and_value = substr($str, 0, -1);
list($field, $value) = explode(':', $field_and_value, 2);
$facets[$field][] = $field_and_value;
}
}
if (!empty($limiters)) {
$query['limiter']='';
foreach ($limiters as $field => $limiter) {
// e.g. LA99:English,French,German.
$query['limiter'].= $field . ':' . implode(',', $limiter);
}
}
if (!empty($expanders)) {
// e.g. fulltext, thesaurus.
$query['expander'] = implode(',', $expanders);
}
if (!empty($facets)) {
$groupId = 1;
foreach ($facets as $field => $facet) {
// e.g. 1,DE:Math,DE:History.
$query['facetfilter'] = $groupId . ',' . implode(',', $facet);
$groupId += 1;
}
}
// 2014-03-26 - new action to jump to page.
if ($start > 1) {
$query['action'] = "GoToPage(" . $start . ")";
}
// Add the sort option.
$sortBy = in_array($sortBy, self::$sort_options) ? $sortBy : self::$mapped_sort_options[$sortBy];
// Add the HTTP query params.
$params = array(
// Specifies the sort. Valid options are:
// relevance, date, date2
// date = Date descending
// date2 = Date ascending.
'sort' => $sortBy,
// Specifies the search mode. Valid options are:
// bool, any, all, smart.
'searchmode' => $mode,
// Specifies the amount of data to return with the response
// Valid options are:
// title: Title only
// brief: Title + Source, Subjects
// detailed: Brief + full abstract.
'view' => $amount,
// Specifies whether or not to include facets.
'includefacets' => 'y',
'resultsperpage' => $limit,
// 2014-03-26 RF.
'pagenumber' => $start,
// 'pagenumber' => 1,
// Specifies whether or not to include highlighting in the search results.
'highlight' => 'y',
//'includeimagequickview' => $includeimagequickview,
//UPEI commented out
//'format' => 'ris',
//UPEI commented out
//'styles' => $styles,
);
if ($autosuggest == TRUE) {
$params["autosuggest"] = "y";
}
if ($rs == TRUE) {
$params["relatedcontent"] = "rs";
}
if ($emp == TRUE) {
if (isset($params["relatedcontent"])) {
$params["relatedcontent"] .= ",emp";
}
else {
$params["relatedcontent"] = "emp";
}
}
if ($includeimagequickview == TRUE) {
//$params["includeimagequickview"] = "y";
}
if ($styles == 'all') {
$params["styles"] = "all";
}
if ($autoComplete == TRUE) {
$params["autocomplete"] = "y";
}
$params = array_merge($params, $query);
$result = $this->request('Search', $params);
return $result;
}
/**
* Wrapper for retrieve API call.
*
* @param array $an
* The accession number.
* @param string $start
* The short database name.
*
* @throws object PEAR Error
*
* @return array An associative array of data
*
* @access public
*/
public function apiRetrieve($an, $db) {
// Add the HTTP query params.
//$includeimagequickviewDetail = FALSE;
$params = array(
'an' => $an,
'dbid' => $db,
'highlight' => 'y',
//'includeimagequickview' => $includeimagequickviewDetail,
//'IllustrationInfo' => 'y',
'IllustrationInfo' => $IllustrationInfo,
'format' => 'ris',
'styles' => $styles,
);
$result = $this->request('Retrieve', $params);
return $result;
}
public function apiExport($an, $db) {
$params = array(
'an' => $an,
'dbid' => $db,
'format' => 'ris'
);
$result = $this->request('Export', $params);
return $result;
}
public function apiCitationStyles($an, $db, $styles) {
$params = array(
'an' => $an,
'dbid' => $db,
'styles' => $styles
);
$result = $this->request('CitationStyles', $params);
return $result;
}
/**
* Wrapper for info API call.
*
* @throws object PEAR Error
*
* @return array An associative array of data
*
* @access public
*/
public function apiInfo() {
if ($result = $this->readSession('info')) {
return $result;
}
$result = $this->request('Info');
if (!$this->isError($result)) {
$this->writeSession('info', $result);
}
return $result;
}
public function apiAutoComplete(){
if(self::$autocomplete == 'y'){
// var_dump($autocomplete);
// die();
return true;
}
else{
return false;
}
}
/**
* Handle a PEAR_Error. Return :
* - if the error is critical : an associative array with the current error message
* - if the error is not critical : the error message .
*
* @param Pear_Error $exception
*
* @return array or the Pear_Error exception
*
* @access protected
*/
private function handleError($error) {
$errorCode = $error->getCode();
switch ($errorCode) {
// This kind of error was generated by user , so display it to user.
case EBSCOConnector::EDS_INVALID_ARGUMENT_VALUE:
// Any other errors are system errors, don't display them to user.
default:
$errorMessage = 'An error occurred when getting the data.';
break;
}
$result = array(
'errors' => $errorMessage,
'recordCount' => 0,
'numFound' => 0,
'start' => 0,
'documents' => array(),
'facets' => array(),
);
return $result;
}
/**
* Store the given object into session.
*
* @param string $key
* The key used for reading the value.
* @param object $value
* The object stored in session.
*
* @return none
*
* @access protected
*/
protected function writeSession($key, $value) {
if (!empty($key) && !empty($value)) {
$_SESSION['EBSCO'][$key] = $value;
}
}
/**
* Read from session the object having the given key.
*
* @param string $key
* The key used for reading the object.
*
* @return object
*
* @access protected
*/
protected function readSession($key) {
$value = isset($_SESSION['EBSCO'][$key]) ? $_SESSION['EBSCO'][$key] : '';
return $value;
}
/**
* Check if given object is an EBSCOException object.
*
* @param object $object
*
* @return bool
*
* @access protected
*/
protected function isError($object) {
return is_a($object, 'EBSCOException');
}
}

580
modules/roblib_search_eds/src/Lib/EBSCOConnector.php

@ -0,0 +1,580 @@
<?php
namespace Drupal\roblib_search_eds\Lib;
/**
* @file
* The EBSCO Connector and Exception classes.
*
* Used when EBSCO API calls return error messages.
*
* Copyright [2017] [EBSCO Information Services]
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* EBSCOException class.
*/
class EBSCOException extends \Exception {
const CRITICAL_ERROR = 1;
/**
* Make message argument mandatory.
*/
public function __construct($message, $code = self::CRITICAL_ERROR, Exception $previous = NULL) {
parent::__construct($message, $code, $previous);
}
}
/**
* EBSCOConnector class.
*/
class EBSCOConnector {
/**
* Error codes defined by EDS API.
*/
const EDS_UNKNOWN_PARAMETER = 100;
const EDS_INCORRECT_PARAMETER_FORMAT = 101;
const EDS_INVALID_PARAMETER_INDEX = 102;
const EDS_MISSING_PARAMETER = 103;
const EDS_AUTH_TOKEN_INVALID = 104;
const EDS_INCORRECT_ARGUMENTS_NUMBER = 105;
const EDS_UNKNOWN_ERROR = 106;
const EDS_AUTH_TOKEN_MISSING = 107;
const EDS_SESSION_TOKEN_MISSING = 108;
const EDS_SESSION_TOKEN_INVALID = 109;
const EDS_INVALID_RECORD_FORMAT = 110;
const EDS_UNKNOWN_ACTION = 111;
const EDS_INVALID_ARGUMENT_VALUE = 112;
const EDS_CREATE_SESSION_ERROR = 113;
const EDS_REQUIRED_DATA_MISSING = 114;
const EDS_TRANSACTION_LOGGING_ERROR = 115;
const EDS_DUPLICATE_PARAMETER = 116;
const EDS_UNABLE_TO_AUTHENTICATE = 117;
const EDS_SEARCH_ERROR = 118;
const EDS_INVALID_PAGE_SIZE = 119;
const EDS_SESSION_SAVE_ERROR = 120;
const EDS_SESSION_ENDING_ERROR = 121;
const EDS_CACHING_RESULTSET_ERROR = 122;
const EDS_INVALID_EXPANDER_ERROR = 123;
const EDS_INVALID_SEARCH_MODE_ERROR = 124;
const EDS_INVALID_LIMITER_ERROR = 125;
const EDS_INVALID_LIMITER_VALUE_ERROR = 126;
const EDS_UNSUPPORTED_PROFILE_ERROR = 127;
const EDS_PROFILE_NOT_SUPPORTED_ERROR = 128;
const EDS_INVALID_CONTENT_PROVIDER_ERROR = 129;
const EDS_INVALID_SOURCE_TYPE_ERROR = 130;
const EDS_XSLT_ERROR = 131;
const EDS_RECORD_NOT_FOUND_ERROR = 132;
const EDS_SIMULTANEOUS_USER_LIMIT_ERROR = 133;
const EDS_NO_GUEST_ACCESS_ERROR = 134;
const EDS_DBID_NOT_IN_PROFILE_ERROR = 135;
const EDS_INVALID_SEARCH_VIEW_ERROR = 136;
const EDS_RETRIEVING_FULL_TEXT_ERROR = 137;
/**
* HTTP status codes constants
* https://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html.
*
* @global integer HTTP_OK The request has succeeded
* @global integer HTTP_NOT_FOUND The server has not found anything matching the Request-URI
*/
const HTTP_OK = 200;
const HTTP_BAD_REQUEST = 400;
const HTTP_NOT_FOUND = 404;
const HTTP_INTERNAL_SERVER_ERROR = 500;
/**
* The HTTP_Request object used for API transactions.
*
* @global object HTTP_Request
*/
private $client;
/**
* The URL of the EBSCO API server.
*
* @global string
*/
private static $end_point = 'https://eds-api.ebscohost.com/EDSAPI/rest';
/**
* The URL of the EBSCO API server.
*
* @global string
*/
private static $authentication_end_point = 'https://eds-api.ebscohost.com/AuthService/rest';
/**
* The password used for API transactions.
*
* @global string
*/
private $password;
/**
* The user id used for API transactions.
*
* @global string
*/
private $userId;
/**
* The profile ID used for API transactions.
*
* @global string
*/
private $profileId;
/**
* The interface ID used for API transactions.
*
* @global string
*/
private $interfaceId;
/**
* The customer ID used for API transactions.
*
* @global string
*/
private $orgId;
/**
* The isGuest used for API transactions.
*
* @global string 'y' or 'n'
*/
private $isGuest;
/**
* Contains the list of ip addresses.
*
* @global string
*/
private $local_ip_address;
/**
* You can log HTTP_Request requests using this option.
*
* @global bool logAPIRequests
*/
private $logAPIRequests;
/**
* Autocomplete
* @global string
*/
private $autoComplete;
/**
* The logger object.
*
* @global object Logger
*/
//private $logger;
/**
* Constructor.
*
* Sets up the EBSCO API settings.
*
* @param none
*
* @access public
*/
public function __construct($config) {
$this->password = $config['password'];
$this->userId = $config['user'];
$this->interfaceId = $config['interface'];
$this->profileId = $config['profile'];
$this->autoComplete = $config['autocomplete'];
$this->orgId = $config['organization'];
$this->local_ip_address = $config['local_ip_address'];
$this->isGuest = 'n';
$this->logAPIRequests = ($config['log'] == 1);
}
/**
* Detects if the user is authorized based on the IP address.
*
* @return string
*/
public function isGuestIPAddress($ipUser) {
$s = $this->local_ip_address;
if (trim($s) == "") {
return FALSE;
}
// Break records.
$m = explode(",", $s);
foreach ($m as $ip) {
if (strcmp(substr($ipUser, 0, strlen(trim($ip))), trim($ip)) == 0) {
// Inside of ip address range of customer.
return TRUE;
}
}
return FALSE;
}
/**
* Public getter for private isGuest .
*
* @param none
*
* @return string isGuest
*
* @access public
*/
public function isGuest() {
return $this->isGuest;
}
/**
* Request the authentication token.
*
* @param none
*
* @return object SimpleXml or PEAR_Error
*
* @access public
*/
public function requestAuthenticationToken() {
$url = self::$authentication_end_point . '/uidauth';
// Add the body of the request.
$params = '<UIDAuthRequestMessage xmlns="https://www.ebscohost.com/services/public/AuthService/Response/2012/06/01">'
.'<UserId>'.$this->userId.'</UserId>'
.'<Password>'.$this->password.'</Password>'
.'<InterfaceId>wsapi</InterfaceId>'
// .'<Options>
// <Option>'.$this->autoComplete.'</Option>
// </Options>'
.'</UIDAuthRequestMessage>';
$response = $this->request($url,$params, array(), 'POST');
return $response;
}
/**
* Request the session token.
*
* @param array $headers
* Authentication token.
*
* @return object SimpleXml or PEAR_Error
*
* @access public
*/
public function requestSessionToken($headers) {
$url = self::$end_point . '/CreateSession';
// Add the HTTP query params.
$params = array(
'profile' => $this->profileId,
'org' => $this->orgId,
'guest' => $this->isGuest
);
$response = $this->request($url, $params, $headers);
return $response;
}
/**
* Request the search records.
*
* @param array $params
* Search specific parameters.
* @param array $headers
* Authentication and session tokens.
*
* @return object SimpleXml or PEAR_Error
*
* @access public
*/
public function requestSearch($params, $headers) {
$url = self::$end_point . '/Search';
$response = $this->request($url, $params, $headers);
return $response;
}
/**
* Request a specific record.
*
* @param array $params
* Retrieve specific parameters.
* @param array $headers
* Authentication and session tokens.
*
* @return object SimpleXml or PEAR_Error
*
* @access public
*/
public function requestRetrieve($params, $headers) {
$url = self::$end_point . '/Retrieve';
$response = $this->request($url, $params, $headers);
return $response;
}
/**
* Export a specific record.
*
* @param array $params
* Export specific parameters.
* @param array $headers
* Authentication and session tokens.
*
* @return object SimpleXml or PEAR_Error
*
* @access public
*/
public function requestExport($params, $headers) {
$url = self::$end_point . '/ExportFormat';
$response = $this->request($url, $params, $headers);
return $response;
}
/**
* CitationStyles a specific record.
*
* @param array $params
* CitationStyles specific parameters.
* @param array $headers
* Authentication and session tokens.
*
* @return object SimpleXml or PEAR_Error
*
* @access public
*/
public function requestCitationStyles($params, $headers) {
$url = self::$end_point . '/CitationStyles';
$responseCitation = $this->request($url, $params, $headers);
$response = $responseCitation->Citations;
return $response;
}
/**
* Request the info data.
*
* @param null $params
* Not used.
* @param array $headers
* Authentication and session tokens.
*
* @return object SimpleXml or PEAR_Error
*
* @access public
*/
public function requestInfo($params, $headers) {
$url = self::$end_point . '/Info';
$response = $this->request($url, $params, $headers);
return $response;
}
/**
* Send an HTTP request and inspect the response.
*
* @param string $url
* The url of the HTTP request.
* @param array $params
* The parameters of the HTTP request.
* @param array $headers
* The headers of the HTTP request.
* @param array $body
* The body of the HTTP request.
* @param string $method
* The HTTP method, default is 'GET'.
*
* @return object SimpleXml or PEAR_Error
*
* @access protected
*/
protected function request($url, $params, $headers = array(), $method = 'GET') {
$xml = FALSE;
$return = FALSE;
$data = NULL;
if(!is_array($headers)){
$headers = [];
}
// Add compression in case its not there.
array_push($headers, 'Content-Type: text/xml');
$data=$params;
// Send the request.
$response=null;
try {
$curl = curl_init();
curl_setopt($curl, CURLOPT_URL, $url);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($curl, CURLOPT_MAXREDIRS, 10 );
curl_setopt($curl, CURLOPT_FOLLOWLOCATION, 1);
curl_setopt($curl, CURLOPT_TIMEOUT, 10);
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, FALSE);
curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
switch ($method)
{
case 'GET':
if ($data) { $url = sprintf('%s?%s', $url, http_build_query($data)); }
curl_setopt($curl, CURLOPT_URL, $url);
break;
case 'POST':
if ($data) {
curl_setopt($curl,CURLOPT_POST, 1);
curl_setopt($curl,CURLOPT_POSTFIELDS, $data);
}
break;
case 'DELETE':
if ($data) {
if (count($headers)>0) {
curl_setopt($curl,CURLOPT_HTTPHEADER, $headers);
}
curl_setopt($curl, CURLOPT_CUSTOMREQUEST, "DELETE");
}
break;
}
$response = curl_exec($curl);
$code = curl_getinfo($curl, CURLINFO_HTTP_CODE);
curl_close($curl);
switch ($code) {
case self::HTTP_OK:
$xml_str = $response;
try {
// Clean EMP namespace.
$xml_str = str_replace(array("<a:", "</a:"), array("<", "</"), $xml_str);
$xml = simplexml_load_string($xml_str);
$return = $xml;
}
catch (Exception $e) {
$return = new EBSCOException($xml);
}
break;
case self::HTTP_BAD_REQUEST:
$xml_str = $response;
try {
$xml = simplexml_load_string($xml_str);
// If the response is an API error.
$isError = isset($xml->ErrorNumber) || isset($xml->ErrorCode);
if ($isError) {
$error = ''; $code = 0;
if (isset($xml->DetailedErrorDescription) && !empty($xml->DetailedErrorDescription)) {
$error = (string) $xml->DetailedErrorDescription;
}
elseif (isset($xml->ErrorDescription)) {
$error = (string) $xml->ErrorDescription;
}
elseif (isset($xml->Reason)) {
$error = (string) $xml->Reason;
}
if (isset($xml->ErrorNumber)) {
$code = (integer) $xml->ErrorNumber;
}
elseif (isset($xml->ErrorCode)) {
$code = (integer) $xml->ErrorCode;
}
$return = new EBSCOException($error, $code);
}
else {
$return = new EBSCOException("HTTP {$code} : The request could not be understood by the server due to malformed syntax. Modify your search before retrying.");
}
}
catch (Exception $e) {
$return = new EBSCOException($xml);
}
break;
case self::HTTP_NOT_FOUND:
$return = new EBSCOException("HTTP {$code} : The resource you are looking for might have been removed, had its name changed, or is temporarily unavailable.");
break;
case self::HTTP_INTERNAL_SERVER_ERROR:
$return = new EBSCOException("HTTP {$code} : The server encountered an unexpected condition which prevented it from fulfilling the request.");
break;
default:
$return = new EBSCOException("HTTP {$code} : Unexpected HTTP error.");
break;
}
}
catch (Exception $e) {
// Or $this->toString($response)
$message = $this->toString($e);
\Drupal::logger('ebsco')->error($message);
$return = new EBSCOException($response);
}
// Log any error
if ($this->logAPIRequests) {
// $client = both the HTTP request and response
// $response = only the HTTP response
$message = $this->toString($client); // or $this->toString($response)
\Drupal::logger('ebsco')->error($client);
}
return $return;
}
/**
* Capture the output of print_r into a string.
*
* @param object Any object
*
* @access private
*/
private function toString($object) {
ob_start();
print_r($object);
return ob_get_clean();
}
}

1050
modules/roblib_search_eds/src/Lib/EBSCODocument.php

File diff suppressed because it is too large Load Diff

528
modules/roblib_search_eds/src/Lib/EBSCORecord.php

@ -0,0 +1,528 @@
<?php
namespace Drupal\roblib_search_eds\Lib;
/**
* @file
* The EBSCO record object.
*
* PHP version 5
*
* Copyright [2017] [EBSCO Information Services]
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* EBSCORecord class.
*/
class EBSCORecord {
/**
* The array of data.
*
* @global array
*/
private $data = array();
/**
* The result id (the EBSCO counter) of the record.
*
* @global integer
*/
public $result_id = NULL;
/**
* The id of the record.
*
* @global integer
*/
public $record_id = NULL;
/**
* The summary of the record.
*
* @global string
*/
public $summary = NULL;
/**
* The authors of the record.
*
* @global string
*/
public $authors = NULL;
/**
* The subjects of the record.
*
* @global string
*/
public $subjects = NULL;
/**
* The custom links provided for the record.
*
* @global array
*/
public $custom_links = array();
/**
* The database label of the record.
*
* @global string
*/
public $db_label = NULL;
/**
* The full-text availability of the record.
*
* @global boolean
*/
public $full_text_availability = NULL;
/**
* The full text of the record.
*
* @global string
*/
public $full_text = NULL;
/**
* The PDF availability of the record.
*
* @global boolean
*/
public $pdf_availability = NULL;
/**
* The items of the record.
*
* @global array
*/
public $items = array();
/**
* The external link of the record.
*
* @global string
*/
public $p_link = NULL;
/**
* The external link to the PDF version of the record.
*
* @global string
*/
public $pdf_link = NULL;
/**
* The publication type link of the record.
*
* @global string
*/
public $publication_type = NULL;
/**
* The external thumbnails links of the record.
*
* @global string
*/
public $small_thumb_link = NULL;
public $medium_thumb_link = NULL;
/**
* The title of the record.
*
* @global string
*/
public $title = NULL;
/**
* The source of the record.
*
* @global string
*/
public $source = NULL;
/**
* The access level of the record.
*
* @global string
*/
public $access_level = NULL;
/**image quick view
* ImageQuickViewItems
*/
/**
* * @global string
*/
//public $image_quick_view_type = NULL;
public $image_quick_view = array();
public $image_quick_view_type_2 = array();
/**image quick view
* ImageQuickViewItems
*/
/**
* * @global string
*/
public $image_quick_url = NULL;
/* IllustrationInfo
*/
/**
* * @global string
*/
public $illustrationinfo = array();
/**
* Type to IQV
* * @global string
*/
public $type = NULL;
/**
* Cite to IQV
* * @global string
*/
public $cite = NULL;
/**
* Permission to IQV
* * @global string
*/
public $permission = NULL;
/**
* imgTitle to IQV
* * @global string
*/
public $imgtitle = NULL;
/**
*Citations styles
* * @global string
*/
public $citationStylesRecord = NULL;
/**
* Constructor.
*
* @param array $data
* Raw data from the EBSCO search representing the record.
*/
public function __construct($data = array()) {
$this->data = $data;
$this->record_id = $this->record_id();
$this->result_id = $this->result_id();
$this->title = $this->title();
$this->summary = $this->summary();
$this->authors = $this->authors();
$this->subjects = $this->subjects();
$this->custom_links = $this->custom_links();
$this->db_label = $this->db_label();
$this->full_text_availability = $this->full_text_availability();
$this->full_text = $this->full_text();
$this->items = $this->items();
$this->p_link = $this->p_link();
$this->publication_type = $this->publication_type();
$this->pdf_availability = $this->pdf_availability();
$this->pdf_link = $this->pdf_link();
$this->small_thumb_link = $this->thumb_link();
$this->medium_thumb_link = $this->thumb_link('medium');
$this->source = $this->source();
$this->access_level = $this->access_level();
$this->image_quick_view = $this->image_quick_view();
$this->image_quick_view_type_2 = $this->image_quick_view_type_2();
$this->image_quick_url = $this->image_quick_url();
$this->illustrationinfo = $this->illustrationinfo();
$this->type = $this->type();
$this->cite = $this->cite();
$this->permission = $this->permission();
$this->imgtitle = $this->imgtitle();
$this->citationStylesRecord = $this->citationStylesRecord();
}
/********************************************************
*
* Getters
*
********************************************************/
/**
* Get the summary of the record.
*
* @return string
*/
public function access_level() {
return isset($this->data['AccessLevel']) ?
$this->data['AccessLevel'] : '';
}
/**
* Get the summary of the record.
*
* @return string
*/
public function summary() {
return isset($this->data['Items']['Abstract']) ?
$this->data['Items']['Abstract']['Data'] : '';
}
/**
* Get the authors of the record.
*
* @return string
*/
public function authors() {
return isset($this->data['Items']['Author']) ?
$this->data['Items']['Author']['Data'] : '';
}
/**
* Get the custom links of the record.
*
* @return array
*/
public function custom_links() {
return isset($this->data['CustomLinks']) ?
$this->data['CustomLinks'] : array();
}
/**
* Get the database label of the record.
*
* @return string
*/
public function db_label() {
return isset($this->data['DbLabel']) ?
$this->data['DbLabel'] : '';
}
/**
* Get the full text availability of the record.
*
* @return bool
*/
public function full_text() {
return isset($this->data['FullText']) &&
isset($this->data['FullText']['Value']) ? $this->data['FullText']['Value'] : '';
}
/**
* Get the full text availability of the record.
*
* @return bool
*/
public function full_text_availability() {
return isset($this->data['FullText']) &&
$this->data['FullText']['Availability'];
}
/**
* Get the items of the record.
*
* @return array
*/
public function items() {
return isset($this->data['Items']) ? $this->data['Items'] : array();
}
/**
* Get the external url of the record.
*
* @return string
*/
public function p_link() {
return isset($this->data['PLink']) ? $this->data['PLink'] : '';
}
/**
* Get the publication type of the record.
*
* @return string
*/
public function publication_type() {
return isset($this->data['PubType']) ? $this->data['PubType'] : '';
}
/**
* Get the PDF availability of the record.
*
* @return bool
*/
public function pdf_availability() {
return isset($this->data['FullText']) &&
isset($this->data['FullText']['Links']) &&
isset($this->data['FullText']['Links']['pdflink']) &&
$this->data['FullText']['Links']['pdflink'];
}
/**
* Get the PDF url of the record.
*
* @return string
*/
public function pdf_link() {
return isset($this->data['FullText']) &&
isset($this->data['FullText']['Links']) &&
isset($this->data['FullText']['Links']['pdflink']) ?
$this->data['FullText']['Links']['pdflink'] :
'';
}
/**
* Get the result id of the record.
*
* @return int
*/
public function result_id() {
return isset($this->data['ResultId']) ?
$this->data['ResultId'] : '';
}
/**
* Get the subject data of the record.
*
* @return string
*/
public function subjects() {
return isset($this->data['Items']['Subject']) ?
$this->data['Items']['Subject']['Data'] : '';
}
/**
* Return a URL to a thumbnail preview of the record, if available; false
* otherwise.
*
* @param string $size
* Size of thumbnail (small, medium or large -- small is
* default).
*
* @return string
*/
public function thumb_link($size = 'small') {
$imageInfo = isset($this->data['ImageInfo']) ? $this->data['ImageInfo'] : '';
if ($imageInfo && isset($imageInfo['thumb'])) {
switch ($size) {
case 'large':
case 'medium':
return $imageInfo['medium'];
break;
case 'small':
default:
return $imageInfo['thumb'];
break;
}
}
return FALSE;
}
/**
* Get the title of the record.
*
* @return string
*/
public function title() {
return isset($this->data['Items']['Title']) ?
$this->data['Items']['Title']['Data'] : '';
}
/**
* Get the source of the record.
*
* @return string
*/
public function source() {
return isset($this->data['Items']['TitleSource']) ?
$this->data['Items']['TitleSource']['Data'] : '';
}
/**
* Return the identifier of this record within the EBSCO databases.
*
* @return string Unique identifier.
*/
public function record_id() {
return isset($this->data['id']) ?
$this->data['id'] : '';
}
/**
* Get the image quick view of the record.
*
* @return string
*/
public function image_quick_view() {
return isset($this->data['iqv']) ? $this->data['iqv'] : array();
}
public function image_quick_url() {
return isset($this->data['iqv']) ? $this->data['iqv'] : array();
}
public function image_quick_view_type_2() {
return isset($this->data['ImageQuickViewItems']) &&
isset($this->data['ImageQuickViewItems']['iqv']) &&
isset($this->data['ImageQuickViewItems']['iqv']['DbId']) &&
isset($this->data['ImageQuickViewItems']['iqv']['An']) &&
isset($this->data['ImageQuickViewItems']['iqv']['Type']) &&
isset($this->data['ImageQuickViewItems']['iqv']['Url']) ?
$this->data['ImageQuickViewItems']['iqv']['DbId']['An']['Type']['Url'] : '';
}
public function illustrationinfo() {
return isset($this->data['IllustrationInfo'][0]) ? $this->data['IllustrationInfo'][0] : array();
}
public function type() {
return isset($this->data['Items']['type']) ?
$this->data['Items']['type'] : '';
}
public function cite() {
return isset($this->data['Items']['Cite']) ?
$this->data['Items']['Cite'] : '';
}
public function permission() {
return isset($this->data['Items']['Permission']) ?
$this->data['Items']['Permission'] : '';
}
public function imgtitle() {
return isset($this->data['Items']['imgTitle']) ?
$this->data['Items']['imgTitle'] : '';
}
public function citationStylesRecord() {
return isset($this->data['Citation']) ? $this->data['Citation'] : array();
}
}

1056
modules/roblib_search_eds/src/Lib/EBSCOResponse.php

File diff suppressed because it is too large Load Diff

14
modules/roblib_search_eds/src/Lib/RoblibEBSCOAPI.php

@ -0,0 +1,14 @@
<?php
namespace Drupal\roblib_search_eds\Lib;
use Drupal\roblib_search_eds\Lib\EBSCOAPI;
/**
* Wrapper for the EBSCOAPI class that allows config to be set.
*
* @author ppound
*/
class RoblibEBSCOAPI extends EBSCOAPI{
public function setConfig($config) {
$this->config = $config;
}
}

446
modules/roblib_search_eds/src/Lib/sanitizer.class.php

@ -0,0 +1,446 @@
<?php
namespace Drupal\roblib_search_eds\Lib;
/**
* @file
* $Id$.
*/
// vim: expandtab sw=4 ts=4 sts=4:
// ***** BEGIN LICENSE BLOCK *****
// This file is part of HTML Sanitizer.
// Copyright (c) 2005-2011 Frederic Minne <zefredz@gmail.com>.
// All rights reserved.
//
// HTML Sanitizer is free software; you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation; either version 3 of the License, or
// (at your option) any later version.
//
// HTML Sanitizer is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with HTML Sanitizer; if not, see <https://www.gnu.org/licenses/>.
//
// ***** END LICENSE BLOCK *****.
/**
* Sanitize HTML contents :
* Remove dangerous tags and attributes that can lead to security issues like
* XSS or HTTP response splitting.
*
* @author Frederic Minne <zefredz@gmail.com>
* @copyright Copyright &copy; 2005-2011, Frederic Minne
* @license https://www.gnu.org/licenses/lgpl.txt GNU Lesser General Public License version 3 or later
* @version 1.1
*/
class HTML_Sanitizer {
/**
* Private fields.
*/
private $_allowedTags;
private $_allowJavascriptEvents;
private $_allowJavascriptInUrls;
private $_allowObjects;
private $_allowScript;
private $_allowStyle;
private $_additionalTags;
/**
* Constructor.
*/
public function __construct() {
$this->resetAll();
}
/**
* (re)set all options to default value.
*/
public function resetAll() {
$this->_allowDOMEvents = FALSE;
$this->_allowJavascriptInUrls = FALSE;
$this->_allowStyle = FALSE;
$this->_allowScript = FALSE;
$this->_allowObjects = FALSE;
$this->_allowStyle = FALSE;
$this->_allowedTags = '<a><br><b><h1><h2><h3><h4><h5><h6>'
. '<img><li><ol><p><strong><table><tr><td><th><u><ul><thead>'
. '<tbody><tfoot><em><dd><dt><dl><span><div><del><add><i><hr>'
. '<pre><br><blockquote><address><code><caption><abbr><acronym>'
. '<cite><dfn><q><ins><sup><sub><kbd><samp><var><tt><small><big>';
$this->_additionalTags = '';
}
/**
* Add additional tags to allowed tags.
*
* @param string
*
* @access public
*/
public function addAdditionalTags($tags) {
$this->_additionalTags .= $tags;
}
/**
* Allow iframes.
*
* @access public
*/
public function allowIframes() {
$this->addAdditionalTags('<iframe>');
}
/**
* Allow HTML5 media tags.
*
* @access public
*/
public function allowHtml5Media() {
$this->addAdditionalTags('<canvas><video><audio>');
}
/**
* Allow object, embed, applet and param tags in html.
*
* @access public
*/
public function allowObjects() {
$this->_allowObjects = TRUE;
}
/**
* Allow DOM event on DOM elements.
*
* @access public
*/
public function allowDOMEvents() {
$this->_allowDOMEvents = TRUE;
}
/**
* Allow script tags.
*
* @access public
*/
public function allowScript() {
$this->_allowScript = TRUE;
}
/**
* Allow the use of javascript: in urls.
*
* @access public
*/
public function allowJavascriptInUrls() {
$this->_allowJavascriptInUrls = TRUE;
}
/**
* Allow style tags and attributes.
*
* @access public
*/
public function allowStyle() {
$this->_allowStyle = TRUE;
}
/**
* Helper to allow all javascript related tags and attributes.
*
* @access public
*/
public function allowAllJavascript() {
$this->allowDOMEvents();
$this->allowScript();
$this->allowJavascriptInUrls();
}
/**
* Allow all tags and attributes.
*
* @access public
*/
public function allowAll() {
$this->allowAllJavascript();
$this->allowObjects();
$this->allowStyle();
$this->allowIframes();
$this->allowHtml5Media();
}
/**
* Filter URLs to avoid HTTP response splitting attacks.
*
* @access public
* @param string url
*
* @return string filtered url
*/
public function filterHTTPResponseSplitting($url) {
$dangerousCharactersPattern = '~(\r\n|\r|\n|%0a|%0d|%0D|%0A)~';
return preg_replace($dangerousCharactersPattern, '', $url);
}
/**
* Remove potential javascript in urls.
*
* @access public
* @param string url
*
* @return string filtered url
*/
public function removeJavascriptURL($str) {
$HTML_Sanitizer_stripJavascriptURL = 'javascript:[^"]+';
$str = preg_replace("/$HTML_Sanitizer_stripJavascriptURL/i", '__forbidden__', $str);
return $str;
}
/**
* Remove potential flaws in urls.
*
* @access private
* @param string url
*
* @return string filtered url
*/
private function sanitizeURL($url) {
if (!$this->_allowJavascriptInUrls) {
$url = $this->removeJavascriptURL($url);
}
$url = $this->filterHTTPResponseSplitting($url);
return $url;
}
/**
* Callback for PCRE.
*
* @access private
* @param matches array
*
* @return string
*
* @see sanitizeURL
*/
private function _sanitizeURLCallback($matches) {
return 'href="' . $this->sanitizeURL($matches[1]) . '"';
}
/**
* Remove potential flaws in href attributes.
*
* @access private
* @param string html tag
*
* @return string filtered html tag
*/
private function sanitizeHref($str) {
$HTML_Sanitizer_URL = 'href="([^"]+)"';
return preg_replace_callback("/$HTML_Sanitizer_URL/i", array(&$this, '_sanitizeURLCallback'), $str);
}
/**
* Callback for PCRE.
*
* @access private
* @param matches array
*
* @return string
*
* @see sanitizeURL
*/
private function _sanitizeSrcCallback($matches) {
return 'src="' . $this->sanitizeURL($matches[1]) . '"';
}
/**
* Remove potential flaws in href attributes.
*
* @access private
* @param string html tag
*
* @return string filtered html tag
*/
private function sanitizeSrc($str) {
$HTML_Sanitizer_URL = 'src="([^"]+)"';
return preg_replace_callback("/$HTML_Sanitizer_URL/i", array(&$this, '_sanitizeSrcCallback'), $str);
}
/**
* Remove dangerous attributes from html tags.
*
* @access private
* @param string html tag
*
* @return string filtered html tag
*/
private function removeEvilAttributes($str) {
if (!$this->_allowDOMEvents) {
$str = preg_replace_callback('/<(.*?)>/i', array(&$this, '_removeDOMEventsCallback'), $str);
}
if (!$this->_allowStyle) {
$str = preg_replace_callback('/<(.*?)>/i', array(&$this, '_removeStyleCallback'), $str);
}
return $str;
}
/**
* Remove DOM events attributes from html tags.
*
* @access private
* @param string html tag
*
* @return string filtered html tag
*/
private function removeDOMEvents($str) {
$str = preg_replace('/\s*=\s*/', '=', $str);
$HTML_Sanitizer_stripAttrib = '(onclick|ondblclick|onmousedown|'
. 'onmouseup|onmouseover|onmousemove|onmouseout|onkeypress|onkeydown|'
. 'onkeyup|onfocus|onblur|onabort|onerror|onload)';
$str = stripslashes(preg_replace("/$HTML_Sanitizer_stripAttrib/i", 'forbidden', $str));
return $str;
}
/**
* Callback for PCRE.
*
* @access private
* @param matches array
*
* @return string
*
* @see removeDOMEvents
*/
private function _removeDOMEventsCallback($matches) {
return '<' . $this->removeDOMEvents($matches[1]) . '>';
}
/**
* Remove style attributes from html tags.
*
* @access private
* @param string html tag
*
* @return string filtered html tag
*/
private function removeStyle($str) {
$str = preg_replace('/\s*=\s*/', '=', $str);
$HTML_Sanitizer_stripAttrib = '(style)';
$str = stripslashes(preg_replace("/$HTML_Sanitizer_stripAttrib/i", 'forbidden', $str));
return $str;
}
/**
* Callback for PCRE.
*
* @access private
* @param matches array
*
* @return string
*
* @see removeStyle
*/
private function _removeStyleCallback($matches) {
return '<' . $this->removeStyle($matches[1]) . '>';
}
/**
* Remove dangerous HTML tags.
*
* @access private
* @param string html code
*
* @return string filtered url
*/
private function removeEvilTags($str) {
$allowedTags = $this->_allowedTags;
if ($this->_allowScript) {
$allowedTags .= '<script>';
}
if ($this->_allowStyle) {
$allowedTags .= '<style>';
}
if ($this->_allowObjects) {
$allowedTags .= '<object><embed><applet><param>';
}
$allowedTags .= $this->_additionalTags;
$str = strip_tags($str, $allowedTags);
return $str;
}
/**
* Sanitize HTML
* remove dangerous tags and attributes
* clean urls.
*
* @access public
* @param string html code
*
* @return string sanitized html code
*/
public function sanitize($html) {
$html = $this->removeEvilTags($html);
$html = $this->removeEvilAttributes($html);
$html = $this->sanitizeHref($html);
$html = $this->sanitizeSrc($html);
return $html;
}
}
/**
*
*/
function html_sanitize($str) {
static $san = NULL;
if (empty($san)) {
$san = new HTML_Sanitizer();
}
return $san->sanitize($str);
}
/**
*
*/
function html_loose_sanitize($str) {
static $san = NULL;
if (empty($san)) {
$san = new HTML_Sanitizer();
$san->allowAll();
}
return $san->sanitize($str);
}

53
modules/roblib_search_eds/src/Plugin/Block/RoblibSearchEdsArticles.php

@ -0,0 +1,53 @@
<?php
namespace Drupal\roblib_search_eds\Plugin\Block;
use Drupal\Core\Block\BlockBase;
/**
* Provides EDS Article search results.
*
* @Block(
* id = "roblib_search_eds_articles_block",
* admin_label = @Translation("Roblib Search EDS Articles Block"),
* category = @Translation("Roblib Search"),
* )
*/
class RoblibSearchEdsArticles extends BlockBase {
/**
* {@inheritdoc}
*/
public function build() {
$host = \Drupal::request()->getSchemeAndHttpHost();
$search_url = $host . '/roblib_search/eds/articles/';
$eds_profile = \Drupal::config('roblib_search_eds.settings')
->get('eds_article_profile');
$settings = [
'eds_article_search_url' => $search_url,
'eds_article_profile' => $eds_profile,
];
return [
'#theme' => 'roblib_search_eds_articles',
'query' => $query,
'#attached' => [
'library' => [
'roblib_search_eds/eds-article'
],
'drupalSettings' => $settings,
],
];
}
/**
* {@inheritdoc}
*/
public function getCacheMaxAge() {
// Reading dynamic content from external source so no caching.
if (\Drupal::currentUser()->isAnonymous()) {
// Anonymous user...
return 0;
}
}
}

54
modules/roblib_search_eds/src/Plugin/Block/RoblibSearchEdsBooks.php

@ -0,0 +1,54 @@
<?php
namespace Drupal\roblib_search_eds\Plugin\Block;
use Drupal\Core\Block\BlockBase;
/**
* Provides EDS book search results.
*
* @Block(
* id = "roblib_search_eds_books_block",
* admin_label = @Translation("Roblib Search EDS Books Block"),
* category = @Translation("Roblib Search"),
* )
*/
class RoblibSearchEdsBooks extends BlockBase {
/**
* {@inheritdoc}
*/
public function build() {
$host = \Drupal::request()->getSchemeAndHttpHost();
$search_url = $host . '/roblib_search/eds/book/';
$eds_profile = \Drupal::config('roblib_search_eds.settings')
->get('eds_book_profile');
$settings = [
'eds_book_search_url' => $search_url,
'eds_book_profile' => $eds_profile,
];
return [
'#theme' => 'roblib_search_eds_books',
//'query' => $query,
'#attached' => [
'library' => [
'roblib_search_eds/eds-book'
],
'drupalSettings' => $settings,
],
];
}
/**
* {@inheritdoc}
*/
public function getCacheMaxAge() {
// Reading dynamic content from external source so no caching.
if (\Drupal::currentUser()->isAnonymous()) {
// Anonymous user...
return 0;
}
}
}

12
modules/roblib_search_eds/templates/roblib-search-eds-articles.html.twig

@ -0,0 +1,12 @@
<div class="panel-pane pane-block pane-roblib-search-eds-roblib-search-eds-results pane-roblib-search-eds">
<div class="roblib-search-header roblib-search-eds-articles-header"><h3>Articles</h3></div>
<div class ="roblib-search-more" id="roblib-search-eds-article-more"></div>
<div class ="roblib-search-content eds-article" id="roblib-search-content-eds-articles">
<img src="{{ spinner_path }}"/>
</div>
<div id="roblib-eds-articles-more-results" class="roblib-eds-more-button button"></div>
<div id="roblib-eds-articles-toc" class="roblib-bento-toc moveme-please"></div>
</div>

13
targets/eds/theme/roblib-search-eds.tpl.php → modules/roblib_search_eds/templates/roblib-search-eds-books.html.twig

@ -1,15 +1,10 @@
<?php <div class="panel-pane pane-block pane-roblib-search-eds-roblib-search-eds-results pane-roblib-search-eds">
<div class="roblib-search-header roblib-search-eds-media-header"><h3>Books</h3></div>
/**
* @file roblib-search-eds.tpl.php
*
*/
?>
<div class ="roblib-search-more" id="roblib-search-eds-more"></div> <div class ="roblib-search-more" id="roblib-search-eds-more"></div>
<div class ="roblib-search-content eds" id="roblib-search-content-eds"> <div class ="roblib-search-content eds" id="roblib-search-content-eds">
<img src="<?php print (empty($spinner_path) ? ' ' : $spinner_path); ?>"/> <img src="{{ spinner_path }}"/>
</div> </div>
<div id="roblib-eds-books-more-results" class="roblib-eds-more-button button"></div> <div id="roblib-eds-books-more-results" class="roblib-eds-more-button button"></div>
<div id="roblib-eds-books-toc" class="roblib-bento-toc moveme-please"></div> <div id="roblib-eds-books-toc" class="roblib-bento-toc moveme-please"></div>
</div>

38
modules/solr_site/README.md

@ -0,0 +1,38 @@
# Roblib Solr Search
## Table of contents
- Introduction
- Requirements
- Configuration
- Maintainers
## Introduction
Creates a block that can be used for bento box type results. Used by the
roblib_search module.
## Requirements
Requires roblib_search module. Also assumes Solr Search API is installed and
the index has fields for body, body summary, type, rendered_item and
search_api_url
For the BestBet block we also need a content type of bestbet with title, body
link fields (field_link). The field_link will also have to be added to the
solr index.
## Configuration
### Plugins
## Maintainers
### Current maintainers

0
targets/solr_site/css/roblib_search_solr_site.css → modules/solr_site/css/roblib_search_solr_site.css

35
modules/solr_site/js/solr_site_bestbet.js

@ -0,0 +1,35 @@
Drupal.behaviors.roblib_search_solr_bestbet_results = {
attach: function (context, settings) {
if (context == document) {
query = drupalSettings.path.currentPath.replace('roblib_search/', '');
solrUrl = settings.solr_site_search_url + query;
baseUrl = settings.solr_bestbet_base_url + query;
jQuery.getJSON(baseUrl, function (data) {
var items = [];
total_found = data.resultCount;
if (total_found < 1) {
jQuery('#' + 'roblib-search-content-solr-site-bestbet').empty().append('No Results');
jQuery('.' + 'pane-roblib-search-solr-site-roblib-search-solr-site-bestbet').hide();
jQuery('.' + 'pane-roblib-search-solr-site-roblib-search-solr-site-' . solrType).hide();
} else {
jQuery('#' + 'roblib-search-content-solr-site-bestbet').empty();
var counter = 0;
var divs = new Array();
var content = new Array();
jQuery.each(data.results, function (key, val) {
id = 'roblib_search_solr_results_bestbet-' + counter;
content[counter] = val.teaser;
divs[counter++] = id;
items.push('<div class ="roblib-search-row" id="' + id + '">\n\
<span class="roblib-title results">\n\
<a href="' + val.field_link + '">' + val.title + '</a></span>' +
'\n\<span class="roblib-solr-bundle">(' + val.type + ')</span> <span class="roblib-solr-teaser"> ' + val.body + '</span></div>');
});
jQuery('#' + 'roblib-search-content-solr-site-bestbet').empty().append(items.join(''));
}
});
}
}
}

0
targets/solr_site/js/solr_site_databases.js → modules/solr_site/js/solr_site_databases.js

0
targets/solr_site/js/solr_site_guides.js → modules/solr_site/js/solr_site_guides.js

0
targets/solr_site/js/solr_site_reserves.js → modules/solr_site/js/solr_site_reserves.js

44
modules/solr_site/js/solr_site_results.js

@ -0,0 +1,44 @@
Drupal.behaviors.roblib_search_solr_site_results = {
attach: function (context, settings) {
if (context == document) {
unencoded_query = drupalSettings.path.currentPath.replace('roblib_search/', '');
query = encodeURIComponent(unencoded_query);
solrUrl = settings.solr_site_search_url + query;
baseUrl = settings.solr_site_base_url + query;
jQuery.getJSON(baseUrl, function (data) {
var items = [];
total_found = data.resultCount;
if (total_found < 1) {
jQuery('#' + 'roblib-search-content-solr-site-results').empty().append('No Results');
jQuery('.' + 'pane-roblib-search-solr-site-roblib-search-solr-site-results').hide();
} else {
jQuery('#' + 'roblib-search-content-solr-site-results').empty();
var counter = 0;
var divs = new Array();
var content = new Array();
jQuery.each(data.results, function (key, val) {
id = 'roblib_search_solr_results_' + counter;
content[counter] = val.teaser;
divs[counter++] = id;
items.push('<div class ="roblib-search-row" id="' + id + '">\n\
<span class="roblib-title results">\n\
<a href="' + val.url + '">' + val.title + '</a></span>' +
'\n\<span class="roblib-solr-bundle">(' + val.type + ')</span> <span class="roblib-solr-teaser"> ' + val.body + '</span></div>');
});
jQuery('#' + 'roblib-search-content-solr-site-results').empty().append(items.join(''));
}
if (total_found > 0) {
results_url = '<a href=\'' + solrUrl + '\'>see all results ('
+ total_found + ') </a>';
move_me_div_url = '<a href=\'' + solrUrl + '\'>Library Site ('
+ total_found + ') </a>';
jQuery('#' + 'roblib-search-solr-site-results-more').empty().append(results_url);
jQuery('#' + 'roblib-solr-more-results-results').empty().append(results_url);
jQuery('#' + 'roblib-solr-search-toc-results').empty().append(move_me_div_url);
}
});
}
}
}

8
modules/solr_site/roblib_search_solr_site.info.yml

@ -0,0 +1,8 @@
name: Roblib Search Solr site
type: module
configure: roblib_search_solr_site.settings
description: Implements the Roblib Search for local Solr site bento results
package: Roblib Search
core_version_requirement: ^9 || ^10
dependancies:
- roblib_search

15
modules/solr_site/roblib_search_solr_site.libraries.yml

@ -0,0 +1,15 @@
solr-site:
version: 1.x
css:
base:
css/roblib_search_solr_site.css: {}
js:
js/solr_site_results.js: {}
dependencies:
- core/drupal
solr-bestbet:
version: 1.x
js:
js/solr_site_bestbet.js: {}
dependencies:
- core/drupal

100
modules/solr_site/roblib_search_solr_site.module

@ -0,0 +1,100 @@
<?php
/**
* @file
* Implementation of Roblib search for searching several targets.
*/
/**
/**
* Implements hook_theme().
*/
function roblib_search_solr_site_theme($existing, $type, $theme, $path) {
$modulePath = \Drupal::service('module_handler')->getModule('roblib_search')
->getPath();
$spinner_path = '/' . $modulePath . "/img/spinner.gif";
return [
'roblib_search_solr_site_results' => [
'variables' => ['solr_type' => 'results', 'spinner_path' => $spinner_path],
],
'roblib_search_solr_site_bestbet' => [
'variables' => ['solr_type' => 'bestbet', 'spinner_path' => $spinner_path],
],
];
}
/**
* Send the query to solr but limit the results so it doesn't include certain content.
*
* Print json and exit so the javascript can consume the json.
*
* @param string $query
* The solr search string.
*/
/*function roblib_search_solr_site_results($query) {
print roblib_search_solr_site_get_results($query, '-bundle:bestbet');
exit();
}*/
/**
* Send the query to solr but limit the results so it only includes content of type bestbet.
*
* Print json and exit so the javascript can consume the json.
*
* @param string $query
* The solr search string.
*/
/*function roblib_search_solr_site_bestbet($query) {
$query = str_replace('"', '', $query);
$json = roblib_search_solr_site_get_results("sort_label:$query", 'bundle:bestbet');
$json = roblib_search_solr_site_add_url($json);
print $json;
exit();
}*/
/**
*
* Updates the json passed in with a url directly to the target of the link field.
* This information is not in solr as it comes from a custom field.
*
*
* @param string $json
* The json string returned from the solr query.
*
* @return string
* json we got from solr with an updated url directly to the target of the link field
*/
/*function roblib_search_solr_site_add_url($json) {
$responses = json_decode($json);
foreach ($responses->response->docs as &$doc) {
$nid = $doc->entity_id;
// The link field is a complex field and we get the text in solr but not the actual url.
// Since best best will only every return one result it's not much overhead to load the node
// and get the value of the link field. probably less overhead then installing additional
// modules to get the url in solr.
$node = node_load($nid);
$url = $node->field_link['und'][0]['url'];
$doc->url = $url;
}
return json_encode($responses);
}
*/
/**
* Implements hook_help().
*/
function roblib_search_solr_site_help($path, $arg) {
switch ($path) {
case 'admin/help#roblib_search_solr_site':
return t(
'<p>
provides a Solr target for the Roblib search module
</p>'
);
}
}

24
modules/solr_site/roblib_search_solr_site.routing.yml

@ -0,0 +1,24 @@
roblib_search_solr_site.settings:
path: '/admin/config/system/roblib_search_solr_site_settings'
defaults:
_form: '\Drupal\roblib_search_solr_site\Form\SolrsiteSettingsForm'
_title: 'Roblib Search Solr Site Settings Form'
requirements:
_permission: 'administer site configuration'
roblib_search_solr_site.bestbet_search:
path: '/roblib_search/solr_site/bestbet/{query}'
defaults:
_controller: '\Drupal\roblib_search_solr_site\Controller\RoblibSearchSolrsiteController::bestbetResults'
_title: 'Roblib Search Bestbet'
query: '[a-zA-Z\s]+'
requirements:
_permission: 'access content'
roblib_search_solr_site.general_search:
path: '/roblib_search/solr_site/general/{query}'
defaults:
_controller: '\Drupal\roblib_search_solr_site\Controller\RoblibSearchSolrsiteController::generalResults'
_title: 'Roblib Search Solr Site Search'
query: '[a-zA-Z\s]+'
requirements:
_permission: 'access content'

124
modules/solr_site/src/Controller/RoblibSearchSolrsiteController.php

@ -0,0 +1,124 @@
<?php
namespace Drupal\roblib_search_solr_site\Controller;
use Drupal\Core\Controller\ControllerBase;
/**
* Controller for d3 graphs.
*/
class RoblibSearchSolrsiteController extends ControllerBase {
/**
* Print JSON.
*
*/
public function bestbetResults($query = NULL) {
print $this->getResults($query, 'BestBet');
exit();
}
/**
* Print JSON.
*
*/
public function generalResults($query = NULL) {
print $this->getResults($query, 'General');
exit();
}
/**
* Query Solr for site results.
* @param string $queryString
* The search term(s) to send to Solr.
* @param string type
* The type of search, either BestBet or General.
* @return string
* A JSON string
*/
function getResults($queryString = NULL, $solr_type = 'General') {
global $base_url;
$config = \Drupal::config('roblib_search_solr_site.settings');
// Url parameters.
if (!isset($queryString)) {
if (isset($_GET['roblib_query'])) {
$queryString = $_GET['roblib_query'];
}
else {
return '';
}
}
//$queryString = urlencode($queryString);
// TODO make the index configurable.
$index = \Drupal\search_api\Entity\Index::load('library');
$query = $index->query();
// Change the parse mode for the search.
$parse_mode = \Drupal::service('plugin.manager.search_api.parse_mode')
->createInstance('direct');
$parse_mode->setConjunction('OR');
$query->setParseMode($parse_mode);
// Restrict the search to specific languages.
//$query->setLanguages(['en']);
$query->keys($queryString);
if ($solr_type == 'BestBet') {
$query->addCondition('type', 'bestbet', '=');
$query->setFulltextFields(['title_1']);
if(str_starts_with($queryString, '"')) {
$query->keys($queryString);
} else {
$query->keys('"'.$queryString.'"');
}
} else {
$query->addCondition('type', 'bestbet', '<>');
}
// $query->setFulltextFields(['rendered_item', 'title', 'body']);
$query->range(0, 5);
$query->sort('search_api_relevance', 'DESC');
$results = $query->execute();
$output = [];
$output['resultCount'] = $results->getResultCount();
$output['results'] = [];
foreach ($results as $result) {
$id = $result->getId();
$title = $result->getField('title');
if(empty($title)){
break;
}
$titles = $title->getValues();
$output['results'][$id]['title'] = reset($titles);
$body = $result->getField('body')->getValues();
if (!empty($body)) {
$bodyOutput = strip_tags($body[0]->getText());
if (strlen($bodyOutput) > 500) {
$bodyOutput = substr($bodyOutput, 0, 499) . '...';
}
}
$output['results'][$id]['body'] = empty($bodyOutput) ? '' : $bodyOutput;
//$rendered_items = $result->getField('rendered_item')->getValues();
// $output['rendered_item'] = $rendered_items[0]->getText();
$summarys = $result->getField('summary')->getValues();
$output['results'][$id]['summary'] = empty($summmarys) ? '' : reset($summarys);
$type = $result->getField('type')->getValues();
$output['results'][$id]['type'] = reset($type);
$urls = $result->getField('url')->getValues();
$output['results'][$id]['url'] = reset($urls);
if ($solr_type == 'BestBet') {
$entity = $result->getOriginalObject()->getValue();
$output['results'][$id]['title'] = $entity->field_link->first()->title;
}
$links = $result->getField('field_link')->getValues();
$output['results'][$id]['field_link'] = empty($links) ? '' : $links;
}
echo json_encode($output);
exit();
}
}

67
modules/solr_site/src/Form/SolrsiteSettingsForm.php

@ -0,0 +1,67 @@
<?php
namespace Drupal\roblib_search_solr_site\Form;
use Drupal\Core\Form\FormBase;
use Drupal\Core\Form\FormStateInterface;
/**
* Settings form for module
*
* @author ppound
*/
class SolrsiteSettingsForm extends FormBase {
/**
* {@inheritdoc}
*/
public function getFormId() {
return 'roblib_search_solr_settings_form';
}
/**
* {@inheritdoc}
*/
public function buildForm(array $form, FormStateInterface $form_state) {
$config = \Drupal::config('roblib_search_solr_site.settings');
$form['solr_site_url'] = array(
'#type' => 'textfield',
'#title' => t('Solr URL'),
'#default_value' => $config->get('solr_site_url'),
'#description' => t('The base Solr URL, for example /search/node?keys='),
'#required' => TRUE,
);
$form['solr_site_num_results'] = array(
'#type' => 'textfield',
'#title' => t('Number of results to return'),
'#default_value' => $config->get('solr_site_num_results'),
'#description' => t('The number of results to display in the Bento box'),
'#required' => TRUE,
);
$form['actions']['submit'] = [
'#type' => 'submit',
'#value' => t('Save'),
'#button_type' => 'primary',
];
return $form;
}
/**
* {@inheritdoc}
*/
public function validateForm(array &$form, FormStateInterface $form_state) {
}
/**
* {@inheritdoc}
*/
public function submitForm(array &$form, FormStateInterface $form_state) {
$config = \Drupal::configFactory()->getEditable('roblib_search_solr_site.settings');
$config->set('solr_site_url', $form_state->getValue('solr_site_url'))->save();
$config->set('solr_site_num_results', $form_state->getValue('solr_site_num_results'))->save();
}
}

51
modules/solr_site/src/Plugin/Block/RoblibSearchSolrsiteBestbet.php

@ -0,0 +1,51 @@
<?php
namespace Drupal\roblib_search_solr_site\Plugin\Block;
use Drupal\Core\Block\BlockBase;
/**
* Provides EDS Article search results.
*
* @Block(
* id = "roblib_search_solr_site_bestbet_block",
* admin_label = @Translation("Roblib Search Solr Bestbet Block"),
* category = @Translation("Roblib Search"),
* )
*/
class RoblibSearchSolrSiteBestbet extends BlockBase {
/**
* {@inheritdoc}
*/
public function build() {
$search_url = \Drupal::config('roblib_search_solr_site.settings')
->get('solr_site_url');
$settings = [
'solr_site_search_url' => $search_url,
'solr_bestbet_base_url' => '/roblib_search/solr_site/bestbet/',
];
return [
'#theme' => 'roblib_search_solr_site_bestbet',
//'#solr_type' => 'bestbet',
'#attached' => [
'library' => [
'roblib_search_solr_site/solr-bestbet'
],
'drupalSettings' => $settings,
],
];
}
/**
* {@inheritdoc}
*/
public function getCacheMaxAge() {
// Reading dynamic content from external source so no caching.
if (\Drupal::currentUser()->isAnonymous()) {
// Anonymous user...
return 0;
}
}
}

53
modules/solr_site/src/Plugin/Block/RoblibSearchSolrsiteGeneral.php

@ -0,0 +1,53 @@
<?php
namespace Drupal\roblib_search_solr_site\Plugin\Block;
use Drupal\Core\Block\BlockBase;
/**
* Provides EDS book search results.
*
* @Block(
* id = "roblib_search_solr_site_general_block",
* admin_label = @Translation("Roblib Search Solr Site Block"),
* category = @Translation("Roblib Search"),
* )
*/
class RoblibSearchSolrsiteGeneral extends BlockBase {
/**
* {@inheritdoc}
*/
public function build() {
$search_url = \Drupal::config('roblib_search_solr_site.settings')
->get('solr_site_url');
$settings = [
'solr_site_search_url' => $search_url,
'solr_site_base_url' => '/roblib_search/solr_site/general/',
'solr_type' => 'results',
'solr_site_search_url' => $search_url,
];
return [
'#theme' => 'roblib_search_solr_site_results',
//'#solr_type' => 'results',
'#attached' => [
'library' => [
'roblib_search_solr_site/solr-site'
],
'drupalSettings' => $settings,
],
];
}
/**
* {@inheritdoc}
*/
public function getCacheMaxAge() {
// Reading dynamic content from external source so no caching.
if (\Drupal::currentUser()->isAnonymous()) {
// Anonymous user...
return 0;
}
}
}

10
modules/solr_site/templates/roblib-search-solr-site-bestbet.html.twig

@ -0,0 +1,10 @@
<div class="panel-pane pane-block pane-roblib-search-solr-site-roblib-search-solr-site-bestbet pane-roblib-search-solr-site">
<div class="roblib-search-header roblib-search-solr-bestbet-header" id="roblib-search-solr-site-bestbet-title"><h3>Best Bet</h3></div>
<div class ="roblib-search-more" id="roblib-search-solr-site-{{ solr_type }}-more"></div>
<div class ="roblib-search-content solr-site-{{ solr_type }}" id="roblib-search-content-solr-site-{{ solr_type }}">
<img src="{{ spinner_path }}"/>
</div>
<div id="roblib-solr-more-results-{{ solr_type }}" class="roblib-solr-more-button "></div>
<div id="roblib-solr-search-toc-{{ solr_type }}" class="roblib-bento-toc moveme-please"></div>
</div>

10
modules/solr_site/templates/roblib-search-solr-site-results.html.twig

@ -0,0 +1,10 @@
<div class="panel-pane pane-block pane-roblib-search-solr-site-roblib-search-solr-site-results pane-roblib-search-solr-site">
<div class="roblib-search-header roblib-search-solr-results-header"><h3>Library Site</h3></div>
<div class ="roblib-search-more" id="roblib-search-solr-site-{{ solr_type }}-more"></div>
<div class ="roblib-search-content solr-site-{{ solr_type }}" id="roblib-search-content-solr-site-{{ solr_type }}">
<img src="{{ spinner_path }}"/>
</div>
<div id="roblib-solr-more-results-{{ solr_type }}" class="roblib-solr-more-button "></div>
<div id="roblib-solr-search-toc-{{ solr_type }}" class="roblib-bento-toc moveme-please"></div>
</div>

9
roblib_search.info

@ -1,9 +0,0 @@
name = Roblib Search
configure = admin/roblib_search/configure
description = Provides a search form and fires a hook when the search is submitted. Other modules should implement the search functionality by implementing the correct hooks.
package = Roblib Search
dependencies[] = apachesolr_access
dependencies[] = views_ui
version = 7.x-dev
core = 7.x
stylesheets[all][] = css/roblib_search.base.css

10
roblib_search.info.yml

@ -0,0 +1,10 @@
name: Roblib Search
type: module
core_version_requirement: ^9 || ^10
configure: roblib_search.settings
description: Provides a search form and fires a hook when the search is submitted. Other modules should implement the search functionality by implementing the correct hooks.
package: Roblib Search
dependancies:
- drupal:views_ui
- drupal:message

44
roblib_search.install

@ -1,44 +0,0 @@
<?php
/**
* @file
* Installation hooks.
*/
/**
* Implements hook_schema().
*/
function roblib_search_schema() {
$schema = array();
$schema['roblib_search_log'] = array(
'description' => 'stores search data such as date/time ip etc.',
'fields' => array(
'sid' => array(
'type' => 'serial',
'not null' => TRUE,
'description' => 'unique id for each row',
),
'query' => array(
'description' => 'the search string',
'type' => 'varchar',
'not null' => TRUE,
'length' => 1024,
),
'searched_date' => array(
'description' => 'the date the search request occured',
'type' => 'varchar',
'mysql_type' => 'DATETIME',
'not null' => TRUE,
),
'ipaddress' => array(
'description' => 'the ip or domain of the users computer ',
'type' => 'varchar',
'not null' => TRUE,
'length' => 255,
),
),
'primary key' => array('sid'),
);
return $schema;
}

339
roblib_search.module

@ -5,312 +5,31 @@
* Implementation of Roblib search for searching several targets. * Implementation of Roblib search for searching several targets.
*/ */
/**
* Implements hook_menu().
*/
function roblib_search_menu() {
$items['admin/roblib_search'] = array(
'title' => 'Roblib search',
'description' => 'Configure global Roblib search settings.',
'access arguments' => array('administer site configuration'),
'type' => MENU_NORMAL_ITEM,
);
$items['admin/roblib_search/configure'] = array(
'title' => 'Global Configuration',
'description' => 'Configure global Roblib search settings.',
'access arguments' => array('administer site configuration'),
'page callback' => 'drupal_get_form',
'page arguments' => array('roblib_search_config_form'),
'type' => MENU_NORMAL_ITEM,
);
return $items;
}
/**
* A form for managing the modules configuration.
*
* @param array $form
* A Drupal form array
* @param array $form_state
* A Drupal formstate array
*
* @return array
* A Drupal form
*/
function roblib_search_config_form($form, &$form_state) {
$form['roblib_search_panel_page'] = array(
'#type' => 'textfield',
'#title' => t('Path to the roblib search panel page'),
'#default_value' => variable_get('roblib_search_panel_page', '/roblib/panel'),
'#description' => t('The Path to the Roblib Search Panel, for example /roblib/panel'),
'#required' => TRUE,
);
return system_settings_form($form);
}
/**
* Implements hook_admin_paths().
*/
function roblib_search_admin_paths() {
$paths = array(
'admin/roblib/search' => TRUE,
);
return $paths;
}
function roblib_search_views_data(){
$data['roblib_search_log']['table']['group'] = t('Roblib Search log');
$data['roblib_search_log']['table']['base'] = array(
'field' => 'sid', // This is the identifier field for the view.
'title' => t('Roblib Search log'),
'help' => t('Contains the Roblib Bento box search query strings.'),
'weight' => -10,
);
// The individual fields.
$data['roblib_search_log']['query'] = array(
'title' => t('the query string field'),
'help' => t('a plain text field.'),
'field' => array(
'handler' => 'views_handler_field',
'click sortable' => TRUE, // This is use by the table display plugin.
),
'sort' => array(
'handler' => 'views_handler_sort',
),
'filter' => array(
'handler' => 'views_handler_filter_string',
),
'argument' => array(
'handler' => 'views_handler_argument_string',
),
);
$data['roblib_search_log']['sid'] = array(
'title' => t('Numeric field'),
'help' => t('the unique identifier for each row'),
'field' => array(
'handler' => 'views_handler_field_numeric',
'click sortable' => TRUE,
),
'filter' => array(
'handler' => 'views_handler_filter_numeric',
),
'sort' => array(
'handler' => 'views_handler_sort',
),
);
$data['roblib_search_log']['ipaddress'] = array(
'title' => t('the ipaddress of the user who submitted the search'),
'help' => t('a plain text field.'),
'field' => array(
'handler' => 'views_handler_field',
'click sortable' => TRUE, // This is use by the table display plugin.
),
'sort' => array(
'handler' => 'views_handler_sort',
),
'filter' => array(
'handler' => 'views_handler_filter_string',
),
'argument' => array(
'handler' => 'views_handler_argument_string',
),
);
$data['roblib_search_log']['searched_date'] = array(
'title' => t('Timestamp field'),
'help' => t('a timestamp field.'),
'field' => array(
'handler' => 'views_handler_field',
'click sortable' => TRUE,
),
'argument' => array('handler' => 'views_handler_argument_date'),
'sort' => array(
'handler' => 'views_handler_sort_date',
),
'filter' => array(
'handler' => 'roblib_search_handler_filter_datetime',
),
);
return $data;
}
/**
* Implements hook_permission().
*/
function roblib_search_permission() {
return array(
'search roblib' => array(
'title' => t('Search all configured targets'),
'description' => t('Search all Roblib configured targets. This permission exposes the search blocks and allows you to see search results.'),
),
'administer roblib search' => array(
'title' => t('Administer Roblib Search'),
'description' => t('Administer settings for the Roblib search client.'),
),
);
}
/**
* Implements hook_block_info().
*/
function roblib_search_block_info() {
$blocks['roblib_search_form'] = array(
'info' => t('Roblib Global Search Form'),
'cache' => DRUPAL_CACHE_PER_ROLE,
);
$blocks['roblib_search_other'] = array(
'info' => t('Roblib Search Other Sources'),
'cache' => DRUPAL_CACHE_PER_ROLE,
);
return $blocks;
}
/** /**
* Implements hook_theme(). * Implements hook_theme().
*/ */
function roblib_search_theme() { function roblib_search_theme($existing, $type, $theme, $path) {
$path = drupal_get_path('module', 'roblib_search'); return [
$file = 'theme.inc'; 'roblib_search_results' => [
'variables' => ['query' => NULL],
return array( ],
'roblib_search_other_sources' => array( 'roblib_search_other_sources' => [
'path' => $path . '/theme', 'variables' => ['query' => NULL],
'file' => $file, ],
'template' => 'roblib-search-other-sources', ];
'variables' => array('results' => NULL),
)
);
} }
/**
* Hook the panels pane preprocessor so we can wrap it in a div for themeing.
*
* @param array $variables
* Drupal variables array
* @param $hook
*/
function roblib_search_preprocess_panels_pane(&$variables, $hook){
switch ($variables['pane']->subtype) {
case 'roblib_search-roblib_search_other':
$variables['title_prefix'] = '<div class="roblib-search-header roblib-search-other-sources-header">';
$variables['title_suffix'] = '</div>';
break;
}
}
/** /**
* Implements hook_init(). * Implements hook_init().
*/ */
function roblib_search_init() { /*function roblib_search_init() {
drupal_add_js(drupal_get_path('module', 'roblib_search') . '/js/imagesloaded.pkg.min.js'); drupal_add_js(drupal_get_path('module', 'roblib_search') . '/js/imagesloaded.pkg.min.js');
drupal_add_js(drupal_get_path('module', 'roblib_search') . '/js/roblib_search.js'); drupal_add_js(drupal_get_path('module', 'roblib_search') . '/js/roblib_search.js');
drupal_add_css(drupal_get_path('module', 'roblib_search') . '/css/jquery.qtip.min.css'); drupal_add_css(drupal_get_path('module', 'roblib_search') . '/css/jquery.qtip.min.css');
} }*/
/**
* Implements hook_block_view().
*/
function roblib_search_block_view($delta = '') {
switch ($delta) {
case 'roblib_search_form':
$block['subject'] = t('Bento Search');
$block['content'] = drupal_get_form('roblib_search_simple_form');
break;
case 'roblib_search_other':
$block['subject'] = t('Other Sources');
$block['content'] = theme('roblib_search_other_sources', array('results' => NULL));
}
return $block;
}
/**
* Roblib search simple search form submit.
*
* @param array $form
* Drupal form array
* @param array $form_state
* Drupal formstate array
*/
function roblib_search_simple_form_submit($form, &$form_state) {
global $base_url;
$form_state['rebuild'] = TRUE;
$search_string = $form_state['values']['roblib_search_simple_search_query'];
$search_string = filter_xss($search_string);
roblib_search_log_query($search_string);
$redirect_url = variable_get('roblib_search_panel_page', 'roblib/panel');
$redirect_url = $base_url . '/' . $redirect_url;
drupal_goto($redirect_url, array('query' => array('roblib_query' => $search_string)));
}
/**
* Logs a search query to a database table.
*
* @param string $search_string
* The query to log
*/
function roblib_search_log_query($search_string) {
$eid = db_insert('roblib_search_log')
->fields(array(
'query' => $search_string,
'searched_date' => format_date(time(), 'custom', 'Y-m-d H:i:s'),
'ipaddress' => ip_address(),
))
->execute();
}
/**
* Roblib search simple search form.
*
* @param array $form
* Drupal form array
* @param array $form_state
* Drupal formstate
*
* @return array
* A Drupal formapi array
*/
function roblib_search_simple_form($form, &$form_state) {
if (isset($_GET['roblib_query'])) {
$query = $_GET['roblib_query'];
}
else {
$query = '';
}
$form['simple'] = array(
'#type' => 'container',
'#attributes' => array(
'class' => array(
'container-inline'
)
)
);
$form['simple']["roblib_search_simple_search_query"] = array(
'#size' => '15',
'#type' => 'textfield',
'#title' => '',
'#required' => TRUE,
'#default_value' => $query,
);
$form['simple']['submit'] = array(
'#type' => 'submit',
'#value' => t('search')
);
return $form;
}
/** /**
* Implements hook_help(). * Implements hook_help().
@ -327,37 +46,3 @@ function roblib_search_help($path, $arg) {
); );
} }
} }
class roblib_search_handler_filter_datetime extends views_handler_filter_date {
function op_between($field) {
if ($this->operator == 'between') {
$a = intval(strtotime($this->value['min'], 0));
$b = intval(strtotime($this->value['max'], 0));
}
else {
$a = intval(strtotime($this->value['max'], 0));
$b = intval(strtotime($this->value['min'], 0));
}
if ($this->value['type'] == 'offset') {
// changed from original
$a = (integer)time() + (integer)sprintf('%+d', $a); // keep sign
$b = (integer)time() + (integer)sprintf('%+d', $b); // keep sign
// changed from original ends
}
// %s is safe here because strtotime scrubbed the input and we might
// have a string if using offset.
$this->query->add_where_expression($this->options['group'], "$field >= '".date("Y-m-d H:i:s", $a)."'");
$this->query->add_where_expression($this->options['group'], "$field <= '".date("Y-m-d H:i:s", $b)."'");
}
function op_simple($field) {
$value = intval(strtotime($this->value['value'], 0));
if (!empty($this->value['type']) && $this->value['type'] == 'offset') {
$this->query->add_where_expression($this->options['group'], "$field $this->operator DATE_ADD(NOW(), INTERVAL $value SECOND)");
} else {
$this->query->add_where_expression($this->options['group'], "$field $this->operator $value");
}
}
}

18
roblib_search.routing.yml

@ -0,0 +1,18 @@
roblib_search.settings:
path: '/admin/config/system/roblib_search'
defaults:
_form: '\Drupal\roblib_search\Form\RoblibSearchSettingsForm'
_title: 'Roblib Search Settings Form'
requirements:
_permission: 'administer site configuration'
roblib_search.landing_page:
path: '/roblib_search/{query}'
defaults:
_controller: '\Drupal\roblib_search\Controller\RoblibSearchController::searchResults'
_title: 'Roblib Search Landing Page'
query: '[a-zA-Z\s]+'
options:
no_cache: 'TRUE'
requirements:
_permission: 'access content'

39
src/Controller/RoblibSearchController.php

@ -0,0 +1,39 @@
<?php
namespace Drupal\roblib_search\Controller;
use Drupal\Core\Controller\ControllerBase;
use Drupal\Core\Url;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Drupal\Component\Utility\Html;
/**
* Controller for d3 graphs.
*/
class RoblibSearchController extends ControllerBase {
/**
* Display the markup.
*
* @return array
* A renderable array.
*/
public function searchResults($query = NULL) {
if ($query = $_GET['roblib_query']) {
$query = str_replace('/', ' ',$query);
$query = trim(Html::decodeEntities($query));
if(empty($query)) {
\Drupal::messenger()->addMessage($this->t('Please Enter a valid search string.'));
$url = Url::fromRoute('roblib_search.landing_page');
} else {
$url = Url::fromRoute('roblib_search.landing_page', ['query' => $query]);
}
return new RedirectResponse($url->toString());
}
return [
'#theme' => 'roblib_search_results',
'#query' => $query,
];
}
}

80
src/Form/RoblibSearchForm.php

@ -0,0 +1,80 @@
<?php
namespace Drupal\roblib_search\Form;
use Drupal\Core\Form\FormBase;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Component\Utility\Html;
use Drupal\Core\Url;
use Drupal\message\Entity\Message;
/**
* Config form for module
*
* @author ppound
*/
class RoblibSearchForm extends FormBase{
/**
* {@inheritdoc}
*/
public function getFormId() {
return 'roblib_searchbox_form';
}
/**
* {@inheritdoc}
*/
public function buildForm(array $form, FormStateInterface $form_state) {
if (isset($_GET['roblib_query'])) {
$query = $_GET['roblib_query'];
}
else {
$query = '';
}
$form['simple'] = array(
'#type' => 'container',
'#attributes' => array(
'class' => array(
'container-inline'
)
)
);
$form['simple']["roblib_search_simple_search_query"] = array(
'#size' => '15',
'#type' => 'textfield',
'#title' => '',
'#required' => TRUE,
'#default_value' => $query,
);
$form['simple']['submit'] = array(
'#type' => 'submit',
'#value' => t('search')
);
return $form;
}
/**
* {@inheritdoc}
*/
public function validateForm(array &$form, FormStateInterface $form_state) {
}
/**
* {@inheritdoc}
*/
public function submitForm(array &$form, FormStateInterface $form_state) {
$search_string = $form_state->getValue('roblib_search_simple_search_query');
//$search_string = Html::escape($search_string);
$message = Message::create(['template' => 'roblib_search_message_template',
'uid' => \Drupal::currentUser()->id()]);
$message->set('field_ip_address', \Drupal::request()->getClientIp());
$message->set('field_search_string', $search_string);
$message->save();
$url = Url::fromUserInput('/roblib_search/' . $search_string);
$form_state->setRedirectUrl($url);
}
}

57
src/Form/RoblibSearchSettingsForm.php

@ -0,0 +1,57 @@
<?php
namespace Drupal\roblib_search\Form;
use Drupal\Core\Form\FormBase;
use Drupal\Core\Form\FormStateInterface;
/**
* Settings form for module
*
* @author ppound
*/
class RoblibSearchSettingsForm extends FormBase {
/**
* {@inheritdoc}
*/
public function getFormId() {
return 'roblib_search_settings_form';
}
/**
* {@inheritdoc}
*/
public function buildForm(array $form, FormStateInterface $form_state) {
$config = \Drupal::config('roblib_search.settings');
$form['search_panel_page'] = array(
'#type' => 'textfield',
'#title' => t('Path to the roblib search panel page'),
'#default_value' => $config->get('search_panel_page'),
'#description' => t('The Path to the Roblib Search Panel, for example /roblib/panel'),
'#required' => TRUE,
);
$form['actions']['submit'] = [
'#type' => 'submit',
'#value' => t('Save'),
'#button_type' => 'primary',
];
return $form;
}
/**
* {@inheritdoc}
*/
public function validateForm(array &$form, FormStateInterface $form_state) {
}
/**
* {@inheritdoc}
*/
public function submitForm(array &$form, FormStateInterface $form_state) {
$config = \Drupal::configFactory()->getEditable('roblib_search.settings');
$config->set('search_panel_page', $form_state->getValue('search_panel_page'))->save();
}
}

26
src/Plugin/Block/RoblibSearchBoxBlock.php

@ -0,0 +1,26 @@
<?php
namespace Drupal\roblib_search\Plugin\Block;
use Drupal\Core\Block\BlockBase;
/**
* Provides a search form.
*
* @Block(
* id = "roblib_search_box",
* admin_label = @Translation("Roblib Search Block"),
* category = @Translation("Roblib Search"),
* )
*/
class RoblibSearchBoxBlock extends BlockBase {
/**
* {@inheritdoc}
*/
public function build() {
$form = \Drupal::formBuilder()->getForm('\Drupal\roblib_search\Form\RoblibSearchForm');
return $form;
}
}

39
src/Plugin/Block/RoblibSearchOtherSourcesBlock.php

@ -0,0 +1,39 @@
<?php
namespace Drupal\roblib_search\Plugin\Block;
use Drupal\Core\Block\BlockBase;
/**
* Provides a search form.
*
* @Block(
* id = "roblib_search_other_sources",
* admin_label = @Translation("Roblib Search Other Sources"),
* category = @Translation("Roblib Search"),
* )
*/
class RoblibSearchOtherSourcesBlock extends BlockBase {
/**
* {@inheritdoc}
*/
///roblib_search/
public function build() {
$prefix = '/roblib_search/';
$query = $_SERVER['REQUEST_URI'];
if (substr($query, 0, strlen($prefix)) == $prefix) {
$query = substr($query, strlen($prefix));
}
return [
'#theme' => 'roblib_search_other_sources',
'#query' => $query,
];
}
public function getCacheMaxAge() {
// don't cache this block
return 0;
}
}

12
targets/cufts/css/roblib_search_cufts.base.css

@ -1,12 +0,0 @@
/*
Document : roblib_search_cufts
Created on : Jun 10, 2013, 3:07:56 PM
Author : yqjiang
Description:
Purpose of the stylesheet follows.
*/
.cufts-issns , .cufts-fulltext-coverages{
padding-left: 10px; font-size: smaller;
}

61
targets/cufts/js/cufts_results.js

@ -1,61 +0,0 @@
Drupal.behaviors.roblib_search_cufts = {
attach: function(context, settings) {
url = settings.roblib_search_cufts.search_url;
jQuery.getJSON(url, function(data) {
var items = [];
var numberOfDocs = 0;
try {
numberOfDocs = data.journals.length;
} catch (err) {
// do nothing leave docLength at 0
}
if (numberOfDocs < 1) {
jQuery('#' + 'roblib-search-content-cufts').empty().append('No Results');
jQuery('.' + 'pane-roblib-search-cufts-roblib-search-cufts-results').hide();
} else {
var counter = 0;
var divs = new Array();
var content = new Array();
jQuery.each(data.journals, function(key, val) {
id = 'roblib_cufts_results_' + counter;
content[counter] = "";
divs[counter] = id;
var item_str = '<div class ="roblib-search-row" id="' + id + '">';
item_str += '<div class="roblib-title cufts">';
item_str += '<a href = "' + val.url + '">' + val.title + '</a>';
item_str += '</div>';
item_str += '</div>';
items.push(item_str);
jQuery.each(val.fulltext_coverages, function(key3, val3) {
if(typeof val3 !== 'undefined' && val3 != null ){
content[counter] += '<div class="cufts-coverage">' + val3 + "</div>";
}
});
jQuery.each(val["links"], function(key4, val4) {
if(typeof val4.print_coverage !== 'undefined' && val4.print_coverage != null ){
content[counter] += '<div class="cufts-coverage">' + val4.print_coverage + "</div>";
}
});
counter++;
});
jQuery('#' + 'roblib-search-content-cufts').empty().append(items.join(''));
qtipify(divs, content, 'Coverage');
}
var originURL = settings.roblib_search_cufts.url;
var originSuffix = settings.roblib_search_cufts.suffix;
var newSuffix = originSuffix.replace("&format=json", "");
if (parseInt(data.numOfResults) > 0)
{
jQuery('#' + 'roblib-search-cufts-more').empty().append('<a href="' + originURL + newSuffix + '">see all ' + data.numOfResults + ' results</a>');
}
else
{
jQuery('#' + 'roblib-search-content-cufts').empty().append('<p>no result</p>');
jQuery('#' + 'roblib-search-cufts-more').empty();
}
});
}
}

8
targets/cufts/roblib_search_cufts.info

@ -1,8 +0,0 @@
name = Roblib Search Cufts
dependencies[] = roblib_search
configure = admin/roblib_search/cufts_search
description = implements the Roblib Search modules _roblib_search hook
package = Roblib Search
version = 7.x-dev
core = 7.x
stylesheets[all][] = css/roblib_search_cufts.base.css

2
targets/cufts/roblib_search_cufts.install

@ -1,2 +0,0 @@
<?php

203
targets/cufts/roblib_search_cufts.module

@ -1,203 +0,0 @@
<?php
/**
* @file
* Implementation of Roblib search for searching several targets.
*/
/**
* Implements hook_menu().
*/
function roblib_search_cufts_menu() {
$items = array();
$items['admin/roblib_search/cufts_search'] = array(
'title' => 'Cufts Search Target configuration',
'description' => 'Configuration for the Roblib evergreen search target',
'page callback' => 'drupal_get_form',
'page arguments' => array('roblib_search_cufts_config_form'),
'access arguments' => array('access administration pages'),
'type' => MENU_NORMAL_ITEM,
);
$items['roblib_search/cufts/ajax/%'] = array(
'title' => 'cufts ajax',
'page callback' => 'roblib_search_cufts_ajax',
'page arguments' => array(3),
'type' => MENU_CALLBACK,
'access arguments' => array('search roblib cufts'),
);
return $items;
}
function roblib_search_cufts_config_form($form, &$form_state) {
$form['roblib_search_cufts_url'] = array(
'#type' => 'textfield',
'#title' => t('Cufts url'),
'#default_value' => variable_get('roblib_search_cufts_url', 'http://cufts2.lib.sfu.ca/CJDB/PCU/browse/show?'),
'#description' => t('The base Cufts URL, for example http://cufts2.lib.sfu.ca/CJDB/PCU/browse/show?'),
'#required' => TRUE,
);
$form['roblib_search_cufts_search_suffix'] = array(
'#type' => 'textfield',
'#title' => t('Cufts search suffix'),
'#default_value' => variable_get('roblib_search_cufts_search_suffix', 'browse_field=title&search_type=startswith&format=json&search_terms='),
'#description' => t('The suffix will be appended to the base url for searches, for example browse_field=title&search_type=startswith&format=json&search_terms='),
'#required' => TRUE,
);
$form['roblib_search_cufts_num_results'] = array(
'#type' => 'textfield',
'#title' => t('Number of results to return'),
'#default_value' => variable_get('roblib_search_cufts_num_results', '5'),
'#description' => t('The number of results to display in the Bento box'),
'#required' => TRUE,
);
return system_settings_form($form);
}
/**
* Implements hook_permission().
*/
function roblib_search_cufts_permission() {
return array(
'search roblib cufts' => array(
'title' => t('Search the cufts target'),
'description' => t('Search oblib cufts target. This permission exposes the search blocks and allows you to see search results.'),
),
'administer roblib search cufts' => array(
'title' => t('Administer Roblib Search Cufts'),
'description' => t('Administer settings for the Roblib cufts search client.'),
),
);
}
/**
* Implements hook_theme().
*/
function roblib_search_cufts_theme() {
// set path
$path = drupal_get_path('module', 'roblib_search_cufts');
$file = 'theme.inc';
return array(
// results page
'roblib_search_cufts' => array(
'path' => $path . '/theme',
'file' => $file,
'template' => 'roblib-search-cufts',
'variables' => array('results'=>NULL)
)
);
}
function roblib_search_cufts_preprocess_panels_pane(&$variables, $hook){
if($variables['pane']->subtype == 'roblib_search_cufts-roblib_search_cufts_results'){
$variables['title_prefix'] = '<div class="roblib-search-header roblib-search-cufts-header">';
$variables['title_suffix'] ='</div>';
}
}
function roblib_search_cufts_block_info() {
$blocks['roblib_search_cufts_results'] = array(
// info: The name of the block.
'info' => t('Cufts Search Results block'),
// Block caching options (per role, per user, etc.)
'cache' => DRUPAL_CACHE_PER_ROLE, // default
);
return $blocks;
}
function roblib_search_cufts_block_view($delta = '') {
switch ($delta) {
case 'roblib_search_cufts_results':
$block['subject'] = t('Journals');
$block['content'] = theme('roblib_search_cufts', array('results' => NULL)); //we will get the results via javascript
break;
}
return $block;
}
function roblib_search_cufts_ajax($query) {
print roblib_search_cufts_get_results($query);
exit();
}
/**
*
* @param string $query
* @return string
* json string
*/
function roblib_search_cufts_get_results($query = NULL) {
drupal_add_css(drupal_get_path('module', 'roblib_search_cufts') . '/css/roblib_search_cufts.theme.css');
// Url parameters.
if (!isset($query)) {
if (isset($_GET['roblib_query'])) {
$query = $_GET['roblib_query'];
}
else {
return '';
}
}
$query = str_replace(' ', '%20', $query);
//http://cufts2.lib.sfu.ca/CJDB/PCU/browse/show?browse_field=title&search_type=startswith&format=json&search_terms=dog&submit=Search
$url = variable_get('roblib_search_cufts_url', 'http://cufts2.lib.sfu.ca/CJDB/PCU/browse/show?');
$url_suffix = variable_get('roblib_search_cufts_search_suffix', 'browse_field=title&search_type=startswith&format=json&search_terms=');
$number_of_records = variable_get('roblib_search_cufts_num_results', '5');
$search_url = $url . $url_suffix . $query . '&submit=Search';
//get the total number of result
$results = drupal_http_request($search_url);
if ($results->code == '200') {
$output = $results->data;
}
else {
$output = $results->status_message;
}
$start_index = strpos($output,'"total_count":')+ strlen('"total_count":');
$end_index = strlen($output)-1;
$length=$end_index-$start_index;
$num_of_result = substr($output,$start_index,$length);
$search_url = $search_url . '&per_page='.$number_of_records;
$results = drupal_http_request($search_url);
if ($results->code == '200') {
$output = $results->data;
}
else {
$output = $results->status_message;
}
$output = str_replace('"total_count":', '"numOfResults":'.$num_of_result.',"total_count":',$output);
return $output;
}
/**
* Implements hook_help().
*
* @param type $path
* @param type $arg
* @return type
*/
function roblib_search_cufts_help($path, $arg) {
switch ($path) {
case 'admin/help#roblib_search_cufts':
return t(
'<p>
provides a target for the Roblib search module. This target uses javascript
to render the results.
</p>'
);
}
}

12
targets/cufts/theme/roblib-search-cufts.tpl.php

@ -1,12 +0,0 @@
<?php
/**
* @file roblib-search-cufts.tpl.php
*
*/
?>
<div class ="roblib-search-more" id="roblib-search-cufts-more"></div>
<div class ="roblib-search-content cufts" id="roblib-search-content-cufts">
<img src="<?php print (empty($spinner_path) ? ' ' : $spinner_path); ?>"/>
</div>

28
targets/cufts/theme/theme.inc

@ -1,28 +0,0 @@
<?php
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
function roblib_search_cufts_preprocess_roblib_search_cufts(&$variables) {
global $base_url;
if (!isset($query)) {
if (isset($_GET['roblib_query'])) {
$query = $_GET['roblib_query'];
}
else {
return '';
}
}
$spinner_path = $base_url . '/' . drupal_get_path('module', 'roblib_search') . '/img/'.'spinner.gif';
$variables['spinner_path'] = $spinner_path;
$search_url = $base_url .'/roblib_search/cufts/ajax/'.urlencode($query);
drupal_add_js(drupal_get_path('module', 'roblib_search_cufts') . '/js/cufts_results.js');
$url = variable_get('roblib_search_cufts_url', 'http://cufts2.lib.sfu.ca/CJDB/PCU/browse/show?');
$url_suffix = variable_get('roblib_search_cufts_search_suffix', 'browse_field=title&search_type=startswith&format=json&search_terms=').$query;
drupal_add_js(array('roblib_search_cufts' => array('search_url' => $search_url,'url'=>$url,'suffix'=>$url_suffix)), array('type' => 'setting'));
}
?>

108
targets/eds/js/eds_results.js

@ -1,108 +0,0 @@
Drupal.behaviors.roblib_search_eds = {
attach: function (context, settings) {
$url = settings.roblib_search_eds.search_url;
profile = settings.roblib_search_eds.eds_profile;
proxy_url = "https://proxy.library.upei.ca/login?url=";
jQuery.getJSON($url, function (data) {
var items = [];
var numberOfDocs = 0;
try {
numberOfDocs = data.numFound;
} catch (err) {
// do nothing leave docLength at 0
}
if (numberOfDocs < 1) {
jQuery('#' + 'roblib-search-content-eds').empty().append('No Results');
jQuery('.' + 'pane-roblib-search-eds-roblib-search-eds-results').hide();
} else {
var counter = 0;
var divs = new Array();
var content = new Array();
var queries = [];
jQuery.each(data.queries, function (key7, query) {
queries.push(query.query);
})
var query_str = encodeURI(data.queries[0].query);
var href_str = 'https://search.ebscohost.com/login.aspx?direct=true&site=eds-live&scope=site&type=1&custid=uprince&groupid=main&profid=lite&mode=bool&lang=en&bquery=';
jQuery.each(data.documents, function (key, val) {
id = 'roblib-search-eds-' + counter;
divs[counter++] = id;
if (typeof val.Items !== 'undefined') {
items.push('<div class ="roblib-search-row" id="' + id + '">');
if (typeof val.Items.Title !== 'undefined') {
items.push('<div class="roblib-title eds">');
items.push('<a href="' + proxy_url + val.PLink + '&scope=site">' + val.Items.Title.Data + '</a></div>');
}
val.PubType == 'Book' ? pubType = 'Print Book' : pubType = val.PubType;
pubYear = val.RecordInfo.BibRelationships.IsPartOfRelationships["date"];
!pubYear ? pubYear = " " : pubYear = pubYear[0]["Y"];
items.push('<div class="eds-type"><span class="eds-pubyear">' + pubYear + '</span> - ' + pubType + '</div>');
var roblib_authors =[];
jQuery.each(val.RecordInfo.BibRelationships.HasContributorRelationships, function (key3, author) {
roblib_authors.push(author.NameFull);
})
items.push('<div class="eds-sor">');
roblib_authors = roblib_shorten(roblib_authors.join('; '), 50, " ");
items.push(roblib_authors);
items.push('</div>');
var url;
!val.Items.URL ? url = " " : url = val.Items.URL.Data;
if(url) {
items.push('<div class="eds-url">' + url + '</div>');
}
if(pubType == "Print Book") {
anNumber = val.An.split(".");
if (anNumber[0] && anNumber[0] == 'upei') {
catalogUrl = '<a href="http://islandpines.roblib.upei.ca/eg/opac/record/' + anNumber[1] +
'">View in UPEI Catalogue</a>';
items.push('<div class="eds-catalog-link">' + catalogUrl + '</div>');
}
}
items.push('</div>');
} else {
items.push('<div class ="roblib-search-row roblib-eds-unauthorized" id="\' + id + \'">You must login to view this result, <a href="https://proxy.library.upei.ca/login?url=' + href_str + query_str + '" id="eds-unauthorized-result">click here to login</a></div>' );
}
});
jQuery('#' + 'roblib-search-content-eds').empty().append(items.join(''));
}
var non_upei_link = '';
var upei_link = '<a href="' + proxy_url + href_str + query_str + '" id="eds-see-all-results">SEE ALL (' + data.recordCount + ')</a> ';
if(!data.is_local_ip) {
non_upei_link = '<a href="' + href_str + query_str + '&authtype=ip,guest" id="eds-non-upei-see_all_results">[Non-UPEI]</a>';
upei_link = upei_link + non_upei_link;
}
jQuery('#roblib-search-eds-more').empty().append(upei_link);
jQuery('#roblib-eds-books-more-results').empty().append(upei_link);
jQuery('#roblib-eds-books-toc').empty().append('<a href="' + proxy_url + href_str + query_str + '" id="eds-see-all-results-toc">Books (' + data.recordCount + ')</a>');
});
}
}
function roblib_intersects(a, b) {
var d = {};
var results = [];
for (var i = 0; i < b.length; i++) {
d[b[i]] = true;
}
for (var j = 0; j < a.length; j++) {
if (d[a[j]])
results.push(a[j]);
}
return results;
}
function roblib_shorten(str, maxLen, separator) {
if (str.length <= maxLen) return str;
return str.substr(0, str.lastIndexOf(separator, maxLen)) + ' et al.';
}

85
targets/eds/js/eds_results_article.js

@ -1,85 +0,0 @@
Drupal.behaviors.roblib_search_eds_articles = {
attach: function (context, settings) {
$url = settings.roblib_search_eds_articles.search_url;
articles_profile = settings.roblib_search_eds_articles.eds_profile;
proxy_url = "https://proxy.library.upei.ca/login?url=";
jQuery.getJSON($url, function (data) {
var items = [];
var numberOfDocs = 0;
try {
numberOfDocs = data.numFound;
} catch (err) {
// do nothing leave docLength at 0
}
if (numberOfDocs < 1) {
jQuery('#' + 'roblib-search-content-eds').empty().append('No Results');
jQuery('.' + 'pane-roblib-search-eds-roblib-search-eds-articles').hide();
} else {
var counter = 0;
var divs = new Array();
var content = new Array();
var queries = [];
jQuery.each(data.queries, function (key7, query) {
queries.push(query.query);
})
var query_str = encodeURI(data.queries[0].query);
var href_str = 'https://search.ebscohost.com/login.aspx?direct=true&site=eds-live&scope=site&type=1&custid=uprince&groupid=main&profile=eds&mode=bool&lang=en&bquery=';
jQuery.each(data.documents, function (key, val) {
id = 'roblib-search-eds-article-' + counter;
divs[counter++] = id;
if (typeof val.Items !== 'undefined') {
items.push('<div class ="roblib-search-row" id="' + id + '">');
if (typeof val.Items.Title !== 'undefined') {
items.push('<div class="roblib-title eds">');
items.push('<a href="' + proxy_url + val.PLink + '&scope=site">' + val.Items.Title.Data + '</a></div>');
}
pubType = val.PubType;
pubYear = val.RecordInfo.BibRelationships.IsPartOfRelationships["date"];
!pubYear ? pubYear = " " : pubYear = pubYear[0]["Y"];
items.push('<div class="eds-type"><span class="eds-pubyear">' + pubYear + '</span> - ' + pubType + '</div>');
var roblib_authors = [];
jQuery.each(val.RecordInfo.BibRelationships.HasContributorRelationships, function (key3, author) {
roblib_authors.push(author.NameFull);
})
items.push('<div class="eds-sor">');
roblib_authors = roblib_shorten(roblib_authors.join('; '), 50, " ");
items.push(roblib_authors);
items.push('</div>');
if (typeof val.Items.TitleSource !== 'undefined') {
items.push('<div class="eds-src"><span class="eds-label">In:</span> ' + val.Items.TitleSource.Data + '</div>');
}
if (typeof val.PLink !== 'undefined' && typeof val.PDF !== 'undefined' && val.PDF == 'pdflink') {
items.push('<div class="eds-db eds-pdf-link"><a href="' + proxy_url + val.PLink + '&scope=site">PDF Full Text</a></div>');
}
if (typeof val.PLink !== 'undefined' && typeof val.HTML !== 'undefined' && val.HTML == '1') {
items.push('<div class="eds-db eds-pdf-link"><a href="' + proxy_url + val.PLink + '&scope=site">HTML Full Text</a></div>');
}
items.push('</div>');
} else {
items.push('<div class ="roblib-search-row roblib-eds-unauthorized" id="\' + id + \'">You must login to view this result, <a href="https://proxy.library.upei.ca/login?url=' + href_str + query_str + '" id="eds-unauthorized-result">click here to login</a></div>' );}
});
jQuery('#' + 'roblib-search-content-eds-articles').empty().append(items.join(''));
}
var non_upei_link = '';
var upei_link = '<a href="' + proxy_url + href_str + query_str + '" id="eds-article-see-all-results">SEE ALL (' + data.recordCount + ')</a> ';
if(!data.is_local_ip) {
non_upei_link = '<a href="' + href_str + query_str + '&authtype=ip,guest" id="eds-article-non-upei-see_all_results">[Non-UPEI]</a>';
upei_link = upei_link + non_upei_link;
}
jQuery('#roblib-search-eds-article-more').empty().append(upei_link);
jQuery('#roblib-eds-articles-more-results').empty().append(upei_link);
jQuery('#roblib-eds-articles-toc').empty().append('<a href="' + proxy_url + href_str + query_str + '" id="eds-article-see-all-results-toc">Articles (' + data.recordCount + ')</a>');
});
}
}

10
targets/eds/roblib_search_eds.info

@ -1,10 +0,0 @@
name = Roblib Search EDS
dependencies[] = roblib_search
dependencies[] = ebsco
configure = admin/roblib_search/eds_search
description = implements the Roblib Search modules _roblib_search hook
package = Roblib Search
version = 7.x-dev
core = 7.x
stylesheets[all][] = css/roblib_search_eds.css

2
targets/eds/roblib_search_eds.install

@ -1,2 +0,0 @@
<?php

365
targets/eds/roblib_search_eds.module

@ -1,365 +0,0 @@
<?php
/**
* @file
* Implementation of Roblib search for searching several targets.
*/
/**
* Implements hook_menu().
*/
function roblib_search_eds_menu() {
$items = array();
$items['admin/roblib_search/eds_search'] = array(
'title' => 'EDS search Target configuration',
'description' => 'Configuration for the Roblib eds search target',
'page callback' => 'drupal_get_form',
'page arguments' => array('roblib_search_eds_config_form'),
'access arguments' => array('access administration pages'),
'type' => MENU_NORMAL_ITEM,
);
$items['roblib_search/eds/ajax/%'] = array(
'title' => 'eds ajax',
'page callback' => 'roblib_search_eds_ajax',
'page arguments' => array(3),
'type' => MENU_CALLBACK,
'access arguments' => array('search roblib eds'),
);
$items['roblib_search/eds/articles/%'] = array(
'title' => 'eds ajax',
'page callback' => 'roblib_search_eds_articles',
'page arguments' => array(3),
'type' => MENU_CALLBACK,
'access arguments' => array('search roblib eds'),
);
$items['roblib_search/eds/info/%'] = array(
'title' => 'eds info',
'page callback' => 'roblib_search_eds_info',
'page arguments' => array(3),
'type' => MENU_CALLBACK,
'access arguments' => array('search roblib eds'),
);
return $items;
}
function roblib_search_eds_info($type = 'Articles') {
$config = roblib_search_eds_build_config_arr($type);
$eds_api = new EBSCOAPI($config);
$output['type'] = $type;
$output['profile'] = $eds_api->getInfo();
print json_encode($output);
exit();
}
function roblib_search_eds_config_form($form, &$form_state) {
$form['roblib_search_eds_rest_url'] = array(
'#type' => 'textfield',
'#title' => t('EDS Rest endpoint'),
'#default_value' => variable_get('roblib_search_eds_rest_url', 'https://eds-api.ebscohost.com/edsapi/rest'),
'#description' => t('The base EDS URL, for example https://eds-api.ebscohost.com/edsapi/rest'),
'#required' => TRUE,
);
$form['roblib_search_eds_auth_url'] = array(
'#type' => 'textfield',
'#title' => t('EDS Auth endpoint'),
'#default_value' => variable_get('roblib_search_eds_auth_url', 'https://eds-api.ebscohost.com/Authservice/rest'),
'#description' => t('The EDS Auth endpoint, for example https://eds-api.ebscohost.com/Authservice/rest'),
'#required' => TRUE,
);
$form['roblib_search_eds_user'] = array(
'#type' => 'textfield',
'#title' => t('EDS user'),
'#default_value' => variable_get('roblib_search_eds_user', 'edsusername'),
'#description' => t('EDS user, for example username'),
'#required' => TRUE,
);
$form['roblib_search_eds_pass'] = array(
'#type' => 'textfield',
'#title' => t('EDS password'),
'#default_value' => variable_get('roblib_search_eds_pass', 'edspassword'),
'#description' => t('EDS password, for example password'),
'#required' => TRUE,
);
$form['roblib_search_eds_guest'] = array(
'#type' => 'textfield',
'#title' => t('EDS Guest access'),
'#default_value' => variable_get('roblib_search_eds_guest', 'y'),
'#description' => t('EDS Guest access, y = guest access, n = not a guest'),
'#required' => TRUE,
);
$form['roblib_search_eds_profile'] = array(
'#type' => 'textfield',
'#title' => t('EDS Article profile'),
'#default_value' => variable_get('roblib_search_eds_profile', 'edsapi'),
'#description' => t('EDS profile, for example edsapi'),
'#required' => TRUE,
);
$form['roblib_search_eds_book_profile'] = array(
'#type' => 'textfield',
'#title' => t('EDS Book profile'),
'#default_value' => variable_get('roblib_search_eds_book_profile', 'apilite'),
'#description' => t('EDS Book profile, for example apilite'),
'#required' => TRUE,
);
$form['roblib_search_eds_num_results'] = array(
'#type' => 'textfield',
'#title' => t('Number of results to return'),
'#default_value' => variable_get('roblib_search_eds_num_results', '5'),
'#description' => t('The number of results to display in the Bento box'),
'#required' => TRUE,
);
$form['roblib_search_eds_article_limiters'] = array(
'#type' => 'textarea',
'#title' => t('The limiters for Article searches'),
'#default_value' => variable_get('roblib_search_eds_article_limiters',
'AND (PT Article OR PT Magazines OR PT News OR PT Academic Journals OR PT Conference Materials)'),
'#description' => t('Specify the Publication Types to use as limiters for Article searches. Formatted similar to
AND (PT Article OR PT Magazines OR PT News OR PT Academic Journals OR PT Conference Materials)'),
'#required' => TRUE,
);
$form['roblib_search_eds_book_limiters'] = array(
'#type' => 'textarea',
'#title' => t('The limiters for Books and Media searches'),
'#default_value' => variable_get('roblib_search_eds_book_limiters',
'AND (PT Book OR PT Video OR PT Audio)'),
'#description' => t('Specify the Publication Types to use as limiters for Article searches. Formatted similar to
AND (PT Book OR PT Video OR PT Audio'),
'#required' => TRUE,
);
return system_settings_form($form);
}
/**
* Implements hook_permission().
*/
function roblib_search_eds_permission() {
return array(
'search roblib eds' => array(
'title' => t('Search the eds target'),
'description' => t('Search Roblib eds target. This permission exposes the search blocks and allows you to see search results.'),
),
'administer roblib search eds' => array(
'title' => t('Administer Roblib Search EDS'),
'description' => t('Administer settings for the Roblib eds search client.'),
),
);
}
/**
* Implements hook_theme().
*/
function roblib_search_eds_theme() {
// set path
$path = drupal_get_path('module', 'roblib_search_eds');
$file = 'theme.inc';
return array(
// results page
'roblib_search_eds' => array(
'path' => $path . '/theme',
'file' => $file,
'template' => 'roblib-search-eds',
'variables' => array('results' => NULL),
),
'roblib_search_eds_articles' => array(
'path' => $path . '/theme',
'file' => $file,
'template' => 'roblib-search-eds-articles',
'variables' => array('results' => NULL),
),
);
}
function roblib_search_eds_preprocess_panels_pane(&$variables, $hook){
if($variables['pane']->subtype == 'roblib_search_eds-roblib_search_eds_articles'){
$variables['title_prefix'] = '<div class="roblib-search-header roblib-search-eds-articles-header">';
$variables['title_suffix'] ='</div>';
}
if($variables['pane']->subtype == 'roblib_search_eds-roblib_search_eds_results'){
$variables['title_prefix'] = '<div class="roblib-search-header roblib-search-eds-media-header">';
$variables['title_suffix'] ='</div>';
}
}
function roblib_search_eds_block_info() {
$blocks['roblib_search_eds_results'] = array(
// info: The name of the block.
'info' => t('EDS Search Results block'),
// Block caching options (per role, per user, etc.)
'cache' => DRUPAL_CACHE_PER_ROLE,
);
$blocks['roblib_search_eds_articles'] = array(
'info' => t('EDS Search Results Articles'),
'cache' => DRUPAL_CACHE_PER_ROLE,
);
return $blocks;
}
function roblib_search_eds_block_view($delta = '') {
switch ($delta) {
case 'roblib_search_eds_results':
$block['subject'] = t('Books & Media');
$block['content'] = theme('roblib_search_eds', array('results' => NULL));
break;
case 'roblib_search_eds_articles':
$block['subject'] = t('Articles');
$block['content'] = theme('roblib_search_eds_articles', array('results' => NULL));
break;
}
return $block;
}
function roblib_search_eds_ajax($query) {
print roblib_search_eds_get_results($query, 'Books');
exit();
}
function roblib_search_eds_articles($query) {
print roblib_search_eds_get_results($query, 'Articles');
exit();
}
/**
*
* @param string $query
* @return string
* json string
*/
function roblib_search_eds_get_results($query = NULL, $type = 'Articles') {
drupal_add_css(drupal_get_path('module', 'roblib_search_eds') . '/css/roblib_search_eds.theme.css');
module_load_include('php', 'ebsco', 'lib/EBSCOAPI');
module_load_include('php', 'ebsco', 'lib/EBSCOAPIConnector');
module_load_include('php', 'ebsco', 'lib/EBSCOAPIResponse');
// Url parameters.
if (!isset($query)) {
if (isset($_GET['roblib_query'])) {
$query = $_GET['roblib_query'];
}
else {
return '';
}
}
$limiters = '';
if ($type != NULL) {
$limiters = urldecode(roblib_search_eds_get_query_limiters($type));
}
// hardcoding "available in library collection" limiter as we can't pass it the
// same way we passed other limiters
$filters = ($type === 'Books') ? array("addlimiter(FT1:y)") : array();
$config = roblib_search_eds_build_config_arr($type);
$number_per_page = variable_get('roblib_search_eds_num_results', '5');
$query = '(' . $query . ') ' . $limiters;
$search = array('lookfor' => $query, 'type' => 'ALLFields', 'index' => 'AllFields', 'q' => 'ebsco/results', 'op' => 'Search');
$eds_api = new EBSCOAPI($config);
$is_local_ip = $eds_api->connector()->isGuestIPAddress($_SERVER["REMOTE_ADDR"]);
//$eds_api->isGuest(boolval(variable_get('roblib_search_eds_guest','y')));
$eds_api->isGuest(!$is_local_ip);
$output = $eds_api->apiSearch($search, $filters, 1, $number_per_page);
$output['is_local_ip'] = $is_local_ip;
return json_encode($output);
}
/**
* For each result query ebsco again to get the detailed record.
*
* and insert a new DetailedRecord element in each record.
*
* @param array $output
* The orginal search results array
* @param string $query
* The orginal query
* @param object $eds_api
* an ebco API PHP object
*/
function roblib_search_eds_get_detailed_result(&$output, $query, &$eds_api) {
foreach ($output['records'] as &$record) {
$db = $record['DbId'];
$an = $record['An'];
$arr = $eds_api->apiRetrieve($an, $db, $query);
$record['DetailedRecord'] = $arr['Items'];
}
}
/**
* Creates the limiter string to append to the end of a query.
*
* @param string $type
* The type of search we want (Articles or Books)
*
* @return string
* The limiters to append to the query.
*/
function roblib_search_eds_get_query_limiters($type) {
$limiters = 'n';
switch ($type) {
case 'Articles':
//$limiters = 'facetfilter=1,SourceType:Magazines,SourceType:News,SourceType:Academic+Journals,SourceType:Conference+Materials';
$limiters = ' ' . variable_get('roblib_search_eds_article_limiters',
'AND (PT Article OR PT Magazines OR PT News OR PT Academic Journals OR PT Conference Materials)');
break;
case 'Books':
// $limiters = '+AND+(PT+book)';
//$limiters = 'facetfilter=1,PublicationType:Books,PublicationType:Audio,PublicationType:Videos';
$limiters = ' ' . variable_get('roblib_search_eds_book_limiters',
'AND (PT Book OR PT Video OR PT Audio)');
break;
}
return urlencode($limiters);
}
function roblib_search_eds_build_config_arr($type) {
$config = array();
$config['user'] = variable_get('roblib_search_eds_user', 'edsusername');
$config['password'] = variable_get('roblib_search_eds_pass', 'edspassword');
//get the local ips allowed from ebsco
$config['local_ip_address'] = variable_get('ebsco_local_ips');
$config['profile'] = ($type === 'Books') ? variable_get('roblib_search_eds_book_profile', 'apilite') :
variable_get('roblib_search_eds_profile', 'edsapi');
$config['auth_url'] = variable_get('roblib_search_eds_auth_url', 'https://eds-api.ebscohost.com/Authservice/rest');
$config['rest_url'] = variable_get('roblib_search_eds_rest_url', 'https://eds-api.ebscohost.com/edsapi/rest');
$config['guest'] = variable_get('roblib_search_eds_guest','y');
return $config;
}
/**
* Implements hook_help().
*
* @param type $path
* @param type $arg
* @return type
*/
function roblib_search_eds_help($path, $arg) {
switch ($path) {
case 'admin/help#roblib_search_eds':
return t(
'<p>
provides a target for the Roblib search module. This target uses javascript
to render the results.
</p>'
);
}
}

35
targets/eds/theme/roblib-search-eds-articles.tpl.php

@ -1,35 +0,0 @@
<?php
/**
* @file roblib-search-eds-article.tpl.php
* Search ebscohost for articles
*
* Variables available:
* - $variables: all array elements of $variables can be used as a variable. e.g. $base_url equals $variables['base_url']
*
*
*/
?>
<div class ="roblib-search-more" id="roblib-search-eds-article-more"></div>
<div class ="roblib-search-content eds-article" id="roblib-search-content-eds-articles">
<img src="<?php print (empty($spinner_path) ? ' ' : $spinner_path); ?>"/>
</div>
<div id="roblib-eds-articles-more-results" class="roblib-eds-more-button button"></div>
<div id="roblib-eds-articles-toc" class="roblib-bento-toc moveme-please"></div>
<?php
/**
* Alternate way to create link back to ebscohost.
<form action="" id = 'roblib-search-eds-articles' method="post" style="width: 375px; overflow: auto;" onsubmit="return ebscoHostSearchGo(this);">
<input id="ebscohosturl" name="ebscohosturl" type="hidden" value="https://search.ebscohost.com/login.aspx?direct=true&amp;site=ehost-live&amp;scope=site&amp;type=0&amp;custid=uprince&amp;profid=eds&amp;groupid=main&amp;mode=and&amp;cli0=RV&amp;clv0=N&amp;lang=en" />
<input id="ebscohostsearchsrc" name="ebscohostsearchsrc" type="hidden" value="url" /> <input id="ebscohostsearchmode" name="ebscohostsearchmode" type="hidden" value="+" />
<input id="ebscohostkeywords" name="ebscohostkeywords" type="hidden" value="" />
<div><input id="ebscohostsearchtext" name="ebscohostsearchtext" value="history" type="hidden" size="23" style="font-size: 9pt; padding-left: 5px; margin-left: 0px;" /> <input type="submit" value="Search" style="font-size: 9pt; padding-left: 5px;" /></div>
</div>
</form>
*/
?>

58
targets/eds/theme/theme.inc

@ -1,58 +0,0 @@
<?php
/*
* all we do here is pass a url to some javascript so the results can be
* loaded async
*/
// TODO: combine these two functions and call this function from the preprocessor
function roblib_search_eds_preprocess_roblib_search_eds(&$variables) {
global $base_url;
if (!isset($query)) {
if (isset($_GET['roblib_query'])) {
$query = $_GET['roblib_query'];
}
else {
return '';
}
}
$spinner_path = $base_url . '/' . drupal_get_path('module', 'roblib_search') . '/img/' . 'spinner.gif';
$variables['spinner_path'] = $spinner_path;
$search_url = $base_url . '/roblib_search/eds/ajax/' . urlencode($query);
drupal_add_js(drupal_get_path('module', 'roblib_search_eds') . '/js/eds_results.js');
drupal_add_js(array(
'roblib_search_eds' => array(
'search_url' => $search_url,
'eds_profile' =>
variable_get('roblib_search_eds_book_profile', 'apilite')
)
), array('type' => 'setting'));
}
function roblib_search_eds_preprocess_roblib_search_eds_articles(&$variables) {
global $base_url;
if (!isset($query)) {
if (isset($_GET['roblib_query'])) {
$query = $_GET['roblib_query'];
}
else {
return '';
}
}
$spinner_path = $base_url . '/' . drupal_get_path('module', 'roblib_search') . '/img/' . 'spinner.gif';
$variables['spinner_path'] = $spinner_path;
$search_url = $base_url . '/roblib_search/eds/articles/' . urlencode($query);
drupal_add_js(drupal_get_path('module', 'roblib_search_eds') . '/js/eds_results_article.js');
drupal_add_js(array(
'roblib_search_eds_articles' => array(
'search_url' => $search_url,
'eds_profile' =>
variable_get('roblib_search_eds_profile', 'edsapi')
)
), array('type' => 'setting'));
}
?>

37
targets/solr_site/js/solr_site_bestbet.js

@ -1,37 +0,0 @@
Drupal.behaviors.roblib_search_solr_site_bestbet = {
attach: function(context, settings) {
url = settings.roblib_search_solr_site_bestbet.search_url;
default_site_type = settings.roblib_search_solr_site_results.default_site_type
jQuery.getJSON(url, function(data) {
var items = [];
var numberOfDocs = 0;
try {
numberOfDocs = data.response.docs.length;
} catch (err) {
// do nothing leave docLength at 0
}
if (numberOfDocs < 1) {
jQuery('#' + 'roblib-search-content-solr-site-bestbet').empty().append('No Results');
jQuery('.' + 'pane-roblib-search-solr-site-roblib-search-solr-site-bestbet').hide();
} else {
jQuery('#' + 'roblib-search-content-solr-site-bestbet').empty();
var counter = 0;
var divs = new Array();
var content = new Array();
jQuery.each(data.response.docs, function(key, val) {
id = 'roblib_search_solr_bestbets_' + counter;
content[counter] = val.teaser;
divs[counter++] = id;
items.push('<div class ="roblib-search-row" id="' + id + '">\n\
<div class="roblib-title solr_site">\n\
<a href="' + val.url + '">' + val.content + '</a></div></div>');
});
jQuery('#' + 'roblib-search-content-solr-site-bestbet').empty().append(items.join(''));
}
});
}
}

47
targets/solr_site/js/solr_site_results.js

@ -1,47 +0,0 @@
Drupal.behaviors.roblib_search_solr_site_results = {
attach: function (context, settings) {
url = settings.roblib_search_solr_site_results.search_url;
query = settings.roblib_search_solr_site_results.search_query;
baseUrl = settings.roblib_search_solr_site_results.base_url;
default_site_type = settings.roblib_search_solr_site_results.default_site_type + '/';
jQuery.getJSON(url, function (data) {
var items = [];
total_found = data.response.numFound;
var numberOfDocs = 0;
try {
numberOfDocs = data.response.docs.length;
} catch (err) {
// do nothing leave docLength at 0
}
if (numberOfDocs < 1) {
jQuery('#' + 'roblib-search-content-solr-site-results').empty().append('No Results');
jQuery('.' + 'pane-roblib-search-solr-site-roblib-search-solr-site-results').hide();
} else {
jQuery('#' + 'roblib-search-content-solr-site-results').empty();
var counter = 0;
var divs = new Array();
var content = new Array();
jQuery.each(data.response.docs, function (key, val) {
id = 'roblib_search_solr_results_' + counter;
content[counter] = val.teaser;
divs[counter++] = id;
items.push('<div class ="roblib-search-row" id="' + id + '">\n\
<span class="roblib-title results">\n\
<a href="' + val.url + '">' + val.label + '</a></span>' +
'\n\<span class="roblib-solr-bundle">(' + val.bundle_name + ')</span> <span class="roblib-solr-teaser"> ' + val.teaser + '</span></div>');
});
jQuery('#' + 'roblib-search-content-solr-site-results').empty().append(items.join(''));
}
if (numberOfDocs > 0) {
results_url = '<a href="' + baseUrl + '/search/' + default_site_type + query + '?f[0]=(-bundle:bestbet)"' + '>see all results ('
+ total_found + ') </a>';
move_me_div_url = '<a href="' + baseUrl + '/search/' + default_site_type + query + '?f[0]=(-bundle:bestbet)"' + '>Library Site ('
+ total_found + ') </a>';
jQuery('#' + 'roblib-search-solr-site-results-more').empty().append(results_url);
jQuery('#' + 'roblib-solr-more-results-results').empty().append(results_url);
jQuery('#' + 'roblib-solr-search-toc-results').empty().append(move_me_div_url);
}
});
}
}

8
targets/solr_site/roblib_search_solr_site.info

@ -1,8 +0,0 @@
name = Roblib Search Solr site
dependencies[] = roblib_search
configure = admin/roblib_search/solr_site_search
description = implements the Roblib Search local Solr site bento results
package = Roblib Search
version = 7.x-dev
core = 7.x
stylesheets[all][] = css/roblib_search_solr_site.css

2
targets/solr_site/roblib_search_solr_site.install

@ -1,2 +0,0 @@
<?php

383
targets/solr_site/roblib_search_solr_site.module

@ -1,383 +0,0 @@
<?php
/**
* @file
* Implementation of Roblib search for searching several targets.
*/
/**
* Implements hook_menu().
*/
function roblib_search_solr_site_menu() {
$items = array();
$items['admin/roblib_search/solr_site_search'] = array(
'title' => 'Roblib Solr Search Target configuration',
'description' => 'Configuration for the Roblib Solr site search target',
'page callback' => 'drupal_get_form',
'page arguments' => array('roblib_search_solr_site_config_form'),
'access arguments' => array('access administration pages'),
'type' => MENU_NORMAL_ITEM,
);
$items['roblib_search/solr_site/bestbet/%'] = array(
'title' => 'BestBet',
'page callback' => 'roblib_search_solr_site_bestbet',
'page arguments' => array(3),
'type' => MENU_CALLBACK,
'access arguments' => array('search roblib solr_site'),
);
$items['roblib_search/solr_site/reserves/%'] = array(
'title' => 'BestBet',
'page callback' => 'roblib_search_solr_site_reserves',
'page arguments' => array(3),
'type' => MENU_CALLBACK,
'access arguments' => array('search roblib solr_site'),
);
$items['roblib_search/solr_site/databases/%'] = array(
'title' => 'solr_site databases',
'page callback' => 'roblib_search_solr_site_databases',
'page arguments' => array(3),
'type' => MENU_CALLBACK,
'access arguments' => array('search roblib solr_site'),
);
$items['roblib_search/solr_site/guides/%'] = array(
'title' => 'solr_site guides',
'page callback' => 'roblib_search_solr_site_guides',
'page arguments' => array(3),
'type' => MENU_CALLBACK,
'access arguments' => array('search roblib solr_site'),
);
$items['roblib_search/solr_site/results/%'] = array(
'title' => 'solr_site guides',
'page callback' => 'roblib_search_solr_site_results',
'page arguments' => array(3),
'type' => MENU_CALLBACK,
'access arguments' => array('search roblib solr_site'),
);
return $items;
}
/**
* A form to manage the modules configuration.
*
* @param array $form
* A Drupal form array
* @param array $form_state
* A Drupal formstate array
*
* @return array
* A Drupal form array
*/
function roblib_search_solr_site_config_form($form, &$form_state) {
$form['roblib_search_solr_site_url'] = array(
'#type' => 'textfield',
'#title' => t('Solr url'),
'#default_value' => variable_get('roblib_search_solr_site_url', 'http://localhost:8983/solr'),
'#description' => t('The base Solr URL, for example http://localhost:8983/solr'),
'#required' => TRUE,
);
$form['roblib_search_solr_site_num_results'] = array(
'#type' => 'textfield',
'#title' => t('Number of results to return'),
'#default_value' => variable_get('roblib_search_solr_site_num_results', '5'),
'#description' => t('The number of results to display in the Bento box'),
'#required' => TRUE,
);
return system_settings_form($form);
}
/**
* Implements hook_permission().
*/
function roblib_search_solr_site_permission() {
return array(
'search roblib solr_site' => array(
'title' => t('Search the solr_site target'),
'description' => t('Search all Roblib solr_site target. This permission exposes the search blocks and allows you to see search results.'),
),
'administer roblib search_solr_site' => array(
'title' => t('Administer Roblib Search Evergreen'),
'description' => t('Administer settings for the Roblib solr_site search client.'),
),
);
}
/**
* Implements hook_theme().
*/
function roblib_search_solr_site_theme() {
// set path
$path = drupal_get_path('module', 'roblib_search_solr_site');
$file = 'theme.inc';
return array(
// results page
'roblib_search_solr_site' => array(
'path' => $path . '/theme',
'file' => $file,
'template' => 'roblib-search-solr-site-results',
'variables' => array('type' => NULL),
),
);
}
/**
* Implements hook_block_info().
*/
function roblib_search_solr_site_block_info() {
$blocks['roblib_search_solr_site_bestbet'] = array(
// info: The name of the block.
'info' => t('Roblib Solr Search Best bets'),
// Block caching options (per role, per user, etc.)
'cache' => DRUPAL_CACHE_PER_ROLE, // default
);
$blocks['roblib_search_solr_site_db'] = array(
// info: The name of the block.
'info' => t('Roblib Solr Search Databases Block'),
// Block caching options (per role, per user, etc.)
'cache' => DRUPAL_CACHE_PER_ROLE, // default
);
$blocks['roblib_search_solr_site_guides'] = array(
// info: The name of the block.
'info' => t('Roblib Solr Search Guides Block'),
// Block caching options (per role, per user, etc.)
'cache' => DRUPAL_CACHE_PER_ROLE, // default
);
$blocks['roblib_search_solr_site_results'] = array(
// info: The name of the block.
'info' => t('Roblib Solr Search Results Block'),
// Block caching options (per role, per user, etc.)
'cache' => DRUPAL_CACHE_PER_ROLE, // default
);
$blocks['roblib_search_solr_site_reserves'] = array(
// info: The name of the block.
'info' => t('Roblib Solr Search Reserves Block'),
// Block caching options (per role, per user, etc.)
'cache' => DRUPAL_CACHE_PER_ROLE, // default
);
return $blocks;
}
/**
* Add a div around our block content so we can theme our panels.
*
* By adding our divs we can theme ours without affecting other drupal panels.
*
* @param array $variables
* Drupal variables array
* @param array $hook
*/
function roblib_search_solr_site_preprocess_panels_pane(&$variables, $hook) {
switch ($variables['pane']->subtype) {
case 'roblib_search_solr_site-roblib_search_solr_site_bestbet':
$variables['title_prefix'] = '<div class="roblib-search-header roblib-search-solr-bestbet-header">';
$variables['title_suffix'] = '</div>';
break;
case 'roblib_search_solr_site-roblib_search_solr_site_db':
$variables['title_prefix'] = '<div class="roblib-search-header roblib-search-solr-db-header">';
$variables['title_suffix'] = '</div>';
break;
case 'roblib_search_solr_site-roblib_search_solr_site_guides':
$variables['title_prefix'] = '<div class="roblib-search-header roblib-search-solr-guides-header">';
$variables['title_suffix'] = '</div>';
break;
case 'roblib_search_solr_site-roblib_search_solr_site_results':
$variables['title_prefix'] = '<div class="roblib-search-header roblib-search-solr-results-header">';
$variables['title_suffix'] = '</div>';
break;
case 'roblib_search_solr_site-roblib_search_solr_site_reserves':
$variables['title_prefix'] = '<div class="roblib-search-header roblib-search-solr-reserves-header">';
$variables['title_suffix'] = '</div>';
break;
}
}
/**
* Implements hook_block_view().
*/
function roblib_search_solr_site_block_view($delta = '') {
switch ($delta) {
case 'roblib_search_solr_site_bestbet':
$block['subject'] = t('Best Bets');
$block['content'] = theme('roblib_search_solr_site', array('type' => 'bestbet'));
break;
case 'roblib_search_solr_site_db':
$block['subject'] = t('Databases');
$block['content'] = theme('roblib_search_solr_site', array('type' => 'databases'));
break;
case 'roblib_search_solr_site_guides':
$block['subject'] = t('Guides');
$block['content'] = theme('roblib_search_solr_site', array('type' => 'guides'));
break;
case 'roblib_search_solr_site_results':
$block['subject'] = t('Library Site');
$block['content'] = theme('roblib_search_solr_site', array('type' => 'results'));
break;
case 'roblib_search_solr_site_reserves':
$block['subject'] = t('Reserves');
$block['content'] = theme('roblib_search_solr_site', array('type' => 'reserves'));
break;
}
return $block;
}
/**
* Send the query to solr but limit the results so it doesn't include certain content.
*
* Print json and exit so the javascript can consume the json.
*
* @param string $query
* The solr search string.
*/
function roblib_search_solr_site_results($query) {
print roblib_search_solr_site_get_results($query, '-bundle:bestbet');
exit();
}
/**
* Send the query to solr but limit the results so it only includes content of type bestbet.
*
* Print json and exit so the javascript can consume the json.
*
* @param string $query
* The solr search string.
*/
function roblib_search_solr_site_bestbet($query) {
$query = str_replace('"', '', $query);
$json = roblib_search_solr_site_get_results("sort_label:$query", 'bundle:bestbet');
$json = roblib_search_solr_site_add_url($json);
print $json;
exit();
}
/**
* Send the query to solr but limit the results so it only includes content of type database.
*
* Print json and exit so the javascript can consume the json.
*
* @param string $query
* The solr search string.
*/
function roblib_search_solr_site_databases($query) {
print roblib_search_solr_site_get_results($query, 'bundle:database');
exit();
}
/**
* Send the query to solr but limit the results so it only includes content of type database.
*
* Print json and exit so the javascript can consume the json.
*
* @param string $query
* The solr search string.
*/
function roblib_search_solr_site_reserves($query) {
print roblib_search_solr_site_get_results($query, 'bundle:course_reserve');
exit();
}
/**
* Send the query to solr but limit the results so it only includes content of tagged with the guide keyword.
*
* Print json and exit so the javascript can consume the json.
*
* @param string $query
* The solr search string.
*/
function roblib_search_solr_site_guides($query) {
// TODO make the field and value searched configurable instead of hardcoded.
// sm_vid_SearchKeywords:guides is another field we might use.
print roblib_search_solr_site_get_results($query, 'im_field_keywords:627');
exit();
}
/**
*
* Updates the json passed in with a url directly to the target of the link field.
* This information is not in solr as it comes from a custom field.
*
*
* @param string $json
* The json string returned from the solr query.
*
* @return string
* json we got from solr with an updated url directly to the target of the link field
*/
function roblib_search_solr_site_add_url($json) {
$responses = json_decode($json);
foreach ($responses->response->docs as &$doc) {
$nid = $doc->entity_id;
// The link field is a complex field and we get the text in solr but not the actual url.
// Since best best will only every return one result it's not much overhead to load the node
// and get the value of the link field. probably less overhead then installing additional
// modules to get the url in solr.
$node = node_load($nid);
$url = $node->field_link['und'][0]['url'];
$doc->url = $url;
}
return json_encode($responses);
}
/**
* Sends a query to Solr.
*
* @param string $query_string
* A string to search for
* @param string $type
* A string to filter the query against field:value
*
* @return string
* Solr results as json.
*/
function roblib_search_solr_site_get_results($query_string = NULL, $type) {
$num_results = variable_get('roblib_search_solr_site_num_results', '5');
$query = apachesolr_drupal_query("apachesolr");
$encoded_query = htmlentities($query_string, ENT_QUOTES);
$query->addParam('q', $encoded_query); // keyword to be searched
$query->addParam('rows', $num_results);
$query->addParam('fq', $type);
$query->addParam('mm', '1');
apachesolr_search_add_boost_params($query);
$response = $query->search();
$json_results = drupal_json_encode($response);
return $json_results;
}
/**
* Implements hook_help().
*/
function roblib_search_solr_site_help($path, $arg) {
switch ($path) {
case 'admin/help#roblib_search_solr_site':
return t(
'<p>
provides a target for the Roblib search module
</p>'
);
}
}

24
targets/solr_site/theme/roblib-search-solr-site-results.tpl.php

@ -1,24 +0,0 @@
<?php
/**
* @file roblib-search-solr-site-results.tpl.php
*
*
* Variables available:
* - $variables: all array elements of $variables can be used as a variable. e.g. $base_url equals $variables['base_url']
*
*/
?>
<?
// Get rid of warnings in admin interface
if (!isset($type)){
$type = 'results';
}
?>
<div class ="roblib-search-more" id="roblib-search-solr-site-<?php echo $type;?>-more"></div>
<div class ="roblib-search-content solr-site-<?php echo $type;?>" id="roblib-search-content-solr-site-<?php echo $type;?>">
<img src="<?php print (empty($spinner_path) ? ' ' : $spinner_path); ?>"/>
</div>
<div id="roblib-solr-more-results-<?php print($type)?>" class="roblib-solr-more-button "></div>
<div id="roblib-solr-search-toc-<?php print($type)?>" class="roblib-bento-toc moveme-please"></div>

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save