/** * update member's ngroups * * @param array $ngroups array of integers */ public function update_ngroups(array $ngroups) { DB::transaction_start(); $sql = "SELECT ngroup FROM member_ngroup WHERE member=".intval($this->id); $existing_ngroups = DB::fetchfieldarray($sql); $insert_ngroups = array_diff($ngroups, $existing_ngroups); if ($insert_ngroups) { $sql_groups = array(); foreach ($insert_ngroups as $insert_ngroup) { $sql_groups[] = "(".intval($this->id).", ".intval($insert_ngroup).")"; } DB::query("INSERT INTO member_ngroup (member, ngroup) VALUES ".join(", ", $sql_groups)); } $delete_ngroups = array_diff($existing_ngroups, $ngroups); if ($delete_ngroups) { $sql = "DELETE FROM member_ngroup WHERE member=".intval($this->id)." AND ngroup IN (".join(", ", array_map("intval", $delete_ngroups)).")"; DB::query($sql); } DB::transaction_commit(); }
/** * upload voter lists for postal voting and for each ballot * * @param Period $period * @param boolean $include_ballot_voters (optional) * @return boolean */ function upload_voters($period, $include_ballot_voters=false) { $data = array(); // postal voters $sql = "SELECT invite FROM member JOIN offlinevoter ON offlinevoter.member = member.id AND offlinevoter.ballot IS NULL AND offlinevoter.period = ".intval($period->id); $data[0] = array( 'name' => "postal voting", 'voters' => DB::fetchfieldarray($sql) ); // ballot voters if ($include_ballot_voters) { $sql_ballot = "SELECT * FROM ballot WHERE period=".intval($period->id)." AND approved=TRUE"; $result_ballot = DB::query($sql_ballot); while ( $ballot = DB::fetch_object($result_ballot, "Ballot") ) { $sql = "SELECT invite FROM member JOIN offlinevoter ON offlinevoter.member = member.id AND offlinevoter.ballot = ".intval($ballot->id); $data[$ballot->id] = array( 'name' => $ballot->name, 'ngroup' => $ballot->ngroup()->name, 'opening' => timeformat($ballot->opening), 'closing' => BALLOT_CLOSE_TIME, 'agents' => $ballot->agents, 'voters' => DB::fetchfieldarray($sql) ); } } // TODO: For now we don't use the data. }
/** * get mail addresses of the recipients * * @param array $members array of member IDs * @param array $exclude array of member IDs to send no mail * @return array */ private function recipients(array $members, array $exclude) { $sql = "SELECT DISTINCT mail FROM member"; $or = array(); // specified members if ( $members ) { $or[] = "member.id IN (".join(",", $members).")"; } // from notification settings if ( isset(self::$default_settings['all'][$this->type]) ) { // check if type exists $sql .= " LEFT JOIN notify ON notify.member = member.id LEFT JOIN member_ngroup ON member_ngroup.member = member.id LEFT JOIN participant ON participant.member = member.id LEFT JOIN supporter ON supporter.member = member.id"; // members who saved their notification settings $where_notify = " notify.".$this->type."=TRUE AND ( notify.interest='all'"; // members with default notification settings $where_default = " notify.member IS NULL"; if ( !self::$default_settings['all'][$this->type] ) { $where_default .= " AND ( FALSE"; } if ($this->period) { $where_notify .= " OR (notify.interest='ngroups' AND member_ngroup.ngroup=".intval($this->period->ngroup).")"; if ( !self::$default_settings['all'][$this->type] and self::$default_settings['ngroups'][$this->type] ) { $where_default .= " OR member_ngroup.ngroup=".intval($this->period->ngroup); } } $areas = array(); $proposals = array(); if ($this->issues) { foreach ($this->issues as $issue) { /** @var $issue Issue */ $areas[] = $issue->area; foreach ($issue->proposals() as $proposal) { $proposals[] = $proposal->id; } } } elseif ($this->issue) { $areas[] = $this->issue->area; foreach ($this->issue->proposals() as $proposal) { $proposals[] = $proposal->id; } } elseif ($this->proposal) { $areas[] = $this->proposal->issue()->area; $proposals[] = $this->proposal->id; } if ($areas) { $areas = join(",", array_unique($areas)); $where_notify .= " OR (notify.interest='participant' AND participant.area IN (".$areas."))"; if ( !self::$default_settings['all'][$this->type] and self::$default_settings['participant'][$this->type] ) { $where_default .= " OR participant.area IN (".$areas.")"; } } if ($proposals) { $proposals = join(",", $proposals); $where_notify .= " OR (notify.interest='supporter' AND supporter.proposal IN (".$proposals.")) OR (notify.interest='proponent' AND supporter.proposal IN (".$proposals.") AND supporter.proponent_confirmed=TRUE)"; if ( !self::$default_settings['all'][$this->type] ) { if ( self::$default_settings['supporter'][$this->type] ) { $where_default .= " OR supporter.proposal IN (".$proposals.")"; } if ( self::$default_settings['proponent'][$this->type] ) { $where_default .= " OR (supporter.proposal IN (".$proposals.") AND supporter.proponent_confirmed=TRUE)"; } } } $where_notify .= " )"; $where_default .= " )"; $or[] = "(".$where_notify." )"; $or[] = "(".$where_default." )"; } if (!$or) return array(); $sql .= " WHERE member.mail IS NOT NULL AND ( ".join(" OR ", $or)." )"; // don't notify a member about his own actions if (Login::$member) $exclude[] = intval(Login::$member->id); if ($exclude) { $sql .= " AND member.id NOT IN (".join(", ", $exclude).")"; } return DB::fetchfieldarray($sql); }
/** * move the proposal to a different issue * * @param integer $new_issue_id */ public function move_to_issue($new_issue_id) { DB::transaction_start(); $this->read(); if ( !$this->allowed_move_to_issue() ) { DB::transaction_rollback(); warning(_("Moving this proposal is not allowed anymore.")); redirect(); }; $options = $this->options_move_to_issue(); if (!isset($options[$new_issue_id])) { DB::transaction_rollback(); warning(_("The selected option is not available.")); redirect(); } $old_issue = $this->issue(); if ($new_issue_id) { $new_issue = new Issue($new_issue_id); if (!$new_issue->id) { DB::transaction_rollback(); warning(_("The issue does not exist.")); redirect(); } } else { // create a new empty issue $new_issue = new Issue; $new_issue->area = $old_issue->area; $new_issue->period = $old_issue->period; $new_issue->state = $old_issue->state; // If the old issue reached offline voting, the new issue gets offline voting unseen the number of offline voting demanders. $new_issue->votingmode_reached = $old_issue->votingmode_reached; $new_issue->debate_started = $old_issue->debate_started; $new_issue->create(); } $this->issue = $new_issue->id; if ( ! $this->update(['issue']) ) { DB::transaction_rollback(); return; } DB::transaction_commit(); // cancel empty issue if ( ! $old_issue->proposals() ) $old_issue->cancel(); // send notification $notification = new Notification("proposal_moved"); $notification->issue_old = $old_issue; $notification->issue = $new_issue; $notification->proposal = $this; // votingmode voters of both issues $sql = "SELECT DISTINCT member FROM votingmode_token WHERE issue=".intval($old_issue->id)." OR issue=".intval($new_issue->id); $recipients = DB::fetchfieldarray($sql); // supporters and proponents of the proposal $sql = "SELECT DISTINCT member FROM supporter WHERE proposal=".intval($this->id); $recipients = array_unique(array_merge($recipients, DB::fetchfieldarray($sql))); $notification->send($recipients); }
/** * change manual order * * needs a database column: * `manualorder` smallint(6) NOT NULL DEFAULT '0' * column description: * array("manualorder", _("Order"), "", "manualorder", false) * * @param string $action * @param integer $id ID of the record to be moved * @param string $where (optional) WHERE part of the SQL statement * @param string $colname (optional) name of the database column to use */ protected function action_manualorder($action, $id, $where="", $colname="manualorder") { // renumber records $sql = "SELECT ".$this->dbtable.".id FROM ".$this->dbtable." ".$where." ORDER BY ".$this->dbtable.".".DB::ident($colname); $renumids = DB::fetchfieldarray($sql); $aktindex = array_search($id, $renumids); switch ($action) { case "movefirst": $renumids[$aktindex] = ""; // delete occurrence of the current ID array_unshift($renumids, $id); // set the current ID to the beginning of the array break; case "movelast": $renumids[$aktindex] = ""; // delete occurrence of the current ID $renumids[] = $id; // set the current ID to the end of the array break; case "moveup": case "movedown": if ($action=="moveup") $swapindex = $aktindex - 1; else $swapindex = $aktindex + 1; // If the order was changed in between, it could be that there is no record, which could be exchanged with the current one. if (!isset($renumids[$swapindex])) return; $aktvalue = $id; $swapvalue = $renumids[$swapindex]; $renumids[$swapindex] = $aktvalue; $renumids[$aktindex] = $swapvalue; break; default: return; } $i = -32760; foreach ( $renumids as $renumid ) { if ($renumid) { DB::query("UPDATE ".$this->dbtable." SET ".$colname."=".$i." WHERE id=".$renumid); ++$i; } } }