/** * options for drop down menu * * Here we use all ngroups, not only the active ones. * * @param integer $parent * @return array */ public static function options($parent) { $options = array(); $sql = "SELECT ngroup.*, member FROM ngroup LEFT JOIN member_ngroup ON member_ngroup.ngroup = ngroup.id AND member_ngroup.member = ".intval(Login::$member->id)." ORDER BY name"; $result = DB::query($sql); $ngroups = array(); while ( $ngroup = DB::fetch_object($result, "Ngroup") ) $ngroups[] = $ngroup; $ngroups = Ngroup::parent_sort($ngroups, $parent); // own ngroups foreach ($ngroups as $ngroup) { if (!$ngroup->member) continue; $options[$ngroup->id] = $ngroup->name." ∆"; } // other ngroups foreach ($ngroups as $ngroup) { if ($ngroup->member) continue; $options[$ngroup->id] = $ngroup->name; } return $options; }
/** * assign all remaining members to their nearest ballots */ public function assign_members_to_ballots() { // get all approved ballots $sql_ballot = "SELECT * FROM ballot WHERE period=".intval($this->id)." AND approved=TRUE"; $result_ballot = DB::query($sql_ballot); $ballots = array(); while ( $ballot = DB::fetch_object($result_ballot, "Ballot") ) { $ballots[] = $ballot; } // If no ballots were approved at all, ballot voting just can not take place. if (!$ballots) return; // get all ngroups within the ngroup of the period $result = DB::query("SELECT * FROM ngroup"); $ngroups = array(); while ( $ngroup = DB::fetch_object($result, "Ngroup") ) $ngroups[$ngroup->id] = $ngroup; $period_ngroups = Ngroup::parent_sort($ngroups, $ngroups[$this->ngroup]->parent); // get all members, who are in the current period not assigned to a ballot yet $sql = "SELECT member.* FROM member JOIN member_ngroup ON member_ngroup.member = member.id AND member_ngroup.ngroup = ".intval($this->ngroup)." LEFT JOIN offlinevoter ON member.id = offlinevoter.member AND offlinevoter.period = ".intval($this->id)." WHERE offlinevoter.member IS NULL"; $result = DB::query($sql); while ( $member = DB::fetch_object($result, "Member") ) { // get lowest member ngroup (within the ngroup of the period) $lowest_member_ngroup = $member->lowest_ngroup($period_ngroups); if (!$lowest_member_ngroup) { trigger_error("No lowest member ngroup found", E_USER_NOTICE); $best_ballots = $ballots; } else { // rate ballots by distance between member and ballot foreach ( $ballots as $ballot ) { $ballot_ngroup = $period_ngroups[$ballot->ngroup]; $ballot->score = 0; // if no matching is found at all // climb up from the lowest ngroup of the member until the top $reference_member_ngroup = $lowest_member_ngroup; do { if ( self::ngroup_is_equal_or_child($ballot_ngroup, $reference_member_ngroup, $period_ngroups) ) { // Score depends on how far the member has to climb up, but not on how deep the ballot is from there. $ballot->score = $reference_member_ngroup->depth; break; } } while ( $reference_member_ngroup->parent and $reference_member_ngroup = $period_ngroups[$reference_member_ngroup->parent] // step up to parent of member ngroup ); } // pick ballots with highest score $highest_score = 0; $best_ballots = array(); foreach ( $ballots as $ballot ) { if ($ballot->score == $highest_score) { $best_ballots[] = $ballot; } elseif ($ballot->score > $highest_score) { $best_ballots = array($ballot); $highest_score = $ballot->score; } } } // assign member to random of the best ballots /** @noinspection PhpUndefinedMethodInspection */ $best_ballots[rand(0, count($best_ballots)-1)]->assign_member($member); } $this->update_voters_cache(); }