1<?php 2 3/** 4 * Github modules 5 * @package modules 6 * @subpackage github 7 */ 8 9if (!defined('DEBUG_MODE')) { die(); } 10 11/** 12 * Used to cache "read" github items 13 * @subpackage github/lib 14 */ 15class Hm_Github_Uid_Cache { 16 use Hm_Uid_Cache; 17} 18 19/** 20 * @subpackage github/handler 21 */ 22class Hm_Handler_process_github_limit_setting extends Hm_Handler_Module { 23 public function process() { 24 process_site_setting('github_limit', $this, 'max_source_setting_callback', DEFAULT_PER_SOURCE); 25 } 26} 27 28/** 29 * @subpackage github/handler 30 */ 31class Hm_Handler_process_github_since_setting extends Hm_Handler_Module { 32 public function process() { 33 process_site_setting('github_since', $this, 'since_setting_callback'); 34 } 35} 36 37/** 38 * @subpackage github/handler 39 */ 40class Hm_Handler_process_unread_github_included extends Hm_Handler_Module { 41 public function process() { 42 function unread_github_setting_callback($val) { return $val; } 43 process_site_setting('unread_exclude_github', $this, 'unread_github_setting_callback', false, true); 44 } 45} 46 47/** 48 * @subpackage github/handler 49 */ 50class Hm_Handler_github_status extends Hm_Handler_Module { 51 public function process() { 52 list($success, $form) = $this->process_form(array('github_repo')); 53 if ($success) { 54 $details = $this->user_config->get('github_connect_details', array()); 55 if (!empty($details)) { 56 $repos = $this->user_config->get('github_repos', array()); 57 if (in_array($form['github_repo'], $repos, true)) { 58 $url = sprintf('https://api.github.com/repos/%s/events?page=1&per_page=1', $form['github_repo']); 59 $start = microtime(true); 60 $api = new Hm_API_Curl(); 61 $data = $api->command($url, array('Authorization: token ' . $details['access_token'])); 62 if (!empty($data)) { 63 $this->out('github_status', 'success'); 64 $this->out('github_connect_time', (microtime(true) - $start)); 65 $this->out('github_repo', $form['github_repo']); 66 return; 67 } 68 } 69 } 70 $this->out('github_status', 'failed'); 71 $this->out('github_repo', $form['github_repo']); 72 } 73 } 74} 75 76/** 77 * @subpackage github/handler 78 */ 79class Hm_Handler_load_github_repos extends Hm_Handler_Module { 80 public function process() { 81 $this->out('github_repos', $this->user_config->get('github_repos', array())); 82 } 83} 84 85/** 86 * @subpackage github/handler 87 */ 88class Hm_Handler_github_message_action extends Hm_Handler_Module { 89 public function process() { 90 91 list($success, $form) = $this->process_form(array('action_type', 'message_ids')); 92 if ($success) { 93 $id_list = explode(',', $form['message_ids']); 94 Hm_Github_Uid_Cache::load($this->cache->get('github_read_uids', array(), true)); 95 foreach ($id_list as $msg_id) { 96 if (preg_match("/^github_(\d)+_(\d)+$/", $msg_id)) { 97 $parts = explode('_', $msg_id, 3); 98 $guid = $parts[2]; 99 switch($form['action_type']) { 100 case 'unread': 101 Hm_Github_Uid_Cache::unread($guid); 102 break; 103 case 'read': 104 case 'delete': 105 Hm_Github_Uid_Cache::read($guid); 106 break; 107 } 108 } 109 } 110 $this->cache->set('github_read_uids', Hm_Github_Uid_Cache::dump(), 0, true); 111 } 112 } 113} 114 115/** 116 * @subpackage github/handler 117 */ 118class Hm_Handler_github_folders_data extends Hm_Handler_Module { 119 public function process() { 120 $this->out('github_connect_details', $this->user_config->get('github_connect_details', array())); 121 $this->out('github_repos', $this->user_config->get('github_repos', array())); 122 } 123} 124 125/** 126 * @subpackage github/handler 127 */ 128class Hm_Handler_github_event_detail extends Hm_Handler_Module { 129 public function process() { 130 list($success, $form) = $this->process_form(array('list_path', 'github_uid')); 131 if ($success) { 132 Hm_Github_Uid_Cache::load($this->cache->get('github_read_uids', array(), true)); 133 $details = $this->user_config->get('github_connect_details', array()); 134 $repos = $this->user_config->get('github_repos', array()); 135 $limit = $this->user_config->get('github_limit_setting', DEFAULT_PER_SOURCE); 136 $repo = substr($form['list_path'], 7); 137 if (in_array($repo, $repos, true)) { 138 $url = sprintf('https://api.github.com/repos/%s/events?page=1&per_page='.$limit, $repo); 139 $api = new Hm_API_Curl(); 140 $data = $api->command($url, array('Authorization: token ' . $details['access_token'])); 141 $event = array(); 142 $uid = substr($form['github_uid'], 9); 143 if (is_array($data)) { 144 foreach ($data as $item) { 145 if ($item['id'] == $uid) { 146 $event = $item; 147 break; 148 } 149 } 150 } 151 Hm_Github_Uid_Cache::read($item['id']); 152 $this->cache->set('github_read_uids', Hm_Github_Uid_Cache::dump(), 0, true); 153 $this->out('github_event_detail', $event); 154 } 155 } 156 } 157} 158 159/** 160 * @subpackage github/handler 161 */ 162class Hm_Handler_process_github_authorization extends Hm_Handler_Module { 163 public function process() { 164 if (array_key_exists('state', $this->request->get) && $this->request->get['state'] == 'github_authorization') { 165 if (array_key_exists('code', $this->request->get)) { 166 $details = github_connect_details($this->config); 167 $oauth2 = new Hm_Oauth2($details['client_id'], $details['client_secret'], $details['redirect_uri']); 168 $result = $oauth2->request_token($details['token_url'], $this->request->get['code'], array('Accept: application/json')); 169 if (count($result) > 0 && array_key_exists('access_token', $result)) { 170 Hm_Msgs::add('Github connection established'); 171 $this->user_config->set('github_connect_details', $result); 172 $user_data = $this->user_config->dump(); 173 $this->session->set('user_data', $user_data); 174 $this->session->record_unsaved('Github connection'); 175 $this->session->secure_cookie($this->request, 'hm_reload_folders', '1'); 176 $this->session->close_early(); 177 } 178 else { 179 Hm_Msgs::add('ERRAn Error Occurred'); 180 } 181 } 182 elseif (array_key_exists('error', $this->request->get)) { 183 Hm_Msgs::add('ERR'.ucwords(str_replace('_', ' ', $this->request->get['error']))); 184 } 185 else { 186 Hm_Msgs::add('ERRAn Error Occurred'); 187 } 188 $msgs = Hm_Msgs::get(); 189 $this->session->secure_cookie($this->request, 'hm_msgs', base64_encode(serialize($msgs))); 190 Hm_Dispatch::page_redirect('?page=servers'); 191 } 192 } 193} 194 195/** 196 * @subpackage github/handler 197 */ 198class Hm_Handler_setup_github_connect extends Hm_Handler_Module { 199 public function process() { 200 $details = github_connect_details($this->config); 201 if (!empty($details)) { 202 $oauth2 = new Hm_Oauth2($details['client_id'], $details['client_secret'], $details['redirect_uri']); 203 $this->out('github_auth_url', $oauth2->request_authorization_url($details['auth_url'], 'repo', 'github_authorization')); 204 $this->out('github_connect_details', $this->user_config->get('github_connect_details', array())); 205 $this->out('github_repos', $this->user_config->get('github_repos', array())); 206 } 207 } 208} 209 210/** 211 * @subpackage github/handler 212 */ 213class Hm_Handler_github_process_remove_repo extends Hm_Handler_Module { 214 public function process() { 215 list($success, $form) = $this->process_form(array('github_repo', 'github_remove_repo')); 216 if ($success) { 217 $details = $this->user_config->get('github_connect_details'); 218 if ($details) { 219 $repos = $this->user_config->get('github_repos', array()); 220 if (in_array($form['github_repo'], $repos, true)) { 221 foreach ($repos as $index => $repo) { 222 if ($repo === $form['github_repo']) { 223 unset($repos[$index]); 224 break; 225 } 226 } 227 $this->user_config->set('github_repos', $repos); 228 $user_data = $this->user_config->dump(); 229 $this->session->set('user_data', $user_data); 230 $this->session->record_unsaved('Github repository removed'); 231 $this->session->secure_cookie($this->request, 'hm_reload_folders', '1'); 232 Hm_Msgs::add('Removed repository'); 233 } 234 } 235 } 236 } 237} 238 239/** 240 * @subpackage github/handler 241 */ 242class Hm_Handler_github_process_add_repo extends Hm_Handler_Module { 243 public function process() { 244 list($success, $form) = $this->process_form(array('new_github_repo', 'new_github_repo_owner', 'github_add_repo')); 245 if ($success) { 246 $details = $this->user_config->get('github_connect_details'); 247 if ($details) { 248 $url = sprintf('https://api.github.com/repos/%s/%s/events?page=1&per_page=1', urlencode($form['new_github_repo_owner']), urlencode($form['new_github_repo'])); 249 $api = new Hm_API_Curl(); 250 $data = $api->command($url, array('Authorization: token ' . $details['access_token'])); 251 if (!empty($data)) { 252 $repos = $this->user_config->get('github_repos', array()); 253 $new_repo = urlencode($form['new_github_repo_owner']).'/'.urlencode($form['new_github_repo']); 254 if (!in_array($new_repo, $repos, true)) { 255 $repos[] = $new_repo; 256 $this->user_config->set('github_repos', $repos); 257 $user_data = $this->user_config->dump(); 258 $this->session->set('user_data', $user_data); 259 $this->session->record_unsaved('Github repository added'); 260 $this->session->secure_cookie($this->request, 'hm_reload_folders', '1'); 261 Hm_Msgs::add('Added repository'); 262 } 263 else { 264 Hm_Msgs::add('ERRRepository is already added'); 265 } 266 } 267 else { 268 Hm_Msgs::add('ERRCould not find that repository/owner combination at github.com'); 269 } 270 } 271 } 272 } 273} 274 275/** 276 * @subpackage github/handler 277 */ 278class Hm_Handler_github_disconnect extends Hm_Handler_Module { 279 public function process() { 280 if (array_key_exists('github_disconnect', $this->request->post)) { 281 $this->user_config->set('github_connect_details', array()); 282 $user_data = $this->user_config->dump(); 283 $this->session->set('user_data', $user_data); 284 $this->out('reload_folders', true, false); 285 $this->session->record_unsaved('Github connection deleted'); 286 Hm_Msgs::add('Github connection deleted'); 287 } 288 } 289} 290 291/** 292 * @subpackage github/handler 293 */ 294class Hm_Handler_github_list_data extends Hm_Handler_Module { 295 public function process() { 296 list($success, $form) = $this->process_form(array('github_repo')); 297 if ($success) { 298 $login_time = $this->session->get('login_time', false); 299 if ($login_time) { 300 $this->out('login_time', $login_time); 301 } 302 if (array_key_exists('list_path', $this->request->get)) { 303 if (in_array($this->request->get['list_path'], array('combined_inbox', 'unread'), true)) { 304 $this->out('list_parent', $this->request->get['list_path']); 305 } 306 } 307 Hm_Github_Uid_Cache::load($this->cache->get('github_read_uids', array(), true)); 308 $details = $this->user_config->get('github_connect_details'); 309 $repos = $this->user_config->get('github_repos'); 310 if (in_array($form['github_repo'], $repos, true) && $details) { 311 $limit = $this->user_config->get('github_limit_setting', DEFAULT_PER_SOURCE); 312 $url = sprintf('https://api.github.com/repos/%s/events?page=1&per_page='.$limit, $form['github_repo']); 313 $api = new Hm_API_Curl(); 314 $this->out('github_data', $api->command($url, array('Authorization: token ' . $details['access_token']))); 315 $this->out('github_data_source', $form['github_repo']); 316 $this->out('github_data_source_id', array_search($form['github_repo'], $repos, true)); 317 } 318 if (array_key_exists('list_path', $this->request->get)) { 319 if ($this->request->get['list_path'] == 'unread') { 320 $this->out('github_list_since', process_since_argument($this->user_config->get('unread_since_setting', DEFAULT_SINCE))); 321 } 322 if ($this->request->get['list_path'] == 'combined_inbox') { 323 $this->out('github_list_since', process_since_argument($this->user_config->get('all_since_setting', DEFAULT_SINCE))); 324 } 325 if ($this->request->get['list_path'] == 'github_all') { 326 $this->out('github_list_since', process_since_argument($this->user_config->get('github_since_setting', DEFAULT_SINCE))); 327 } 328 } 329 if (array_key_exists('github_unread', $this->request->post) && $this->request->post['github_unread']) { 330 $this->out('github_unread', true); 331 } 332 } 333 } 334} 335 336/** 337 * @subpackage github/handler 338 */ 339class Hm_Handler_github_list_type extends Hm_Handler_Module { 340 public function process() { 341 $repos = $this->user_config->get('github_repos', array()); 342 $excluded = $this->user_config->get('unread_exclude_github_setting', false); 343 $github_list = false; 344 $parent = ''; 345 if (array_key_exists('list_parent', $this->request->get)) { 346 $parent = $this->request->get['list_parent']; 347 } 348 if (array_key_exists('list_path', $this->request->get)) { 349 $path = $this->request->get['list_path']; 350 if ($this->page == 'message_list' && preg_match("/^github_(.+)$/", $path)) { 351 $github_list = true; 352 if ($path == 'github_all') { 353 $this->out('list_path', 'github_all', false); 354 $this->out('list_parent', $parent, false); 355 $this->out('mailbox_list_title', array('Github', 'All')); 356 $this->out('message_list_since', $this->user_config->get('github_since_setting', DEFAULT_SINCE)); 357 $this->out('per_source_limit', $this->user_config->get('github_limit_setting', DEFAULT_PER_SOURCE)); 358 foreach ($repos as $repo) { 359 $this->append('data_sources', array('callback' => 'load_github_data', 'type' => 'github', 'name' => $repo, 'id' => $repo)); 360 } 361 } 362 else { 363 $repo = substr($path, 7); 364 $this->out('list_parent', $parent, false); 365 if ($parent == 'github_all') { 366 $this->out('mailbox_list_title', array(urldecode($repo))); 367 } 368 else { 369 $this->out('mailbox_list_title', array('Github', urldecode($repo))); 370 $this->out('list_path', $path, false); 371 } 372 $this->out('custom_list_controls', ' '); 373 $this->append('data_sources', array('callback' => 'load_github_data', 'type' => 'github', 'name' => $repo, 'id' => $repo)); 374 } 375 } 376 elseif ($this->page == 'message_list' && ($path == 'combined_inbox' || $path == 'unread')) { 377 $github_list = true; 378 if (!$excluded || $path == 'combined_inbox') { 379 foreach ($repos as $repo) { 380 $this->append('data_sources', array('callback' => 'load_github_data', 'type' => 'github', 'name' => $repo, 'id' => $repo)); 381 } 382 } 383 } 384 elseif ($this->page == 'message' && preg_match("/^github_(.+)$/", $path)) { 385 if (!$parent) { 386 $repo = substr($path, 7); 387 $this->out('mailbox_list_title', array('Github', urldecode($repo))); 388 } 389 } 390 } 391 if (!$github_list) { 392 foreach ($repos as $repo) { 393 if (!$excluded) { 394 $this->append('data_sources', array('callback' => 'load_github_data_background', 'group' => 'background', 'type' => 'github', 'name' => 'Github', 'id' => $repo)); 395 } 396 } 397 } 398 } 399} 400 401/** 402 * @subpackage github/output 403 */ 404class Hm_Output_github_folders extends Hm_Output_Module { 405 protected function output() { 406 $details = $this->get('github_connect_details', array()); 407 if (!empty($details)) { 408 $res = '<li class="menu_github_all"><a class="unread_link" href="?page=message_list&list_path=github_all">'; 409 if (!$this->get('hide_folder_icons')) { 410 $res .= '<img class="account_icon" src="'.$this->html_safe(Hm_Image_Sources::$code).'" alt="" width="16" height="16" /> '; 411 } 412 $res .= $this->trans('All').'</a></li>'; 413 foreach ($this->get('github_repos', array()) as $repo) { 414 $res .= '<li class="menu_github_'.$this->html_safe($repo).'"><a class="unread_link" href="?page=message_list&list_path=github_'.$this->html_safe($repo).'">'; 415 if (!$this->get('hide_folder_icons')) { 416 $res .= '<img class="account_icon" src="'.$this->html_safe(Hm_Image_Sources::$code).'" alt="" width="16" height="16" /> '; 417 } 418 $res .= $this->html_safe(explode('/', urldecode($repo))[1]).'</a></li>'; 419 } 420 $this->append('folder_sources', array('github_folders', $res)); 421 } 422 } 423} 424 425/** 426 * @subpackage github/output 427 */ 428class Hm_Output_filter_github_data extends Hm_Output_Module { 429 protected function output() { 430 $res = array(); 431 $login_time = false; 432 $unread_only = false; 433 $show_icons = $this->get('msg_list_icons'); 434 if ($this->get('login_time')) { 435 $login_time = $this->get('login_time'); 436 } 437 if ($this->get('list_path', '') == 'unread' || $this->get('github_unread', false)) { 438 $unread_only = true; 439 } 440 $repo_id = $this->get('github_data_source_id'); 441 $repo = $this->get('github_data_source', 'Github'); 442 $repo_parts = explode('/', $repo); 443 $repo_name = $repo_parts[1]; 444 $cutoff = $this->get('github_list_since', ''); 445 if ($cutoff) { 446 $cutoff = strtotime($cutoff); 447 } 448 else { 449 $cutoff = 0; 450 } 451 $list_parent = false; 452 if ($this->get('list_parent', '')) { 453 $list_parent = $this->get('list_parent'); 454 } 455 elseif ($this->get('list_path') == 'github_all') { 456 $list_parent = $this->get('list_path'); 457 } 458 foreach ($this->get('github_data', array()) as $event) { 459 if (!is_array($event) || !array_key_exists('id', $event)) { 460 continue; 461 } 462 $row_class = 'github'; 463 $id = 'github_'.$repo_id.'_'.$event['id']; 464 $subject = build_github_subject($event, $this); 465 $url = '?page=message&uid='.$this->html_safe($id).'&list_path=github_'.$this->html_safe($repo); 466 if ($list_parent) { 467 $url .= '&list_parent='.$this->html_safe($list_parent); 468 } 469 $from = $event['actor']['login']; 470 $ts = strtotime($event['created_at']); 471 if ($ts < $cutoff) { 472 continue; 473 } 474 if (Hm_Github_Uid_Cache::is_read($event['id'])) { 475 $flags = array(); 476 } 477 elseif (Hm_Github_Uid_Cache::is_unread($event['id'])) { 478 $flags = array('unseen'); 479 $row_class .= ' unseen'; 480 } 481 elseif ($ts && $login_time && $ts <= $login_time) { 482 $flags = array(); 483 } 484 else { 485 $row_class .= ' unseen'; 486 $flags = array('unseen'); 487 } 488 if ($unread_only && !in_array('unseen', $flags)) { 489 continue; 490 } 491 $date = date('r', $ts); 492 $style = $this->get('news_list_style') ? 'news' : 'email'; 493 if ($this->get('is_mobile')) { 494 $style = 'news'; 495 } 496 $row_class .= ' '.$repo_name; 497 $icon = 'code'; 498 if (!$show_icons) { 499 $icon = ''; 500 } 501 if ($style == 'news') { 502 $res[$id] = message_list_row(array( 503 array('checkbox_callback', $id), 504 array('icon_callback', $flags), 505 array('subject_callback', $subject, $url, $flags, $icon), 506 array('safe_output_callback', 'source', $repo_name), 507 array('safe_output_callback', 'from', $from), 508 array('date_callback', human_readable_interval($date), $ts), 509 ), 510 $id, 511 $style, 512 $this, 513 $row_class 514 ); 515 } 516 else { 517 $res[$id] = message_list_row(array( 518 array('checkbox_callback', $id), 519 array('safe_output_callback', 'source', $repo_name, $icon), 520 array('safe_output_callback', 'from', $from), 521 array('subject_callback', $subject, $url, $flags), 522 array('date_callback', human_readable_interval($date), $ts), 523 array('icon_callback', $flags) 524 ), 525 $id, 526 $style, 527 $this, 528 $row_class 529 ); 530 } 531 } 532 $this->out('formatted_message_list', $res); 533 $this->out('github_server_id', $repo_id); 534 } 535} 536 537/** 538 * @subpackage github/output 539 */ 540class Hm_Output_github_add_repo extends Hm_Output_Module { 541 protected function output() { 542 $res = ''; 543 $details = $this->get('github_connect_details', array()); 544 if (!empty($details)) { 545 $res = '<div class="configured_server"><div class="subtitle">'.$this->trans('Add a Repository').'</div>'. 546 '<form method="POST">'. 547 '<input type="hidden" name="hm_page_key" value="'.$this->html_safe(Hm_Request_Key::generate()).'" />'. 548 '<label class="screen_reader">'.$this->trans('Name').'</label>'. 549 '<input type="text" value="" placeholder="'.$this->trans('Name').'" name="new_github_repo" />'. 550 '<label class="screen_reader">'.$this->trans('Owner').'</label>'. 551 '<input type="text" value="" placeholder="'.$this->trans('Owner').'" name="new_github_repo_owner" />'. 552 '<input type="submit" name="github_add_repo" value="Add" />'. 553 '</form></div>'; 554 $res .= '<div class="configured_server"><div class="server_title">'.$this->trans('Repositories').'</div>'; 555 foreach ($this->get('github_repos', array()) as $repo) { 556 $res .= '<div class="configured_repo"><form class="remove_repo" method="POST">'. 557 '<input type="hidden" name="hm_page_key" value="'.$this->html_safe(Hm_Request_Key::generate()).'" />'. 558 '<input type="hidden" name="github_repo" value="'.$this->html_safe($repo).'" />'. 559 '<input type="submit" name="github_remove_repo" value="'.$this->trans('Remove').'" class="github_remove_repo" />'.$this->html_safe($repo).'</form></div>'; 560 } 561 $res .= '</div></div><div class="end_float"></div></div>'; 562 } 563 return $res; 564 } 565} 566 567/** 568 * @subpackage github/output 569 */ 570class Hm_Output_filter_github_event_detail extends Hm_Output_Module { 571 protected function output() { 572 $details = $this->get('github_event_detail', array()); 573 if (!empty($details)) { 574 if (array_key_exists('payload', $details)) { 575 $body = github_parse_payload($details, $this); 576 $headers = github_parse_headers($details, $this); 577 } 578 $this->out('github_msg_text', $headers.$body); 579 } 580 } 581} 582 583/** 584 * @subpackage github/output 585 */ 586class Hm_Output_filter_github_status extends Hm_Output_Module { 587 protected function output() { 588 if ($this->get('github_status') == 'success') { 589 $this->out('github_status_display', '<span class="online">'.$this->trans('Connected').'</span> in '.round($this->get('github_connect_time'), 3)); 590 } 591 else { 592 $this->out('github_status_display', '<span class="down">'.$this->trans('Down').'</span>'); 593 } 594 $this->out('github_status_repo', $this->get('github_repo', '')); 595 } 596}; 597 598/** 599 * @subpackage github/output 600 */ 601class Hm_Output_display_github_status extends Hm_Output_Module { 602 protected function output() { 603 $res = ''; 604 $repos = $this->get('github_repos', array()); 605 if (!empty($repos)) { 606 foreach ($repos as $repo) { 607 $res .= '<tr><td class="github_repo" data-id="'.$this->html_safe($repo).'">'.$this->trans('Github repo').'</td><td>'.$this->html_safe($repo).'</td><td class="github_'.$this->html_safe($repo).'"></td></tr>'; 608 } 609 } 610 return $res; 611 } 612} 613 614/** 615 * @subpackage github/output 616 */ 617class Hm_Output_github_connect_section extends Hm_Output_Module { 618 protected function output() { 619 $details = $this->get('github_connect_details', array()); 620 $res = '<div class="github_connect"><div data-target=".github_connect_section" class="server_section">'. 621 '<img src="'.Hm_Image_Sources::$code.'" alt="" width="16" height="16" /> '. 622 $this->trans('Github Connect').'</div><div class="github_connect_section"><div class="add_server">'; 623 if (empty($details)) { 624 $res .= 'Connect to Github<br /><br />'; 625 $res .= '<a href="'.$this->get('github_auth_url', '').'">'.$this->trans('Enable').'</a></div></div><div class="end_float"</div>'; 626 } 627 else { 628 $res .= $this->trans('Already connected'); 629 $res .= '<br /><form id="github_disconnect_form" method="POST">'; 630 $res .= '<input type="hidden" name="hm_page_key" value="'.$this->html_safe(Hm_Request_Key::generate()).'" />'; 631 $res .= '<input type="submit" name="github_disconnect" class="github_disconnect" value="'.$this->trans('Disconnect').'" />'; 632 $res .= '</form>'; 633 } 634 return $res.'</div>'; 635 } 636} 637 638/** 639 * @subpackage github/output 640 */ 641class Hm_Output_unread_github_included_setting extends Hm_Output_Module { 642 protected function output() { 643 $settings = $this->get('user_settings'); 644 if (array_key_exists('unread_exclude_github', $settings) && $settings['unread_exclude_github']) { 645 $checked = ' checked="checked"'; 646 } 647 else { 648 $checked = ''; 649 } 650 return '<tr class="unread_setting"><td><label for="unread_exclude_github">'.$this->trans('Exclude unread Github notices').'</label></td>'. 651 '<td><input type="checkbox" '.$checked.' value="1" id="unread_exclude_github" name="unread_exclude_github" /></td></tr>'; 652 } 653} 654 655/** 656 * @subpackage github/output 657 */ 658class Hm_Output_start_github_settings extends Hm_Output_Module { 659 protected function output() { 660 return '<tr><td colspan="2" data-target=".github_all_setting" class="settings_subtitle">'. 661 '<img alt="" src="'.Hm_Image_Sources::$code.'" width="16" height="16" />'.$this->trans('Github Settings').'</td></tr>'; 662 } 663} 664 665/** 666 * @subpackage github/output 667 */ 668class Hm_Output_github_since_setting extends Hm_Output_Module { 669 protected function output() { 670 $since = DEFAULT_SINCE; 671 $settings = $this->get('user_settings'); 672 if (array_key_exists('github_since', $settings) && $settings['github_since']) { 673 $since = $settings['github_since']; 674 } 675 return '<tr class="github_all_setting"><td><label for="github_since">'.$this->trans('Show Github notices received since').'</label></td>'. 676 '<td>'.message_since_dropdown($since, 'github_since', $this).'</td></tr>'; 677 } 678} 679 680/** 681 * @subpackage github/output 682 */ 683class Hm_Output_github_limit_setting extends Hm_Output_Module { 684 protected function output() { 685 $limit = DEFAULT_PER_SOURCE; 686 $settings = $this->get('user_settings'); 687 if (array_key_exists('github_limit', $settings)) { 688 $limit = $settings['github_limit']; 689 } 690 return '<tr class="github_all_setting"><td><label for="github_limit">'.$this->trans('Max Github notices per repository').'</label></td>'. 691 '<td><input type="text" id="github_limit" name="github_limit" size="2" value="'.$this->html_safe($limit).'" /></td></tr>'; 692 } 693} 694 695/** 696 * @subpackage github/functions 697 */ 698if (!hm_exists('github_connect_details')) { 699function github_connect_details($config) { 700 return get_ini($config, 'github.ini'); 701}} 702 703/** 704 * @subpackage github/functions 705 */ 706if (!hm_exists('build_github_subject')) { 707function build_github_subject($event, $output_mod) { 708 $ref = ''; 709 if (array_key_exists('payload', $event) && array_key_exists('ref', $event['payload'])) { 710 $ref = sprintf(' / %s', preg_replace("/^refs\/heads\//", '', $event['payload']['ref'])); 711 } 712 $pre = '['.$output_mod->html_safe(trim(str_replace('Event', '', trim(preg_replace("/([A-Z])/", " $1", $event['type']))))).']'; 713 $post = ''; 714 $max = 100; 715 switch (strtolower($event['type'])) { 716 case 'issuecommentevent': 717 $post = $event['payload']['issue']['title']; 718 break; 719 case 'issuesevent': 720 $post = $event['payload']['issue']['title'].' - '.$event['payload']['action']; 721 break; 722 case 'pushevent': 723 if (count($event['payload']['commits']) > 1) { 724 $post .= sprintf($output_mod->trans('%d commits: '), count($event['payload']['commits'])); 725 } 726 else { 727 $post .= sprintf($output_mod->trans('%d commit: '), count($event['payload']['commits'])); 728 } 729 $post .= substr($event['payload']['commits'][0]['message'], 0, $max); 730 break; 731 case 'watchevent': 732 if ($event['payload']['action'] == 'started') { 733 $post .= sprintf($output_mod->trans('%s started watching this repo'), $event['actor']['login']); 734 } 735 else { 736 $post .= sprintf($output_mod->trans('%s stopped watching this repo'), $event['actor']['login']); 737 } 738 break; 739 case 'forkevent': 740 $post = sprintf($output_mod->trans("%s forked %s"), $event['actor']['login'], $event['repo']['name']); 741 break; 742 case 'createevent': 743 $post = sprintf($output_mod->trans("%s repository created"), $event['repo']['name']); 744 break; 745 case 'pullrequestevent': 746 $post = substr($event['payload']['pull_request']['body'], 0, $max); 747 break; 748 case 'commitcommentevent': 749 $post = substr($event['payload']['comment']['body'], 0, $max); 750 break; 751 case 'releaseevent': 752 $post = substr($event['payload']['release']['name'], 0, $max); 753 default: 754 break; 755 } 756 if ($ref) { 757 $post .= $output_mod->html_safe($ref); 758 } 759 return $pre.' '.$post; 760}} 761 762/** 763 * @subpackage github/functions 764 */ 765if (!hm_exists('github_parse_headers')) { 766function github_parse_headers($data, $output_mod) { 767 $res = '<table class="msg_headers"><colgroup><col class="header_name_col"><col class="header_val_col"></colgroup>'; 768 if (array_key_exists('type', $data)) { 769 $type = build_github_subject($data, $output_mod); 770 } 771 else { 772 $type = '[Unknown Type]'; 773 } 774 if (array_key_exists('created_at', $data)) { 775 $date = sprintf("%s", date('r', strtotime($data['created_at']))); 776 } 777 else { 778 $date = '[No date]'; 779 } 780 $repo_link = ''; 781 $from_link = ''; 782 783 if (array_key_exists('actor', $data) && array_key_exists('login', $data['actor'])) { 784 $from = $data['actor']['login']; 785 $from_link = sprintf(' - <a href="https://github.com/%s">https://github.com/%s</a>', $output_mod->html_safe($from), $output_mod->html_safe($from)); 786 } 787 else { 788 $from = '[No From]'; 789 } 790 if (array_key_exists('repo', $data) && array_key_exists('name', $data['repo'])) { 791 $name = $data['repo']['name']; 792 $repo_link = sprintf(' - <a href="https://github.com/%s">https://github.com/%s</a>', $output_mod->html_safe($name), $output_mod->html_safe($name)); 793 } 794 else { 795 $name = '[No Repo]'; 796 } 797 $res .= '<tr class="header_subject"><th colspan="2">'.$output_mod->html_safe($type).'</th></tr>'; 798 $res .= '<tr class="header_date"><th>'.$output_mod->trans('Date').'</th><td>'.$output_mod->html_safe($date).'</td></tr>'; 799 $res .= '<tr class="header_from"><th>'.$output_mod->trans('Author').'</th><td>'.$output_mod->html_safe($from).$from_link.'</td></tr>'; 800 $res .= '<tr><th>'.$output_mod->trans('Repository').'</th><td>'.$output_mod->html_safe($name).$repo_link.'</td></tr>'; 801 $res .= '<tr><td></td><td></td></tr></table>'; 802 return $res; 803}} 804 805/** 806 * @subpackage github/functions 807 */ 808if (!hm_exists('github_parse_payload')) { 809function github_parse_payload($data, $output_mod) { 810 $type = false; 811 if (array_key_exists('type', $data)) { 812 $type = $data['type']; 813 } 814 /* Event types: CommitCommentEvent CreateEvent DeleteEvent DeploymentEvent DeploymentStatusEvent DownloadEvent FollowEvent 815 * ForkEvent ForkApplyEvent GistEvent GollumEvent IssueCommentEvent IssuesEvent MemberEvent MembershipEvent PageBuildEvent 816 * PublicEvent PullRequestEvent PullRequestReviewCommentEvent PushEvent ReleaseEvent RepositoryEvent StatusEvent TeamAddEvent 817 * WatchEvent */ 818 819 $data = $data['payload']; 820 $content = payload_search($data); 821 $res = '<div class="msg_text_inner">'; 822 foreach ($content as $vals) { 823 $res .= '<div class="github_para">'; 824 if (array_key_exists('name', $vals)) { 825 $res .= $output_mod->html_safe($vals['name']); 826 $res .= '</div><div class="github_para">'; 827 } 828 if (array_key_exists('body', $vals)) { 829 $res .= $output_mod->html_safe(wordwrap($vals['body'], 100)); 830 } 831 if (array_key_exists('message', $vals)) { 832 $res .= $output_mod->html_safe(wordwrap($vals['message'], 100)); 833 } 834 if (array_key_exists('html_url', $vals)) { 835 $res .= sprintf('<div class="github_link"><a href="%s">%s</a></div>', 836 $output_mod->html_safe($vals['html_url']), $output_mod->html_safe($vals['html_url'])); 837 } 838 if (array_key_exists('url', $vals) && array_key_exists('sha', $vals)) { 839 $url = str_replace(array('commits', 'https://api.github.com/repos'), array('commit', 'https://github.com'), $vals['url']); 840 $res .= sprintf('<div class="github_link"><a href="%s">%s</a></div>', 841 $output_mod->html_safe($url), $output_mod->html_safe($vals['sha'])); 842 } 843 $res .= '</div>'; 844 } 845 $res .= '</div>'; 846 return $res; 847}} 848 849/** 850 * @subpackage github/functions 851 */ 852if (!hm_exists('payload_search')) { 853function payload_search($data) { 854 $res = array(); 855 $data_flds = array('url', 'sha', 'body', 'description', 'message', 'name'); 856 foreach($data as $vals) { 857 if (is_array($vals)) { 858 $item = array(); 859 foreach ($data_flds as $fld) { 860 if (array_key_exists($fld, $vals)) { 861 $item[$fld] = $vals[$fld]; 862 } 863 } 864 if (!empty($item)) { 865 if (array_key_exists('html_url', $data)) { 866 $item['html_url'] = $vals['html_url']; 867 } 868 } 869 else { 870 $res = array_merge($res, payload_search($vals)); 871 } 872 if (count($item) > 0) { 873 $res[] = $item; 874 } 875 } 876 } 877 return $res; 878}} 879