/** * called by cli/cron.php */ function cron() { // If called by a regular cron job it's no problem to skip it sometimes. if (BN=="cron.php") { if (!cron_lock()) return; } else { while (!cron_lock()) { echo "Waiting for lock ...\n"; sleep(5); } } $sql_period = "SELECT *, debate <= now() AS debate_now, preparation <= now() AS preparation_now, voting <= now() AS voting_now, ballot_assignment <= now() AS ballot_assignment_now, ballot_preparation <= now() AS ballot_preparation_now, counting <= now() AS counting_now FROM period"; $result_period = DB::query($sql_period); while ( $period = DB::fetch_object($result_period, "Period") ) { /** @var Period $period */ DB::to_bool($period->debate_now); DB::to_bool($period->preparation_now); DB::to_bool($period->voting_now); DB::to_bool($period->ballot_assignment_now); DB::to_bool($period->ballot_preparation_now); DB::to_bool($period->counting_now); $issues_start_debate = array(); $issues_start_voting = array(); $issues_finished_voting = array(); // ballots switch ($period->state) { // ballot assignment case "ballot_application": if (!$period->ballot_assignment_now) break; $period->assign_members_to_ballots(); $sql_ballot = "SELECT * FROM ballot WHERE period=".intval($period->id); $result_ballot = DB::query($sql_ballot); while ( $ballot = DB::fetch_object($result_ballot, "Ballot") ) { // notification to the ballot agents whether the ballot was approved // TODO: more than one ballot agent $notification = new Notification("ballot_approved"); $notification->period = $period; $notification->ballot = $ballot; $sql = "SELECT member FROM offlinevoter WHERE ballot = ".intval($ballot->id)." AND agent = TRUE"; $recipients = DB::fetchfieldarray($sql); $notification->send($recipients); if (!$ballot->approved) continue; // notification to the members to which ballots they were assigned $notification = new Notification("ballot_assigned"); $notification->period = $period; $notification->ballot = $ballot; $sql = "SELECT member FROM offlinevoter WHERE ballot = ".intval($ballot->id); $recipients = DB::fetchfieldarray($sql); $notification->send($recipients); } $period->state = "ballot_assignment"; $period->update(["state"]); break; // ballot preparation case "ballot_assignment": if (!$period->ballot_preparation_now) break; // final upload of the complete postal and ballot voters if ( upload_voters($period, true) ) { $period->state = "ballot_preparation"; $period->update(["state"]); } // ballot_preparation is the final state. } // proposals and issues $sql_issue = "SELECT * FROM issue WHERE period=".intval($period->id)." AND state NOT IN ('finished', 'cancelled')"; $result_issue = DB::query($sql_issue); while ( $issue = DB::fetch_object($result_issue, "Issue") ) { /** @var Issue $issue */ switch ($issue->state) { // debate case "entry": if (!$period->debate_now) break; $all_proposals_revoked = true; $admitted_proposals = false; $not_admitted_proposals = false; foreach ( $issue->proposals() as $proposal ) { /** @var Proposal $proposal */ if ($proposal->state_cancelled()) continue; //if ( $proposal->check_proponents() ) { $all_proposals_revoked = false; if ($proposal->state=="admitted") $admitted_proposals = true; else $not_admitted_proposals = true; /*} else { // revoke proposals without proponents $proposal->state = "revoked"; $proposal->update(["state"]); }*/ } if ($all_proposals_revoked) { $issue->cancel(); break; } // None of the proposals are admitted yet. if (!$admitted_proposals) break; if ($not_admitted_proposals) { /* split issue $new_issue = new Issue; $new_issue->area = $issue->area; $new_issue->create(); foreach ( $issue->proposals() as $proposal ) { if ($proposal->state_cancelled()) continue; if ($proposal->state=="admitted") continue; $proposal->issue = $new_issue->id; $proposal->update(["issue"]); }*/ // cancel proposals foreach ( $issue->proposals() as $proposal ) { /** @var $proposal Proposal */ if ($proposal->state_cancelled()) continue; if ($proposal->state=="admitted") continue; $proposal->cancel("cancelled_debate"); } } $issue->state = "debate"; $issue->update(["state"], 'debate_started=now()'); $issues_start_debate[] = $issue; break; // preparation case "debate": if (!$period->preparation_now) break; // revoke proposals, which were scheduled for revokation revoke_before_preparation($issue); // don't proceed to preparation if all proposals were cancelled if ($issue->state == "cancelled") break; $issue->state = "preparation"; $issue->update(["state"], 'preparation_started=now()'); break; // voting case "preparation": if (!$period->voting_now) break; // collect issues for online voting start if ( !$issue->votingmode_offline() ) $issues_start_voting[] = $issue; // Issues which reached offline voting, stay in preparation state until an admin enters the voting result. break; // counting case "voting": if (!$period->counting_now) break; $issue->state = "counting"; $issue->update(["state"], 'counting_started=now()'); $issue->counting(); $issue->finish(); $issues_finished_voting[] = $issue; remove_inactive_participants($period->ngroup); break; // "finished" and "cancelled" are the final issue states. } } // debate start notifications if ($issues_start_debate) { $notification = new Notification("debate"); $notification->period = $period; $notification->issues = $issues_start_debate; $notification->send(); } // voting finished notifications if ($issues_finished_voting) { $notification = new Notification("finished"); $notification->period = $period; $notification->issues = $issues_finished_voting; $notification->send(); } // start voting and send individual notifications with tokens if ($issues_start_voting) $period->start_voting($issues_start_voting); } cron_unlock(); }
#!/usr/bin/php <? /** * upload lists of postal voters to the ID server share * * A final list of postal and ballot voters is sent by cron() when entering ballot preparation phase. This script here is an addition for uploading incomplete lists of postal voters earlier and send the letters in multiple batches. If just everything is sent in the end in one batch, it can not be guaranteed that the voters get their mailings in time. When sending in multiple batches, this risk only affects late members. * * to be called by a cron job about once per day * * crontab example: * 48 0 * * * <path>/cli/cron_update_postal_voters.php * * @author Magnus Rosenbaum <*****@*****.**> * @package Basisentscheid */ if ( $dir = dirname($_SERVER['argv'][0]) ) chdir($dir); const DOCROOT = "../"; require "../inc/common_cli.php"; // active between postage set and ballot preparation started $sql_period = "SELECT * FROM period WHERE postage = TRUE AND state != 'ballot_preparation'"; $result_period = DB::query($sql_period); while ( $period = DB::fetch_object($result_period, "Period") ) { /** @var $period Period */ upload_voters($period); }