xaizek / rocketgit (License: AGPLv3+) (since 2018-12-09)
Light and fast Git hosting solution suitable to serve both as a hub or as a personal code storage with its tickets, pull requests, API and much more.
<root> / inc / plan.inc.php (b2cea788562931508fc9786c38f7bf575b2bac12) (7,829B) (mode 100644) [raw]
<?php
require_once($INC . "/util.inc.php");
require_once($INC . "/log.inc.php");
require_once($INC . "/sql.inc.php");
require_once($INC . "/events.inc.php");
require_once($INC . "/cache.inc.php");

$rg_plan_error = "";

function rg_plan_set_error($str)
{
	global $rg_plan_error;
	$rg_plan_error = $str;
	rg_log($str);
}

function rg_plan_error()
{
	global $rg_plan_error;
	return $rg_plan_error;
}

/*
 * Validates plan name
 */
function rg_plan_ok($name)
{
	if (empty($name))
		return FALSE;

	return TRUE;
}

/*
 * Add/edit a plan
 * If uid > 0 - edit, else, add
 */
function rg_plan_edit($db, $d)
{
	rg_prof_start("plan_edit");
	rg_log_enter("plan_edit: d: " . rg_array2string($d));

	$ret = FALSE;
	while (1) {
		if (rg_plan_ok($d['name']) !== TRUE)
			break;

		if ($d['id'] == 0) { // add
			$sql = "INSERT INTO plans (name, description, disk_mb"
				. ", users, bw, speed, position"
				. ", max_public_repos, max_private_repos)"
				. " VALUES (@@name@@, @@description@@"
				. ", @@disk_mb@@, @@users@@, @@bw@@"
				. ", @@speed@@, @@position@@"
				. ", @@max_public_repos@@, @@max_private_repos@@)"
				. " RETURNING id";
		} else { // edit
			$sql = "UPDATE plans"
				. " SET name = @@name@@"
				. ", description = @@description@@"
				. ", disk_mb = @@disk_mb@@"
				. ", users = @@users@@"
				. ", bw = @@bw@@"
				. ", speed = @@speed@@"
				. ", position = @@position@@"
				. ", max_public_repos = @@max_public_repos@@"
				. ", max_private_repos = @@max_private_repos@@"
				. " WHERE id = @@id@@"
				. " RETURNING id";
		}

		$res = rg_sql_query_params($db, $sql, $d);
		if ($res === FALSE) {
			rg_plan_set_error('cannot insert/update plan');
			break;
		}
		$row = rg_sql_fetch_array($res);
		rg_sql_free_result($res);

		$d['id'] = $row['id'];

		// invalidate cache
		rg_cache_unset('plan::list', RG_SOCKET_NO_WAIT);

		$ret = $row['id'];
		break;
	}

	rg_log_exit();
	rg_prof_end("plan_edit");
	return $ret;
}

/*
 * Delete plans; list is array("<id>" => "<junk>, ...)
 */
function rg_plan_remove($db, $list)
{
	rg_prof_start("plan_remove");
	rg_log_enter("plan_remove: list=" . rg_array2string($list));

	$ret = FALSE;
	while (1) {
		$my_list = array();
		foreach ($list as $id => $junk)
			$my_list[] = sprintf("%u", $id);

		$sql_list = implode(", ", $my_list);
		$sql = "DELETE FROM plans WHERE id IN (" . $sql_list . ")";
		$res = rg_sql_query($db, $sql);
		if ($res === FALSE) {
			rg_plan_set_error('cannot remove plans');
			break;
		}
		rg_sql_free_result($res);

		// invalidate cache
		rg_cache_unset('plan::list', RG_SOCKET_NO_WAIT);

		$ret = TRUE;
		break;
	}

	rg_log_exit();
	rg_prof_end("plan_remove");
	return $ret;
}

/*
 * 
 */
function rg_plan_cosmetic(&$row)
{
	$_a = rg_xss_safe(trim($row['description']));
	$row['HTML:description_nlbr'] = nl2br($_a);

	$row['exists'] = 1;
}

/*
 *
 */
function rg_plan_cosmetic_list(&$a)
{
	foreach ($a as $id => &$row)
		rg_plan_cosmetic($row);
}

/*
 * Return the list of plans
 */
function rg_plan_list($db)
{
	rg_prof_start("plan_list");
	rg_log_enter("plan_list");

	$ret = FALSE;
	while (1) {
		$ret = rg_cache_get("plan::list");
		if ($ret !== FALSE) {
			rg_plan_cosmetic_list($ret);
			break;
		}

		$sql = "SELECT * FROM plans ORDER BY position";
		$res = rg_sql_query($db, $sql);
		if ($res === FALSE) {
			rg_plan_set_error('cannot get plan list');
			break;
		}

		$ret = array();
		while (($row = rg_sql_fetch_array($res))) {
			$id = $row['id'];
			$ret[$id] = $row;
		}
		rg_sql_free_result($res);

		rg_cache_set("plan::list", $ret, RG_SOCKET_NO_WAIT);
		rg_plan_cosmetic_list($ret);
		break;
	}

	rg_log_exit();
	rg_prof_end("plan_list");
	return $ret;
}

/*
 * Returns info about a plan (by id)
 */
function rg_plan_info($db, $id)
{
	rg_prof_start("plan_info");
	rg_log_enter("plan_info: id=$id");

	$ret = array();
	$ret['ok'] = 0;
	$ret['exists'] = 0;
	while (1) {
		$list = rg_plan_list($db);
		if ($list === FALSE)
			break;

		$ret['ok'] = 1;

		$id = sprintf("%u", $id);
		if (!isset($list[$id]))
			break;

		$ret = array_merge($ret, $list[$id]);
		break;
	}

	rg_log_exit();
	rg_prof_end("plan_info");
	return $ret;
}

/*
 * Returns a select list
 * @name - the variable name
 */
function rg_plan_select($db, $name, $plan_id)
{
	$list = rg_plan_list($db);
	if ($list === FALSE)
		return rg_warning("Could not load plans.");

	$ret = "<select name=\"" . $name . "\" id=\"plan_id\">\n";
	foreach ($list as $row) {
		$add = "";
		if ($row['id'] == $plan_id)
			$add = " selected";
		$ret .= "<option value=\"" . rg_xss_safe($row['id'])
			. "\"" . $add . ">"
			. rg_xss_safe($row['name']) . "</option>\n";
	}

	$ret .= "</select>\n";

	return $ret;
}

/*
 * High-level function for rg_plan_list
 */
function rg_plan_list_high_level($db, $rg)
{
	rg_log_enter('plan_high_list');

	$ret = '';

	$del_errmsg = array();

	$delete = rg_var_uint('delete');
	while ($delete == 1) {
		if (!rg_valid_referer()) {
			$del_errmsg[] = 'invalid referer; try again';
			break;
		}

		if (!rg_token_valid($db, $rg, 'plan_list', FALSE)) {
			$del_errmsg[] = 'invalid token; try again.';
			break;
		}

		$list = rg_var_str('delete_list');
		$r = rg_plan_remove($db, $list);
		if ($r !== TRUE) {
			$rg['errmsg'] = rg_plan_error();
			$del_errmsg[] = rg_template(
				'admin/plans/delete_err.html',
				$rg, TRUE /*xss*/);
			break;
		}
		break;
	}

	$errmsg = array();
	$list = rg_plan_list($db);
	if ($list === FALSE) {
		$rg['errmsg'] = rg_plan_error();
		// TODO: really? no array append?!
		return rg_template('admin/plans/list_err.html',
			$rg, TRUE /*xss*/);
	} else {
		$rg['rg_form_token'] = rg_token_get($db, $rg, 'plan_list');
		$rg['HTML:del_errmsg'] = rg_template_errmsg($del_errmsg);
		$ret .= rg_template_table("admin/plans/list", $list, $rg);
	}

	rg_log_exit();
	return $ret;
}

/*
 * High-level function for rg_plan_edit.
 */
function rg_plan_edit_high_level($db, &$rg)
{
	rg_log("plan_edit_high_level rg:" . rg_array2string($rg));

	if (isset($rg['pi']['id']))
		$id = $rg['pi']['id'];
	else
		$id = 0;

	$ret = "";
	$pi = array();

	if ($rg['doit'] == 0) {
		if ($id > 0) {
			$pi = rg_plan_info($db, $id);
			if ($pi['exists'] != 1) {
				$ret .= rg_warning("Invalid plan.");
				return $ret;
			}
		} else {
			// Defaults
			$pi['id'] = 0;
			$pi['name'] = "";
			$pi['description'] = "";
			$pi['disk_mb'] = "0";
			$pi['users'] = "0";
			$pi['bw'] = "0";
			$pi['speed'] = "0";
			$pi['position'] = "100";
			$pi['max_public_repos'] = "0";
			$pi['max_private_repos'] = "0";
		}
	}

	$errmsg = array();
	$load_form = TRUE;
	while (1) {
		if ($rg['doit'] != 1)
			break;

		$pi = array();
		if ($id > 0)
			$pi['id'] = $id;
		else
			$pi['id'] = rg_var_uint("pi::id");
		$pi['name'] = rg_var_str("pi::name");
		$pi['description'] = trim(rg_var_str("pi::description"));
		$pi['disk_mb'] = rg_var_uint("pi::disk_mb");
		$pi['users'] = rg_var_uint("pi::users");
		$pi['bw'] = rg_var_uint("pi::bw");
		$pi['speed'] = rg_var_uint("pi::speed");
		$pi['position'] = rg_var_uint("pi::position");
		$pi['max_public_repos'] = rg_var_uint("pi::max_public_repos");
		$pi['max_private_repos'] = rg_var_uint("pi::max_private_repos");

		if (!rg_valid_referer()) {
			$errmsg[] = "invalid referer; try again";
			break;
		}

		if (!rg_token_valid($db, $rg, 'plan_edit_hl', FALSE)) {
			$errmsg[] = "invalid token; try again";
			break;
		}

		$r = rg_plan_edit($db, $pi);
		if ($r === FALSE) {
			$errmsg[] = "cannot add/edit plan: " . rg_plan_error();
			break;
		}

		$ret .= rg_template("admin/plans/add_ok.html", $rg, TRUE /* xss */);
		$load_form = FALSE;
		break;
	}

	if ($load_form) {
		$rg['pi'] = $pi;
		$rg['HTML:errmsg'] = rg_template_errmsg($errmsg);
		$rg['rg_form_token'] = rg_token_get($db, $rg, 'plan_edit_hl');
		$ret .= rg_template("admin/plans/add_edit.html", $rg, TRUE /* xss */);
	}

	return $ret;
}

?>
Hints

Before first commit, do not forget to setup your git environment:
git config --global user.name "your_name_here"
git config --global user.email "your@email_here"

Clone this repository using HTTP(S):
git clone https://code.reversed.top/user/xaizek/rocketgit

Clone this repository using ssh (do not forget to upload a key first):
git clone ssh://rocketgit@code.reversed.top/user/xaizek/rocketgit

You are allowed to anonymously push to this repository.
This means that your pushed commits will automatically be transformed into a pull request:
... clone the repository ...
... make some changes and some commits ...
git push origin master