From 2a502f2b29ee178b0824e5e0c25b7c8a8807259c Mon Sep 17 00:00:00 2001
From: Kyle M Hall <kyle@bywatersolutions.com>
Date: Tue, 5 Nov 2019 12:31:04 -0500
Subject: [PATCH] Bug 23975: Add ability to search and install plugins from
 GitHub

It would be nice to be able to search and install plugins directly from GitHub ( and GitLab if possible ). This would make it easier to verify the authenticity of plugins and make discovering new plugins easier as well as making installation of plugins simpler.

Test Plan:
1) Apply this patch
2) Add the new block for plugin_repos to your koha-conf.xml
3) Restart all the things!
4) Browse to the plugins home page
5) Try searching for 'patrons' in the new search box
6) Verify you get results!

Signed-off-by: Martin Renvoize <martin.renvoize@ptfs-europe.com>
---
 debian/templates/koha-conf-site.xml.in        | 12 +++++++
 etc/koha-conf.xml                             | 12 +++++++
 .../prog/en/modules/plugins/plugins-home.tt   | 36 +++++++++++++++++++
 plugins/plugins-home.pl                       | 23 ++++++++++++
 4 files changed, 83 insertions(+)

diff --git a/debian/templates/koha-conf-site.xml.in b/debian/templates/koha-conf-site.xml.in
index a6883945c4..1e0a2331c1 100644
--- a/debian/templates/koha-conf-site.xml.in
+++ b/debian/templates/koha-conf-site.xml.in
@@ -409,6 +409,18 @@ __END_SRU_PUBLICSERVER__
       developers use it to catch bugs related to strict SQL modes -->
  <dev_install>0</dev_install>
  <strict_sql_modes>0</strict_sql_modes>
+ <plugin_repos>
+    <repo>
+        <name>ByWater Solutions</name>
+        <org_name>bywatersolutions</org_name>
+        <service>github</service>
+    </repo>
+    <repo>
+        <name>Theke Solutions</name>
+        <org_name>thekesolutions</org_name>
+        <service>github</service>
+    </repo>
+ </plugin_repos>
 
 </config>
 </yazgfs>
diff --git a/etc/koha-conf.xml b/etc/koha-conf.xml
index b3466070d9..7c87bd267c 100644
--- a/etc/koha-conf.xml
+++ b/etc/koha-conf.xml
@@ -233,6 +233,18 @@ __PAZPAR2_TOGGLE_XML_POST__
       developers use it to catch bugs related to strict SQL modes -->
  <dev_install>0</dev_install>
  <strict_sql_modes>0</strict_sql_modes>
+ <plugin_repos>
+    <repo>
+        <name>ByWater Solutions</name>
+        <org_name>bywatersolutions</org_name>
+        <service>github</service>
+    </repo>
+    <repo>
+        <name>Theke Solutions</name>
+        <org_name>thekesolutions</org_name>
+        <service>github</service>
+    </repo>
+ </plugin_repos>
 
 </config>
 </yazgfs>
diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/plugins/plugins-home.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/plugins/plugins-home.tt
index 5d598c525e..3ae2cd5e3a 100644
--- a/koha-tmpl/intranet-tmpl/prog/en/modules/plugins/plugins-home.tt
+++ b/koha-tmpl/intranet-tmpl/prog/en/modules/plugins/plugins-home.tt
@@ -27,6 +27,7 @@
                     [% IF ( CAN_user_plugins_manage ) %]
                         <div class="btn-toolbar" id="toolbar">
                             <a href="/cgi-bin/koha/plugins/plugins-upload.pl" id="upload_plugin" class="btn btn-default"><i class="fa fa-upload"></i> Upload plugin</a>
+
                             <div class="btn-group">
                                 <button class="btn btn-default dropdown-toggle" data-toggle="dropdown"><i class="fa fa-eye"></i> View plugins by class <span class="caret"></span></button>
                                 <ul class="dropdown-menu">
@@ -38,10 +39,44 @@
                                     <li><a href="/cgi-bin/koha/plugins/plugins-home.pl?method=intranet_catalog_biblio_enhancements">View intranet catalog biblio enhancement plugins</a></li>
                                 </ul>
                             </div>
+
+                            <div class="btn-group">
+                                <form class="form-inline">
+                                    <div class="form-group">
+                                        <div class="input-group">
+                                            <input type="text" class="form-control" name="plugin-search" id="plugin-repo-search" placeholder="Search for plugins" value="[% search_term | html %]"/>
+                                            <div class="input-group-addon"><i class="fa fa-search"></i></div>
+                                        </div>
+                                    </div>
+                                </form>
+                            </div>
                         </div>
                     [% END %]
                     <h1>Plugins</h1>
 
+                    [% IF search_results %]
+                        <h2>Search results</h2>
+                        <table class="table table-striped">
+                            <thead>
+                                <tr>
+                                    <th>Name</th>
+                                    <th>Description</th>
+                                    <th>Organization</th>
+                                    <th>&nbsp;</th>
+                                </tr>
+                            </thead>
+
+                            [% FOREACH sr IN search_results %]
+                                <tr>
+                                    <td><a href="[% sr.result.html_url | url %]" target="_new">[% sr.result.name %]</a></td>
+                                    <td>[% sr.result.description %]</td>
+                                    <td>[% sr.repo.name %]</td>
+                                    <td><button class="btn btn-install-plugin"><i class="fa fa-download"></i> Install</button></td>
+                                </tr>
+                            [% END %]
+                        </table>
+                    [% END %]
+
                     [% UNLESS ( plugins ) %]
                         [% UNLESS ( method ) %]
                             <div class="dialog message">No plugins installed</div>
@@ -161,6 +196,7 @@
     [% INCLUDE 'calendar.inc' %]
     <script>
         $(document).ready(function(){
+            $(".btn-install-plugin").on("click", function() { alert("Sorry, this functionality doesn't exist yet!"); });
             $(".uninstall_plugin").on("click", function(){
                 $(".dropdown").removeClass("open");
                 var plugin_name = $(this).data("plugin-name");
diff --git a/plugins/plugins-home.pl b/plugins/plugins-home.pl
index 1136a2c717..0c17d9b213 100755
--- a/plugins/plugins-home.pl
+++ b/plugins/plugins-home.pl
@@ -21,6 +21,9 @@ use Modern::Perl;
 
 use CGI qw ( -utf8 );
 
+use JSON qw(from_json);
+use LWP::Simple qw(get);
+
 use Koha::Plugins;
 use C4::Auth;
 use C4::Output;
@@ -31,6 +34,7 @@ my $plugins_enabled = C4::Context->preference('UseKohaPlugins') && C4::Context->
 
 my $input  = new CGI;
 my $method = $input->param('method');
+my $plugin_search = $input->param('plugin-search');
 
 my ( $template, $borrowernumber, $cookie ) = get_template_and_user(
     {   template_name => ($plugins_enabled) ? "plugins/plugins-home.tt" : "plugins/plugins-disabled.tt",
@@ -56,6 +60,25 @@ if ($plugins_enabled) {
 
     $template->param( plugins => \@plugins, );
 
+    my @results;
+    if ($plugin_search) {
+        my $repos = C4::Context->config('plugin_repos');
+        foreach my $r ( @{ $repos->{repo} } ) {
+            if ( $r->{service} eq 'github' ) {
+                my $url = "https://api.github.com/search/repositories?q=$plugin_search+user:$r->{org_name}+in:name,description";
+                my $response = from_json( get($url) );
+                foreach my $result ( @{ $response->{items} } ) {
+                    next unless $result->{name} =~ /^koha-plugin-/;
+                    push( @results, { repo => $r, result => $result } );
+                }
+            }
+        }
+
+        $template->param(
+            search_results => \@results,
+            search_term    => $plugin_search,
+        );
+    }
 }
 
 output_html_with_http_headers( $input, $cookie, $template->output );
-- 
2.20.1