<commit_before><?
/**
 * proposal.php
 *
 * @author <NAME> <<EMAIL>>
 * @package Basisentscheid
 */


require "inc/common.php";

URI::strip_one_time_params(array('argument_parent', 'argument_edit', 'edit_admission_decision', 'show_drafts', 'edit_proponent', 'become_proponent', 'remove_proponent'));

$proposal = new Proposal(@$_GET['id']);
if (!$proposal->id) {
	error("The requested proposal does not exist!");
}

$issue = $proposal->issue();

if (Login::$member) $edit_limit = strtotime("- ".ARGUMENT_EDIT_INTERVAL);

if ($action) {
	switch ($action) {

	case "submit_proposal":
		Login::access_action("member");
		if ($proposal->state!="draft") {
			warning(_("The proposal has already been submitted."));
			redirect("proposal.php?id=".$proposal->id);
		}
		if (!$proposal->is_proponent(Login::$member)) {
			warning(_("Your are not a proponent of this proposal."));
			redirect();
		}
		if ($proposal->proponents_count() < Proposal::proponents_required_submission) {
			warning(sprintf(_("For submission %d proponents are required."), Proposal::proponents_required_submission));
			redirect();
		}
		$proposal->submit();
		redirect();
		break;
	case "revoke_proposal":
		Login::access_action("member");
		if ($issue->state != "admission" and $issue->state != "debate") {
			warning(_("In the current phase the proposal can not be revoked anymore."));
			redirect();
		}
		if (!$proposal->is_proponent(Login::$member)) {
			warning(_("Your are not a proponent of this proposal."));
			redirect();
		}
		$proposal->cancel("revoked");
		redirect();
		break;

	case "apply_proponent":
		Login::access_action("member");
		action_required_parameters('proponent');
		if (!$proposal->allowed_edit_proponent()) {
			warning(_("Your proponent info can not be changed anymore once voting preparation has started or the proposal has been closed!"));
			redirect();
		}
		$proponent = trim($_POST['proponent']);
		if (!$proponent) {
			warning(_("Your proponent info must be not empty."));
			redirect();
		}
		if (mb_strlen($proponent) > Proposal::proponent_length) {
			$proponent = limitstr($proponent, Proposal::proponent_length);
			warning(sprintf(_("The input has been truncated to the maximum allowed length of %d characters!"), Proposal::proponent_length));
		}
		$proposal->update_proponent($proponent);
		redirect();
		break;
	case "become_proponent":
		Login::access_action("member");
		action_required_parameters('proponent');
		if (!$proposal->allowed_edit_proponent()) {
			warning(_("You can not become proponent anymore once voting preparation has started or the proposal has been closed!"));
			redirect();
		}
		$proponent = trim($_POST['proponent']);
		if (!$proponent) {
			warning(_("Your proponent info must be not empty."));
			redirect();
		}
		if (mb_strlen($proponent) > Proposal::proponent_length) {
			$proponent = limitstr($proponent, Proposal::proponent_length);
			warning(sprintf(_("The input has been truncated to the maximum allowed length of %d characters!"), Proposal::proponent_length));
		}
		$proposal->add_support(false, $proponent);
		notice(_("Your application to become proponent has been submitted to the current proponents to confirm your request."));
		redirect();
		break;
	case "confirm_proponent":
		Login::access_action("member");
		action_required_parameters('member');
		if (!$proposal->allowed_edit_proponent()) {
			warning(_("You can not confirm proponents anymore once voting preparation has started or the proposal has been closed!"));
			redirect();
		}
		if (!$proposal->is_proponent(Login::$member)) {
			warning(_("Your are not a proponent of this proposal."));
			redirect();
		}
		$member = new Member($_POST['member']);
		if (!$member->id) {
			warning("The member does not exist.");
			redirect();
		}
		if (!$proposal->is_proponent($member, false)) {
			warning(_("The to be confirmed member is not applying to become proponent of this proposal."));
			redirect();
		}
		$proposal->confirm_proponent($member);
		redirect();
		break;
	case "confirm_remove_proponent":
		Login::access_action("member");
		if (!$proposal->allowed_edit_proponent()) {
			warning(_("You can not remove yourself from the proponents list once voting preparation has started or the proposal has been closed!"));
			redirect();
		}
		$proposal->remove_proponent(Login::$member);
		redirect();
		break;

	case "add_support":
		Login::access_action("member");
		if (!$proposal->admission()) {
			warning("Support for this proposal can not be added, because it is not in the admission phase!");
			redirect();
		}
		$proposal->add_support(@$_POST['anonymous']==1);
		redirect();
		break;
	case "revoke_support":
		Login::access_action("member");
		if (!$proposal->admission()) {
			warning("Support for this proposal can not be removed, because it is not in the admission phase!");
			redirect();
		}
		if ($proposal->is_proponent(Login::$member, false)) {
			warning("You can not remove your support while you are proponent!");
			redirect();
		}
		$proposal->revoke_support();
		redirect();
		break;
	case "demand_ballot_voting":
		Login::access_action("member");
		if (!$issue->voting_type_determination()) {
			warning("Demand for ballot voting can not be added, because the proposal is not in admission, admitted or debate phase!");
			redirect();
		}
		$issue->demand_ballot_voting(@$_POST['anonymous']==1);
		redirect();
		break;
	case "revoke_demand_for_ballot_voting":
		Login::access_action("member");
		if (!$issue->voting_type_determination()) {
			warning("Demand for ballot voting can not be removed, because the proposal is not in admission, admitted or debate phase!");
			redirect();
		}
		$issue->revoke_demand_for_ballot_voting();
		redirect();
		break;

	case "select_period":
		Login::access_action("admin");
		action_proposal_select_period();
		break;

	case "admission_decision":
		Login::access_action("admin");
		action_required_parameters("admission_decision");
		$proposal->set_admission_decision(trim($_POST['admission_decision']));
		redirect();
		break;

	case "add_argument":
		Login::access_action("member");
		action_required_parameters("title", "content", "parent");
		if (!$proposal->allowed_add_arguments()) {
			warning(_("Adding or rating arguments is allowed in this phase."));
			redirect();
		}
		$argument = new Argument;
		if ($_POST['parent']=="pro" or $_POST['parent']=="contra") {
			$argument->parent = 0;
			$argument->side = $_POST['parent'];
		} else {
			$parent = new Argument($_POST['parent']);
			if (!$parent->id) {
				warning("Parent argument does not exist.");
				redirect();
			}
			$argument->parent = $parent->id;
			$argument->side = $parent->side;
		}
		$argument->proposal = $proposal->id;
		$argument->member = Login::$member->id;

		$argument->title = trim($_POST['title']);
		if (!$argument->title) {
			warning("The title of the argument must be not empty.");
			break;
		}
		if (mb_strlen($argument->title) > Argument::title_length) {
			$argument->title = limitstr($argument->title, Argument::title_length);
			warning(sprintf(_("The title has been truncated to the maximum allowed length of %d characters!"), Argument::title_length));
		}

		$argument->content = trim($_POST['content']);
		if (!$argument->content) {
			warning("The content of the argument must be not empty.");
			break;
		}
		if (mb_strlen($argument->content) > Argument::content_length) {
			$argument->content = limitstr($argument->content, Argument::content_length);
			warning(sprintf(_("The content has been truncated to the maximum allowed length of %d characters!"), Argument::content_length));
		}

		$argument->create();
		redirect(URI::same()."#argument".$argument->id);
		break;

	case "update_argument":
		Login::access_action("member");
		action_required_parameters("title", "content", "id");
		$argument = new Argument($_POST['id']);
		if (!$argument->id) {
			warning("This argument does not exist.");
			redirect();
		}
		if ($argument->member!=Login::$member->id) {
			warning("You are not the author of the argument.");
			redirect();
		}
		if (strtotime($argument->created) < $edit_limit) {
			warning("This argument may not be updated any longer.");
			redirect();
		}
		$argument->title = trim($_POST['title']);
		if (!$argument->title) {
			warning("The title of the argument must be not empty.");
			break;
		}
		$argument->content = trim($_POST['content']);
		if (!$argument->content) {
			warning("The content of the argument must be not empty.");
			break;
		}
		$argument->update(array("title", "content"), "updated=now()");
		redirect(URI::same()."#argument".$argument->id);
		break;

	case "remove_argument":
	case "restore_argument":
		Login::access_action("admin");
		action_required_parameters("id");
		$argument = new Argument($_POST['id']);
		if (!$argument->id) {
			warning("This argument does not exist.");
			redirect();
		}
		$argument->removed = ($action=="remove_argument");
		$argument->update(array("removed"));
		redirect(URI::same()."#argument".$argument->id);
		break;

	case "rating_plus":
	case "rating_minus":
		Login::access_action("member");
		action_required_parameters("argument");
		if (!$proposal->allowed_add_arguments()) {
			warning(_("Adding or rating arguments is allowed in this phase."));
			redirect();
		}
		$argument = new Argument($_POST['argument']);
		if (!$argument->id) {
			warning("This argument does not exist.");
			redirect();
		}
		if ($argument->member==Login::$member->id) {
			warning("Rating your own arguments is not allowed.");
			redirect();
		}
		if ($argument->removed) {
			warning("The argument has been removed.");
			redirect();
		}
		$argument->set_rating($action=="rating_plus");
		redirect(URI::same()."#argument".$argument->id);
		break;

	case "rating_reset":
		Login::access_action("member");
		action_required_parameters("argument");
		if (!$proposal->allowed_add_arguments()) {
			warning(_("Adding or rating arguments is allowed in this phase."));
			redirect();
		}
		$argument = new Argument($_POST['argument']);
		if (!$argument->id) {
			warning("This argument does not exist.");
			redirect();
		}
		if ($argument->removed) {
			warning("The argument has been removed.");
			redirect();
		}
		$argument->delete_rating();
		redirect(URI::same()."#argument".$argument->id);
		break;

	default:
		warning(_("Unknown action"));
		redirect();
	}
}


if (isset($_GET['draft'])) {
	$draft = new Draft($_GET['draft']);
	if ($draft->proposal != $proposal->id) {
		error("The requested draft does not exist!");
	}
	html_head(sprintf(_("Proposal %d, draft from %s"), $proposal->id, datetimeformat($draft->created)));
	$content_obj = $draft;
} else {
	html_head(_("Proposal")." ".$proposal->id);
	$content_obj = $proposal;
}


if (isset($_GET['remove_proponent']) and $proposal->is_proponent(Login::$member, false)) {
?>
<div class="messages">
<?
	if (!$proposal->allowed_edit_proponent()) {
		warning(_("You can not remove yourself from the proponents list once voting preparation has started or the proposal has been closed!"));
	} else {
		form(URI::same(), 'class="notice"');
?>
&#10148; <?=_("Do you really want to remove yourself from the proponents of this proposal?")?>
<input type="hidden" name="action" value="confirm_remove_proponent">
<input type="submit" value="<?=_("Yes")?>">
<a href="<?=URI::same()?>"><?=_("No")?></a>
</form>
<?
	}
?>
</div>
<div class="clearfix"></div>
<?
}


list($supporters, $proponents, $is_supporter, $is_proponent) = $proposal->supporters();

?>

<div class="proposal_info">
<? display_proposal_info($proposal, $issue, $proponents, $is_proponent); ?>
</div>

<div class="proposal_content">
<?
if ($proposal->state=="draft" and $is_proponent) {
?>
<div class="add"><a href="proposal_edit.php?id=<?=$proposal->id?>" class="icontextlink"><img src="img/edit.png" width="16" height="16" alt="<?=_("edit")?>"><?=_("Edit proposal")?></a></div>
<?
}
?>
<h2><?=_("Title")?></h2>
<p class="proposal proposal_title"><?=h($content_obj->title)?></p>
<h2><?=_("Content")?></h2>
<p class="proposal"><?=content2html($content_obj->content)?></p>
<h2><?=_("Reason")?></h2>
<p class="proposal"><?=content2html($content_obj->reason)?></p>
</div>

<div class="clearfix"></div>

<?
if ($proposal->state != "draft" and !isset($_GET['draft'])) {
?>
<div>
	<div class="arguments_side arguments_pro">
<?
	if (Login::$member and @$_GET['argument_parent']!="pro" and $proposal->allowed_add_arguments()) {
?>
		<div class="add"><a href="<?=URI::append(array('argument_parent'=>"pro"))?>#form" class="icontextlink"><img src="img/plus.png" width="16" height="16" alt="<?=_("plus")?>"><?=_("Add new pro argument")?></a></div>
<?
	}
?>
		<h2><?=_("Pro")?></h2>
		<? display_arguments("pro", "pro", 0); ?>
	</div>
	<div class="arguments_side arguments_contra">
<?
	if (Login::$member and @$_GET['argument_parent']!="contra" and $proposal->allowed_add_arguments()) {
?>
		<div class="add"><a href="<?=URI::append(array('argument_parent'=>"contra"))?>#form" class="icontextlink"><img src="img/plus.png" width="16" height="16" alt="<?=_("plus")?>"><?=_("Add new contra argument")?></a></div>
<?
	}
?>
		<h2><?=_("Contra")?></h2>
		<? display_arguments("contra", "contra", 0); ?>
	</div>
	<div class="clearfix"></div>
</div>

<?
	display_quorum($proposal, $issue, $supporters, $is_supporter);
}

list($proposals, $submitted) = $issue->proposals_list();
if ($submitted) {
	display_ballot_voting_quorum($issue, $submitted);
}
?>

<div class="issue">
<?
if (Login::$member and $issue->allowed_add_alternative_proposal()) {
?>
<div class="add"><a href="proposal_edit.php?issue=<?=$proposal->issue?>" class="icontextlink"><img src="img/plus.png" width="16" height="16" alt="<?=_("plus")?>"><?=_("Add alternative proposal")?></a></div>
<?
}
?>
<h2><?=_("This and alternative proposals")?></h2>
<table class="proposals">
<?
if (Login::$member) $issue->read_ballot_voting_demanded_by_member();
$show_results = in_array($issue->state, array('finished', 'cleared', 'cancelled'));
Issue::display_proposals_th($show_results);
$issue->display_proposals($proposals, $submitted, count($proposals), $show_results, $proposal->id);
?>
</table>
</div>

<?

html_foot();


/**
 *
 * @param object  $proposal
 * @param object  $issue
 * @param array   $proponents
 * @param boolean $is_proponent
 */
function display_proposal_info(Proposal $proposal, Issue $issue, array $proponents, $is_proponent) {
?>
<h2><?=_("Area")?></h2>
<p class="proposal"><?=h($issue->area()->name)?></p>
<?

	$is_any_proponent = false;
	if (Login::$member) {
		foreach ( $proponents as $proponent ) {
			if ($proponent->id==Login::$member->id) {
				$is_any_proponent = true;
				break;
			}
		}
		$allowed_edit_proponent = $proposal->allowed_edit_proponent();
		if ($allowed_edit_proponent and !$is_any_proponent) {
?>
<div class="add"><a href="<?=URI::append(array('become_proponent'=>1))?>" class="icontextlink"><img src="img/plus.png" width="16" height="16" alt="<?=_("plus")?>"><?=_("become proponent")?></a></div>
<?
		}
	}
?>
<h2><?=_("Proponents")?></h2>
<ul>
<?
	$confirmed_proponents = 0;
	foreach ( $proponents as $proponent ) {
		if ($proponent->proponent_confirmed) $confirmed_proponents++;
		// show unconfirmed proponents only to confirmed proponents and himself
		if (!$is_proponent and !$proponent->proponent_confirmed and (!Login::$member or $proponent->id!=Login::$member->id)) continue;
?>
	<li><?
		if (Login::$member and $proponent->id==Login::$member->id and $allowed_edit_proponent) {
			if (isset($_GET['edit_proponent'])) {
				form(URI::same());
?>
<input type="text" name="proponent" value="<?=h($proponent->proponent_name)?>" maxlength="<?=Proposal::proponent_length?>"><br>
<input type="hidden" name="action" value="apply_proponent">
<input type="submit" value="<?=_("apply changes")?>">
</form>
<?
			} else {
				if ($proponent->proponent_confirmed) {
					echo content2html($proponent->proponent_name);
				} else {
?>
<span class="unconfirmed"><?=content2html($proponent->proponent_name)?></span>
(<?=$proponent->username()?>)
<?
				}
				?> <a href="<?=URI::append(array('edit_proponent'=>1))?>" class="iconlink"><img src="img/edit.png" width="16" height="16" alt="<?=_("edit")?>" title="<?=_("edit your proponent name and contact details")?>"></a><a href="<?=URI::append(array('remove_proponent'=>1))?>" class="iconlink"><img src="img/delete.png" width="21" height="16" alt="<?=_("delete")?>" title="<?=_("remove yourself from the list of proponents")?>"></a><?
			}
		} elseif ($proponent->proponent_confirmed) {
			echo content2html($proponent->proponent_name);
		} elseif ($is_proponent and $allowed_edit_proponent) {
			form(URI::same());
?>
<span class="unconfirmed"><?=content2html($proponent->proponent_name)?></span>
(<?=$proponent->username()?>)
<input type="hidden" name="member" value="<?=$proponent->id?>">
<input type="hidden" name="action" value="confirm_proponent">
<input type="submit" value="<?=_("confirm")?>">
</form>
<?
		} else {
			?><span class="unconfirmed"><?=content2html($proponent->proponent_name)?></span><?
		}
		?></li>
<?
	}
	if (Login::$member and $allowed_edit_proponent and isset($_GET['become_proponent']) and !$is_any_proponent) {
?>
	<li><?
		form(URI::same());
?>
<input type="text" name="proponent" value="<?=h(Login::$member->username())?>" maxlength="<?=Proposal::proponent_length?>"><br>
<div class="explain"><?=_("Enter your name and contact details as you would like to see them in the proposal. To prevent fraud, your user name will also be shown to the other proponents:")?> <?=h(Login::$member->username())?></div>
<input type="hidden" name="action" value="become_proponent">
<input type="submit" value="<?=_("apply to become proponent")?>">
</form>
	</li>
<?
	}
?>
</ul>
<?

	if (!Login::$member and !Login::$admin) return;

?>
<h2><?=_("Drafts")?></h2>
<?
	if ($proposal->state=="draft" or !empty($_GET['show_drafts'])) {
?>
<table>
<?
		$sql = "SELECT * FROM drafts WHERE proposal=".intval($proposal->id)." ORDER BY created DESC";
		$result = DB::query($sql);
		$i = DB::num_rows($result);
		while ( $draft = DB::fetch_object($result, "Draft") ) {
			$author = new Member($draft->author);
?>
<tr class="<?=stripes()?>">
	<td class="right"><?=$i?></td>
	<td><a href="<?=URI::append(array('draft'=>$draft->id))?>"><?=datetimeformat($draft->created)?></a></td>
	<td><?=$author->username()?></td>
</tr>
<?
			$i--;
		}
?>
</table>
<?
	} else {
?>
<a href="<?=URI::append(array('show_drafts'=>1))?>"><?=_("Drafts")?></a>
<?
	}

	// actions
	if ($is_proponent) {
?>
<h2><?=_("Actions")?></h2>
<?
		if ($proposal->state=="draft" and $confirmed_proponents >= Proposal::proponents_required_submission) {
			form(URI::same());
?>
<input type="hidden" name="action" value="submit_proposal">
<input type="submit" value="<?=_("submit proposal")?>">
</form>
<?
		}
		if ($issue->state=="admission" or $issue->state=="debate") {
			form(URI::same());
?>
<input type="hidden" name="action" value="revoke_proposal">
<input type="submit" value="<?=_("revoke proposal")?>">
</form>
<?
		}
	}

}


/**
 * list the sub-arguments for one parent-argument
 *
 * @param string  $side   "pro" or "contra"
 * @param mixed   $parent ID of parent argument or "pro" or "contra"
 * @param integer $level
 */
function display_arguments($side, $parent, $level) {
	global $proposal, $edit_limit;

	$sql = "SELECT arguments.*, (arguments.plus - arguments.minus) AS rating";
	if (Login::$member) {
		$sql .= ", ratings.positive
			FROM arguments
			LEFT JOIN ratings ON ratings.argument = arguments.id AND ratings.member = ".intval(Login::$member->id);
	} else {
		$sql .= "
			FROM arguments";
	}
	// intval($parent) gives parent=0 for "pro" and "contra"
	$sql .= "	WHERE proposal=".intval($proposal->id)."
			AND side=".DB::esc($side)."
			AND parent=".intval($parent)."
		ORDER BY removed, rating DESC, arguments.created";<commit_msg>show drafts only to proponents<commit_after><?
/**
 * proposal.php
 *
 * @author <NAME> <<EMAIL>>
 * @package Basisentscheid
 */


require "inc/common.php";

URI::strip_one_time_params(array('argument_parent', 'argument_edit', 'edit_admission_decision', 'show_drafts', 'edit_proponent', 'become_proponent', 'remove_proponent'));

$proposal = new Proposal(@$_GET['id']);
if (!$proposal->id) {
	error("The requested proposal does not exist!");
}

$issue = $proposal->issue();

if (Login::$member) $edit_limit = strtotime("- ".ARGUMENT_EDIT_INTERVAL);

if ($action) {
	switch ($action) {

	case "submit_proposal":
		Login::access_action("member");
		if ($proposal->state!="draft") {
			warning(_("The proposal has already been submitted."));
			redirect("proposal.php?id=".$proposal->id);
		}
		if (!$proposal->is_proponent(Login::$member)) {
			warning(_("Your are not a proponent of this proposal."));
			redirect();
		}
		if ($proposal->proponents_count() < Proposal::proponents_required_submission) {
			warning(sprintf(_("For submission %d proponents are required."), Proposal::proponents_required_submission));
			redirect();
		}
		$proposal->submit();
		redirect();
		break;
	case "revoke_proposal":
		Login::access_action("member");
		if ($issue->state != "admission" and $issue->state != "debate") {
			warning(_("In the current phase the proposal can not be revoked anymore."));
			redirect();
		}
		if (!$proposal->is_proponent(Login::$member)) {
			warning(_("Your are not a proponent of this proposal."));
			redirect();
		}
		$proposal->cancel("revoked");
		redirect();
		break;

	case "apply_proponent":
		Login::access_action("member");
		action_required_parameters('proponent');
		if (!$proposal->allowed_edit_proponent()) {
			warning(_("Your proponent info can not be changed anymore once voting preparation has started or the proposal has been closed!"));
			redirect();
		}
		$proponent = trim($_POST['proponent']);
		if (!$proponent) {
			warning(_("Your proponent info must be not empty."));
			redirect();
		}
		if (mb_strlen($proponent) > Proposal::proponent_length) {
			$proponent = limitstr($proponent, Proposal::proponent_length);
			warning(sprintf(_("The input has been truncated to the maximum allowed length of %d characters!"), Proposal::proponent_length));
		}
		$proposal->update_proponent($proponent);
		redirect();
		break;
	case "become_proponent":
		Login::access_action("member");
		action_required_parameters('proponent');
		if (!$proposal->allowed_edit_proponent()) {
			warning(_("You can not become proponent anymore once voting preparation has started or the proposal has been closed!"));
			redirect();
		}
		$proponent = trim($_POST['proponent']);
		if (!$proponent) {
			warning(_("Your proponent info must be not empty."));
			redirect();
		}
		if (mb_strlen($proponent) > Proposal::proponent_length) {
			$proponent = limitstr($proponent, Proposal::proponent_length);
			warning(sprintf(_("The input has been truncated to the maximum allowed length of %d characters!"), Proposal::proponent_length));
		}
		$proposal->add_support(false, $proponent);
		notice(_("Your application to become proponent has been submitted to the current proponents to confirm your request."));
		redirect();
		break;
	case "confirm_proponent":
		Login::access_action("member");
		action_required_parameters('member');
		if (!$proposal->allowed_edit_proponent()) {
			warning(_("You can not confirm proponents anymore once voting preparation has started or the proposal has been closed!"));
			redirect();
		}
		if (!$proposal->is_proponent(Login::$member)) {
			warning(_("Your are not a proponent of this proposal."));
			redirect();
		}
		$member = new Member($_POST['member']);
		if (!$member->id) {
			warning("The member does not exist.");
			redirect();
		}
		if (!$proposal->is_proponent($member, false)) {
			warning(_("The to be confirmed member is not applying to become proponent of this proposal."));
			redirect();
		}
		$proposal->confirm_proponent($member);
		redirect();
		break;
	case "confirm_remove_proponent":
		Login::access_action("member");
		if (!$proposal->allowed_edit_proponent()) {
			warning(_("You can not remove yourself from the proponents list once voting preparation has started or the proposal has been closed!"));
			redirect();
		}
		$proposal->remove_proponent(Login::$member);
		redirect();
		break;

	case "add_support":
		Login::access_action("member");
		if (!$proposal->admission()) {
			warning("Support for this proposal can not be added, because it is not in the admission phase!");
			redirect();
		}
		$proposal->add_support(@$_POST['anonymous']==1);
		redirect();
		break;
	case "revoke_support":
		Login::access_action("member");
		if (!$proposal->admission()) {
			warning("Support for this proposal can not be removed, because it is not in the admission phase!");
			redirect();
		}
		if ($proposal->is_proponent(Login::$member, false)) {
			warning("You can not remove your support while you are proponent!");
			redirect();
		}
		$proposal->revoke_support();
		redirect();
		break;
	case "demand_ballot_voting":
		Login::access_action("member");
		if (!$issue->voting_type_determination()) {
			warning("Demand for ballot voting can not be added, because the proposal is not in admission, admitted or debate phase!");
			redirect();
		}
		$issue->demand_ballot_voting(@$_POST['anonymous']==1);
		redirect();
		break;
	case "revoke_demand_for_ballot_voting":
		Login::access_action("member");
		if (!$issue->voting_type_determination()) {
			warning("Demand for ballot voting can not be removed, because the proposal is not in admission, admitted or debate phase!");
			redirect();
		}
		$issue->revoke_demand_for_ballot_voting();
		redirect();
		break;

	case "select_period":
		Login::access_action("admin");
		action_proposal_select_period();
		break;

	case "admission_decision":
		Login::access_action("admin");
		action_required_parameters("admission_decision");
		$proposal->set_admission_decision(trim($_POST['admission_decision']));
		redirect();
		break;

	case "add_argument":
		Login::access_action("member");
		action_required_parameters("title", "content", "parent");
		if (!$proposal->allowed_add_arguments()) {
			warning(_("Adding or rating arguments is allowed in this phase."));
			redirect();
		}
		$argument = new Argument;
		if ($_POST['parent']=="pro" or $_POST['parent']=="contra") {
			$argument->parent = 0;
			$argument->side = $_POST['parent'];
		} else {
			$parent = new Argument($_POST['parent']);
			if (!$parent->id) {
				warning("Parent argument does not exist.");
				redirect();
			}
			$argument->parent = $parent->id;
			$argument->side = $parent->side;
		}
		$argument->proposal = $proposal->id;
		$argument->member = Login::$member->id;

		$argument->title = trim($_POST['title']);
		if (!$argument->title) {
			warning("The title of the argument must be not empty.");
			break;
		}
		if (mb_strlen($argument->title) > Argument::title_length) {
			$argument->title = limitstr($argument->title, Argument::title_length);
			warning(sprintf(_("The title has been truncated to the maximum allowed length of %d characters!"), Argument::title_length));
		}

		$argument->content = trim($_POST['content']);
		if (!$argument->content) {
			warning("The content of the argument must be not empty.");
			break;
		}
		if (mb_strlen($argument->content) > Argument::content_length) {
			$argument->content = limitstr($argument->content, Argument::content_length);
			warning(sprintf(_("The content has been truncated to the maximum allowed length of %d characters!"), Argument::content_length));
		}

		$argument->create();
		redirect(URI::same()."#argument".$argument->id);
		break;

	case "update_argument":
		Login::access_action("member");
		action_required_parameters("title", "content", "id");
		$argument = new Argument($_POST['id']);
		if (!$argument->id) {
			warning("This argument does not exist.");
			redirect();
		}
		if ($argument->member!=Login::$member->id) {
			warning("You are not the author of the argument.");
			redirect();
		}
		if (strtotime($argument->created) < $edit_limit) {
			warning("This argument may not be updated any longer.");
			redirect();
		}
		$argument->title = trim($_POST['title']);
		if (!$argument->title) {
			warning("The title of the argument must be not empty.");
			break;
		}
		$argument->content = trim($_POST['content']);
		if (!$argument->content) {
			warning("The content of the argument must be not empty.");
			break;
		}
		$argument->update(array("title", "content"), "updated=now()");
		redirect(URI::same()."#argument".$argument->id);
		break;

	case "remove_argument":
	case "restore_argument":
		Login::access_action("admin");
		action_required_parameters("id");
		$argument = new Argument($_POST['id']);
		if (!$argument->id) {
			warning("This argument does not exist.");
			redirect();
		}
		$argument->removed = ($action=="remove_argument");
		$argument->update(array("removed"));
		redirect(URI::same()."#argument".$argument->id);
		break;

	case "rating_plus":
	case "rating_minus":
		Login::access_action("member");
		action_required_parameters("argument");
		if (!$proposal->allowed_add_arguments()) {
			warning(_("Adding or rating arguments is allowed in this phase."));
			redirect();
		}
		$argument = new Argument($_POST['argument']);
		if (!$argument->id) {
			warning("This argument does not exist.");
			redirect();
		}
		if ($argument->member==Login::$member->id) {
			warning("Rating your own arguments is not allowed.");
			redirect();
		}
		if ($argument->removed) {
			warning("The argument has been removed.");
			redirect();
		}
		$argument->set_rating($action=="rating_plus");
		redirect(URI::same()."#argument".$argument->id);
		break;

	case "rating_reset":
		Login::access_action("member");
		action_required_parameters("argument");
		if (!$proposal->allowed_add_arguments()) {
			warning(_("Adding or rating arguments is allowed in this phase."));
			redirect();
		}
		$argument = new Argument($_POST['argument']);
		if (!$argument->id) {
			warning("This argument does not exist.");
			redirect();
		}
		if ($argument->removed) {
			warning("The argument has been removed.");
			redirect();
		}
		$argument->delete_rating();
		redirect(URI::same()."#argument".$argument->id);
		break;

	default:
		warning(_("Unknown action"));
		redirect();
	}
}


list($supporters, $proponents, $is_supporter, $is_proponent) = $proposal->supporters();

if (isset($_GET['draft'])) {
	$draft = new Draft($_GET['draft']);
	if (!$is_proponent) {
		error("You are not a proponent of this proposal!");
	}
	if ($draft->proposal != $proposal->id) {
		error("The requested draft does not exist!");
	}
	html_head(sprintf(_("Proposal %d, draft from %s"), $proposal->id, datetimeformat($draft->created)));
	$content_obj = $draft;
} else {
	html_head(_("Proposal")." ".$proposal->id);
	$content_obj = $proposal;
}


if (isset($_GET['remove_proponent']) and $proposal->is_proponent(Login::$member, false)) {
?>
<div class="messages">
<?
	if (!$proposal->allowed_edit_proponent()) {
		warning(_("You can not remove yourself from the proponents list once voting preparation has started or the proposal has been closed!"));
	} else {
		form(URI::same(), 'class="notice"');
?>
&#10148; <?=_("Do you really want to remove yourself from the proponents of this proposal?")?>
<input type="hidden" name="action" value="confirm_remove_proponent">
<input type="submit" value="<?=_("Yes")?>">
<a href="<?=URI::same()?>"><?=_("No")?></a>
</form>
<?
	}
?>
</div>
<div class="clearfix"></div>
<?
}


?>

<div class="proposal_info">
<? display_proposal_info($proposal, $issue, $proponents, $is_proponent); ?>
</div>

<div class="proposal_content">
<?
if ($proposal->state=="draft" and $is_proponent) {
?>
<div class="add"><a href="proposal_edit.php?id=<?=$proposal->id?>" class="icontextlink"><img src="img/edit.png" width="16" height="16" alt="<?=_("edit")?>"><?=_("Edit proposal")?></a></div>
<?
}
?>
<h2><?=_("Title")?></h2>
<p class="proposal proposal_title"><?=h($content_obj->title)?></p>
<h2><?=_("Content")?></h2>
<p class="proposal"><?=content2html($content_obj->content)?></p>
<h2><?=_("Reason")?></h2>
<p class="proposal"><?=content2html($content_obj->reason)?></p>
</div>

<div class="clearfix"></div>

<?
if ($proposal->state != "draft" and !isset($_GET['draft'])) {
?>
<div>
	<div class="arguments_side arguments_pro">
<?
	if (Login::$member and @$_GET['argument_parent']!="pro" and $proposal->allowed_add_arguments()) {
?>
		<div class="add"><a href="<?=URI::append(array('argument_parent'=>"pro"))?>#form" class="icontextlink"><img src="img/plus.png" width="16" height="16" alt="<?=_("plus")?>"><?=_("Add new pro argument")?></a></div>
<?
	}
?>
		<h2><?=_("Pro")?></h2>
		<? display_arguments("pro", "pro", 0); ?>
	</div>
	<div class="arguments_side arguments_contra">
<?
	if (Login::$member and @$_GET['argument_parent']!="contra" and $proposal->allowed_add_arguments()) {
?>
		<div class="add"><a href="<?=URI::append(array('argument_parent'=>"contra"))?>#form" class="icontextlink"><img src="img/plus.png" width="16" height="16" alt="<?=_("plus")?>"><?=_("Add new contra argument")?></a></div>
<?
	}
?>
		<h2><?=_("Contra")?></h2>
		<? display_arguments("contra", "contra", 0); ?>
	</div>
	<div class="clearfix"></div>
</div>

<?
	display_quorum($proposal, $issue, $supporters, $is_supporter);
}

list($proposals, $submitted) = $issue->proposals_list();
if ($submitted) {
	display_ballot_voting_quorum($issue, $submitted);
}
?>

<div class="issue">
<?
if (Login::$member and $issue->allowed_add_alternative_proposal()) {
?>
<div class="add"><a href="proposal_edit.php?issue=<?=$proposal->issue?>" class="icontextlink"><img src="img/plus.png" width="16" height="16" alt="<?=_("plus")?>"><?=_("Add alternative proposal")?></a></div>
<?
}
?>
<h2><?=_("This and alternative proposals")?></h2>
<table class="proposals">
<?
if (Login::$member) $issue->read_ballot_voting_demanded_by_member();
$show_results = in_array($issue->state, array('finished', 'cleared', 'cancelled'));
Issue::display_proposals_th($show_results);
$issue->display_proposals($proposals, $submitted, count($proposals), $show_results, $proposal->id);
?>
</table>
</div>

<?

html_foot();


/**
 *
 * @param object  $proposal
 * @param object  $issue
 * @param array   $proponents
 * @param boolean $is_proponent
 */
function display_proposal_info(Proposal $proposal, Issue $issue, array $proponents, $is_proponent) {
?>
<h2><?=_("Area")?></h2>
<p class="proposal"><?=h($issue->area()->name)?></p>
<?

	$is_any_proponent = false;
	if (Login::$member) {
		foreach ( $proponents as $proponent ) {
			if ($proponent->id==Login::$member->id) {
				$is_any_proponent = true;
				break;
			}
		}
		$allowed_edit_proponent = $proposal->allowed_edit_proponent();
		if ($allowed_edit_proponent and !$is_any_proponent) {
?>
<div class="add"><a href="<?=URI::append(array('become_proponent'=>1))?>" class="icontextlink"><img src="img/plus.png" width="16" height="16" alt="<?=_("plus")?>"><?=_("become proponent")?></a></div>
<?
		}
	}
?>
<h2><?=_("Proponents")?></h2>
<ul>
<?
	$confirmed_proponents = 0;
	foreach ( $proponents as $proponent ) {
		if ($proponent->proponent_confirmed) $confirmed_proponents++;
		// show unconfirmed proponents only to confirmed proponents and himself
		if (!$is_proponent and !$proponent->proponent_confirmed and (!Login::$member or $proponent->id!=Login::$member->id)) continue;
?>
	<li><?
		if (Login::$member and $proponent->id==Login::$member->id and $allowed_edit_proponent) {
			if (isset($_GET['edit_proponent'])) {
				form(URI::same());
?>
<input type="text" name="proponent" value="<?=h($proponent->proponent_name)?>" maxlength="<?=Proposal::proponent_length?>"><br>
<input type="hidden" name="action" value="apply_proponent">
<input type="submit" value="<?=_("apply changes")?>">
</form>
<?
			} else {
				if ($proponent->proponent_confirmed) {
					echo content2html($proponent->proponent_name);
				} else {
?>
<span class="unconfirmed"><?=content2html($proponent->proponent_name)?></span>
(<?=$proponent->username()?>)
<?
				}
				?> <a href="<?=URI::append(array('edit_proponent'=>1))?>" class="iconlink"><img src="img/edit.png" width="16" height="16" alt="<?=_("edit")?>" title="<?=_("edit your proponent name and contact details")?>"></a><a href="<?=URI::append(array('remove_proponent'=>1))?>" class="iconlink"><img src="img/delete.png" width="21" height="16" alt="<?=_("delete")?>" title="<?=_("remove yourself from the list of proponents")?>"></a><?
			}
		} elseif ($proponent->proponent_confirmed) {
			echo content2html($proponent->proponent_name);
		} elseif ($is_proponent and $allowed_edit_proponent) {
			form(URI::same());
?>
<span class="unconfirmed"><?=content2html($proponent->proponent_name)?></span>
(<?=$proponent->username()?>)
<input type="hidden" name="member" value="<?=$proponent->id?>">
<input type="hidden" name="action" value="confirm_proponent">
<input type="submit" value="<?=_("confirm")?>">
</form>
<?
		} else {
			?><span class="unconfirmed"><?=content2html($proponent->proponent_name)?></span><?
		}
		?></li>
<?
	}
	if (Login::$member and $allowed_edit_proponent and isset($_GET['become_proponent']) and !$is_any_proponent) {
?>
	<li><?
		form(URI::same());
?>
<input type="text" name="proponent" value="<?=h(Login::$member->username())?>" maxlength="<?=Proposal::proponent_length?>"><br>
<div class="explain"><?=_("Enter your name and contact details as you would like to see them in the proposal. To prevent fraud, your user name will also be shown to the other proponents:")?> <?=h(Login::$member->username())?></div>
<input type="hidden" name="action" value="become_proponent">
<input type="submit" value="<?=_("apply to become proponent")?>">
</form>
	</li>
<?
	}
?>
</ul>
<?

	// show drafts only to the proponents
	if (!$is_proponent) return;

?>
<h2><?=_("Drafts")?></h2>
<?
	if ($proposal->state=="draft" or !empty($_GET['show_drafts'])) {
?>
<table>
<?
		$sql = "SELECT * FROM drafts WHERE proposal=".intval($proposal->id)." ORDER BY created DESC";
		$result = DB::query($sql);
		$i = DB::num_rows($result);
		while ( $draft = DB::fetch_object($result, "Draft") ) {
			$author = new Member($draft->author);
?>
<tr class="<?=stripes()?>">
	<td class="right"><?=$i?></td>
	<td><a href="<?=URI::append(array('draft'=>$draft->id))?>"><?=datetimeformat($draft->created)?></a></td>
	<td><?=$author->username()?></td>
</tr>
<?
			$i--;
		}
?>
</table>
<?
	} else {
?>
<a href="<?=URI::append(array('show_drafts'=>1))?>"><?=_("Drafts")?></a>
<?
	}

?>
<h2><?=_("Actions")?></h2>
<?
	if ($proposal->state=="draft" and $confirmed_proponents >= Proposal::proponents_required_submission) {
		form(URI::same());
?>
<input type="hidden" name="action" value="submit_proposal">
<input type="submit" value="<?=_("submit proposal")?>">
</form>
<?
	}
	if ($issue->state=="admission" or $issue->state=="debate") {
		form(URI::same());
?>
<input type="hidden" name="action" value="revoke_proposal">
<input type="submit" value="<?=_("revoke proposal")?>">
</form>
<?
	}

}


/**
 * list the sub-arguments for one parent-argument
 *
 * @param string  $side   "pro" or "contra"
 * @param mixed   $parent ID of parent argument or "pro" or "contra"
 * @param integer $level
 */
function display_arguments($side, $parent, $level) {
	global $proposal, $edit_limit;

	$sql = "SELECT arguments.*, (arguments.plus - arguments.minus) AS rating";
	if (Login::$member) {
		$sql .= ", ratings.positive
			FROM arguments
			LEFT JOIN ratings ON ratings.argument = arguments.id AND ratings.member = ".intval(Login::$member->id);
	} else {
		$sql .= "
			FROM arguments";
	}
	// intval($parent) gives parent=0 for "pro" and "contra"
	$sql .= "	WHERE proposal=".intval($proposal->id)."
			AND side=".DB::esc($side)."
			AND parent=".intval($parent)."
		ORDER BY removed, rating DESC, arguments.created";
{'fraction_non_alphanumeric': 0.20569341226854768, 'fraction_numerical': 0.003577276735105177, 'mean_word_length': 5.734984730234136, 'pattern_counts': {'":': 38, '<': 487, '<?xml version=': 0, '>': 785, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5779034', 'n_tokens_mistral': 13821, 'n_tokens_neox': 13070, 'n_words': 2820}