@@ -33,6 +33,131 @@ public function register() {
3333
3434 public $ type = 'github ' ;
3535
36+ public function resources ( $ p_event ) {
37+ # Only include the javascript when it's actually needed
38+ parse_str ( parse_url ( $ _SERVER ['REQUEST_URI ' ], PHP_URL_QUERY ), $ t_query );
39+ if ( array_key_exists ( 'page ' , $ t_query ) ) {
40+ $ t_page = basename ( $ t_query ['page ' ] );
41+ if ( $ t_page == 'repo_update_page ' ) {
42+ return '<script src=" ' . plugin_file ( 'sourcegithub.js ' ) . '"></script> ' ;
43+ }
44+ }
45+ return null ;
46+ }
47+
48+ public function hooks () {
49+ return parent ::hooks () + array (
50+ "EVENT_LAYOUT_RESOURCES " => "resources " ,
51+ 'EVENT_REST_API_ROUTES ' => 'routes ' ,
52+ );
53+ }
54+
55+ /**
56+ * Add the RESTful routes handled by this plugin.
57+ *
58+ * @param string $p_event_name The event name
59+ * @param array $p_event_args The event arguments
60+ * @return void
61+ */
62+ public function routes ( $ p_event_name , $ p_event_args ) {
63+ $ t_app = $ p_event_args ['app ' ];
64+ $ t_plugin = $ this ;
65+ $ t_app ->group (
66+ plugin_route_group (),
67+ function () use ( $ t_app , $ t_plugin ) {
68+ $ t_app ->post ( '/{id}/webhook ' , [$ t_plugin , 'route_webhook ' ] );
69+ }
70+ );
71+ }
72+
73+ /**
74+ * RESTful route to create GitHub checkin webhook
75+ *
76+ * @param Slim\Http\Request $p_request
77+ * @param Slim\Http\Response $p_response
78+ * @param array $p_args
79+ *
80+ * @return Slim\Http\Response
81+ */
82+ public function route_webhook ( $ p_request , $ p_response , $ p_args ) {
83+ plugin_push_current ( 'Source ' );
84+
85+ # Make sure the given repository exists
86+ $ t_repo_id = isset ( $ p_args ['id ' ] ) ? $ p_args ['id ' ] : $ p_request ->getParam ( 'id ' );
87+ if ( !SourceRepo::exists ( $ t_repo_id ) ) {
88+ return $ p_response ->withStatus ( HTTP_STATUS_BAD_REQUEST , 'Invalid Repository Id ' );
89+ }
90+
91+ # Check that the repo is of GitHub type
92+ $ t_repo = SourceRepo::load ( $ t_repo_id );
93+ if ( $ t_repo ->type != $ this ->type ) {
94+ return $ p_response ->withStatus ( HTTP_STATUS_BAD_REQUEST , "Id $ t_repo_id is not a GitHub repository " );
95+ }
96+
97+ $ t_username = $ t_repo ->info ['hub_username ' ];
98+ $ t_reponame = $ t_repo ->info ['hub_reponame ' ];
99+
100+ # GitHub webhook payload URL
101+ $ t_payload_url = config_get ( 'path ' ) . plugin_page ( 'checkin ' , true )
102+ . '&api_key= ' . plugin_config_get ( 'api_key ' );
103+
104+ # Retrieve existing webhooks
105+ try {
106+ $ t_github_api = new \GuzzleHttp \Client ();
107+ $ t_api_uri = SourceGithubPlugin::api_uri ( $ t_repo , "repos/ $ t_username/ $ t_reponame/hooks " );
108+
109+ $ t_response = $ t_github_api ->get ( $ t_api_uri );
110+ }
111+ catch ( GuzzleHttp \Exception \ClientException $ e ) {
112+ return $ e ->getResponse ();
113+ }
114+ $ t_hooks = json_decode ( (string ) $ t_response ->getBody () );
115+
116+ # Determine if there is already a webhook attached to the plugin's payload URL
117+ $ t_id = false ;
118+ foreach ( $ t_hooks as $ t_hook ) {
119+ if ( $ t_hook ->name == 'web ' && $ t_hook ->config ->url == $ t_payload_url ) {
120+ $ t_id = $ t_hook ->id ;
121+ break ;
122+ }
123+ }
124+
125+ if ( $ t_id ) {
126+ # Webhook already exists for this URL
127+ # Set the Github URL so user can easily link to it
128+ $ t_hook ->web_url = "https://github.com/ $ t_username/ $ t_reponame/settings/hooks/ " . $ t_hook ->id ;
129+ return $ p_response
130+ ->withStatus ( HTTP_STATUS_CONFLICT ,
131+ plugin_lang_get ( 'webhook_exists ' , 'SourceGithub ' ) )
132+ ->withJson ( $ t_hook );
133+ }
134+
135+ # Create new webhook
136+ try {
137+ $ t_payload = array (
138+ 'name ' => 'web ' ,
139+ 'config ' => array (
140+ 'url ' => $ t_payload_url ,
141+ 'content_type ' => 'json ' ,
142+ 'secret ' => $ t_repo ->info ['hub_webhook_secret ' ],
143+ )
144+ );
145+
146+ $ t_github_response = $ t_github_api ->post ( $ t_api_uri ,
147+ array ( GuzzleHttp \RequestOptions::JSON => $ t_payload )
148+ );
149+ }
150+ catch ( GuzzleHttp \Exception \ClientException $ e ) {
151+ return $ e ->getResponse ();
152+ }
153+
154+ return $ p_response
155+ ->withStatus ( HTTP_STATUS_CREATED ,
156+ plugin_lang_get ( 'webhook_success ' , 'SourceGithub ' ) )
157+ ->withHeader ('Content-type ' , 'application/json ' )
158+ ->write ( $ t_github_response ->getBody () );
159+ }
160+
36161 public function show_type () {
37162 return plugin_lang_get ( 'github ' );
38163 }
@@ -161,17 +286,25 @@ public function update_repo_form( $p_repo ) {
161286 <td class="category"><?php echo plugin_lang_get ( 'hub_app_access_token ' ) ?> </td>
162287 <td>
163288 <?php
289+ $ t_hide_webhook_create = true ;
290+
164291 if ( empty ( $ t_hub_app_client_id ) || empty ( $ t_hub_app_secret ) ) {
165292 echo plugin_lang_get ( 'hub_app_client_id_secret_missing ' );
166293 } elseif ( empty ( $ t_hub_app_access_token ) ) {
167294 print_link ( $ this ->oauth_authorize_uri ( $ p_repo ), plugin_lang_get ( 'hub_app_authorize ' ) );
168295 } else {
296+ $ t_hide_webhook_create = false ;
169297 echo plugin_lang_get ( 'hub_app_authorized ' );
170298 # @TODO This would be better with an AJAX, but this will do for now
171299 ?>
172300 <input type="submit" class="btn btn-xs btn-primary btn-white btn-round" name="revoke" value="<?php echo plugin_lang_get ( 'hub_app_revoke ' ) ?> "/>
173301 <?php
174302 }
303+
304+ # Only show the webhook creation div when the app has been authorized
305+ if ( $ t_hide_webhook_create ) {
306+ $ t_webhook_create_css = ' class="hidden" ' ;
307+ }
175308 ?>
176309 </td>
177310</tr>
@@ -180,6 +313,17 @@ public function update_repo_form( $p_repo ) {
180313 <td class="category"><?php echo plugin_lang_get ( 'hub_webhook_secret ' ) ?> </td>
181314 <td>
182315 <input type="text" name="hub_webhook_secret" maxlength="250" size="40" value="<?php echo string_attribute ( $ t_hub_webhook_secret ) ?> "/>
316+ <div id="webhook_create"<?php echo $ t_webhook_create_css ; ?> >
317+ <div class="space-2"></div>
318+ <button type="button" class="btn btn-primary btn-white btn-round btn-sm">
319+ <?php echo plugin_lang_get ( 'webhook_create ' ); ?>
320+ </button>
321+
322+ <span id="webhook_status">
323+ <i class="ace-icon fa fa-lg"></i>
324+ <span></span>
325+ </span>
326+ </div>
183327 </td>
184328</tr>
185329
0 commit comments