<?php require_once($INC . "/util.inc.php"); require_once($INC . "/log.inc.php"); require_once($INC . "/sql.inc.php"); require_once($INC . "/prof.inc.php"); $rg_wh_error = ""; function rg_wh_set_error($str) { global $rg_wh_error; $rg_wh_error = $str; rg_log($str); } function rg_wh_error() { global $rg_wh_error; return $rg_wh_error; } // Here plugins will store the functions $rg_wh_plugins = array(); $rg_wh_events = array( 'C' => 'Create repository', 'P' => 'Push', 'B' => 'Create branch' ); /* * Generates event list as html */ function rg_wh_check_events($events) { global $rg_wh_events; $ret = '<fieldset>'; $ret .= '<legend>Select trigger events</legend>'; $br = ''; foreach ($rg_wh_events as $id => $name) { $add = ''; if (strchr($events, $id)) $add = ' checked="checked"'; $ret .= $br . '<input type="checkbox" name="wh::events[' . $id . ']"' . ' id="events-' . $id . '"' . $add . ' />' . "\n" . '<label for="events-' . $id . '">' . $name . '</label>'; $br = '<br />' . "\n"; } $ret .= '</fieldset>' . "\n"; return $ret; } /* * Generates an events list as text */ function rg_wh_events($events) { global $rg_wh_events; $a = array(); foreach ($rg_wh_events as $id => $name) { if (strchr($events, $id)) $a[] = $name; } return implode(', ', $a); } /* * Some cosmetics applied to a webhook */ function rg_wh_cosmetic(&$list) { global $rg_wh_plugins; foreach ($list as $id => &$row) { if (isset($row['itime'])) $row['itime_nice'] = gmdate('Y-m-d H:i', $row['itime']); if (isset($row['description'])) { if (empty($row['description'])) $row['HTML:description_nice'] = 'n/a'; else $row['HTML:description_nice'] = nl2br(rg_xss_safe($row['description'])); } if (isset($row['events'])) $row['events_text'] = rg_wh_events($row['events']); if (isset($row['last_output'])) { if (empty($row['last_output'])) $row['HTML:last_output_nice'] = 'n/a'; else $row['HTML:last_output_nice'] = nl2br(rg_xss_safe($row['last_output'])); } $t = $row['htype']; if (isset($rg_wh_plugins[$t]['cosmetic'])) $rg_wh_plugins[$t]['cosmetic']($row); } } /* * Set last_output field of a webhook */ function rg_wh_set_last_output($db, $uid, $id, $output) { rg_prof_start('wh_set_last_output'); rg_log_enter('wh_set_last_output id=$id'); $ret = FALSE; while (1) { $params = array('id' => $id, 'last_output' => $output); $sql = 'UPDATE webhooks' . ' SET last_output = @@last_output@@' . ' WHERE id = @@id@@'; $res = rg_sql_query_params($db, $sql, $params); if ($res === FALSE) { rg_wh_set_error('cannot insert/update data'); break; } rg_sql_free_result($res); $key = 'wh' . '::' . $uid . '::' . 'list' . '::' . $id . '::' . 'last_output'; rg_cache_set($key, $output, RG_SOCKET_NO_WAIT); $ret = TRUE; break; } rg_log_exit(); rg_prof_end('wh_set_last_output'); return $ret; } /* * Sorting the webhooks list by itime DESC */ function rg_wh_sort_helper($a, $b) { if ($a['itime'] > $b['itime']) return -1; if ($a['itime'] == $b['itime']) return 0; return 1; } /* * Returns a list of webhooks associated with a user * @repo_id may be 0 => hooks installed on user account */ function rg_wh_list($db, $uid) { rg_prof_start('wh_list'); rg_log_enter('wh_list'); $ret = array('ok' => 0, 'list' => array()); while (1) { $key = 'wh' . '::' . $uid; $r = rg_cache_get($key); if (($r !== FALSE) && isset($r['LIST_LOADED'])) { $ret['list'] = $r['list']; $ret['ok'] = 1; break; } $params = array('uid' => $uid); $sql = 'SELECT * FROM webhooks' . ' WHERE uid = @@uid@@' . ' ORDER BY itime DESC'; $res = rg_sql_query_params($db, $sql, $params); if ($res === FALSE) { rg_wh_set_error('cannot load data'); break; } while (($row = rg_sql_fetch_array($res))) { //rg_log_ml('DEBUG: wh_list: row: ' . print_r($row, TRUE)); $id = $row['id']; if (strcmp($row['idata'], "") != 0) { $row['idata'] = unserialize($row['idata']); if ($row['idata'] === FALSE) { rg_internal_error('cannot unserialize data'); // we try to continue $row['idata'] = array(); } } else { $row['idata'] = array(); } $ret['list'][$id] = $row; } rg_sql_free_result($res); $a = array('LIST_LOADED' => 1, 'list' => $ret['list']); rg_cache_merge($key, $a, RG_SOCKET_NO_WAIT); $ret['ok'] = 1; break; } uasort($ret['list'], 'rg_wh_sort_helper'); rg_log_exit(); rg_prof_end('wh_list'); return $ret; } /* * Adds/edits a webhook */ function rg_wh_add($db, $uid, $data) { rg_prof_start('wh_add'); rg_log_enter('wh_add'); $ret = array('ok' => 0); while (1) { $data['uid'] = $uid; $data['itime'] = time(); $params = $data; $params['idata'] = serialize($params['idata']); if ($data['id'] == 0) { $data['last_output'] = ''; $sql = 'INSERT INTO webhooks (uid, repo_id, itime' . ', htype, events, url' . ', add_ip, description, key, opaque, idata)' . ' VALUES (@@uid@@, @@repo_id@@, @@itime@@' . ', @@htype@@, @@events@@, @@url@@' . ', @@add_ip@@' . ', @@description@@, @@key@@, @@opaque@@' . ', @@idata@@)' . ' RETURNING id'; } else { $sql = 'UPDATE webhooks' . ' SET events = @@events@@' . ', url = @@url@@' . ', description = @@description@@' . ', key = @@key@@' . ', opaque = @@opaque@@' . ', idata = @@idata@@' . ' WHERE uid = @@uid@@' . ' AND id = @@id@@'; } $res = rg_sql_query_params($db, $sql, $params); if ($res === FALSE) { rg_wh_set_error('cannot insert/update data'); break; } if ($data['id'] == 0) $row = rg_sql_fetch_array($res); rg_sql_free_result($res); if ($data['id'] == 0) $data['id'] = $row['id']; $key = 'wh' . '::' . $uid . '::' . 'list' . '::' . $data['id']; rg_cache_merge($key, $data, RG_SOCKET_NO_WAIT); $ret['ok'] = 1; break; } rg_log_exit(); rg_prof_end('wh_add'); return $ret; } /* * Removes a list of webhooks */ function rg_wh_remove($db, $uid, $list) { rg_prof_start('wh_remove'); rg_log_enter('wh_remove'); $ret = array('ok' => 0); while (1) { if (empty($list)) { rg_wh_set_error('you did not select anything'); break; } $my_list = array(); foreach ($list as $id => $junk) $my_list[] = sprintf("%u", $id); $params = array('uid' => $uid); $sql_list = implode(', ', $my_list); $sql = 'DELETE FROM webhooks' . ' WHERE uid = @@uid@@' . ' AND id IN (' . $sql_list . ')'; $res = rg_sql_query_params($db, $sql, $params); if ($res === FALSE) { rg_wh_set_error('cannot remove webhooks'); break; } rg_sql_free_result($res); foreach ($my_list as $junk => $id) { $key = 'wh' . '::' . $uid . '::' . 'list' . '::' . $id; rg_cache_unset($key, RG_SOCKET_NO_WAIT); } $ret['ok'] = 1; break; } rg_log_exit(); rg_prof_end('wh_remove'); return $ret; } /* * Extract vars from request */ function rg_wh_fill_vars(&$rg) { global $rg_wh_plugins; $ret = FALSE; while (1) { $t = $rg['wh']['htype']; if (!isset($rg_wh_plugins[$t])) { $errmsg[] = rg_template('user/settings/wh/invalid_htype', $rg, TRUE /*xss*/); break; } if (isset($rg_wh_plugins[$t]['fill_vars'])) { $rg_wh_plugins[$t]['fill_vars']($rg); break; } $ret = TRUE; break; } return $ret; } /* * Validate parameters */ function rg_wh_validate_vars($rg, &$errmsg) { global $rg_wh_plugins; $ret = FALSE; while (1) { $t = $rg['wh']['htype']; if (!isset($rg_wh_plugins[$t])) { $errmsg[] = rg_template('user/settings/wh/invalid_htype', $rg, TRUE /*xss*/); break; } if (isset($rg_wh_plugins[$t]['validate_vars'])) { $r = $rg_wh_plugins[$t]['validate_vars']($rg, $errmsg); if ($r !== TRUE) break; } $ret = TRUE; break; } return $ret; } /* * Generic add_form function */ function rg_wh_add_form(&$rg) { global $rg_wh_plugins; while (1) { $t = $rg['wh']['htype']; if (!isset($rg_wh_plugins[$t])) break; if (isset($rg_wh_plugins[$t]['add_form'])) { $rg_wh_plugins[$t]['add_form']($rg); break; } break; } } /* * Generic default_paras function */ function rg_wh_default_paras(&$rg) { global $rg_wh_plugins; while (1) { $t = $rg['wh']['htype']; if (!isset($rg_wh_plugins[$t])) break; if (isset($rg_wh_plugins[$t]['default_paras'])) { $rg_wh_plugins[$t]['default_paras']($rg); break; } break; } } /* * Generic hints add function */ function rg_wh_fill_hints(&$rg, &$hints) { global $rg_wh_plugins; while (1) { $t = $rg['wh']['htype']; if (!isset($rg_wh_plugins[$t])) break; if (isset($rg_wh_plugins[$t]['fill_hints'])) { $rg_wh_plugins[$t]['fill_hints']($rg, $hints); break; } break; } } /* * Returns a HTML list with possible htypes */ function rg_wh_htypes($rg) { global $rg_wh_plugins; return rg_template_table('user/settings/wh/plugins_list', $rg_wh_plugins, $rg); } ?>