This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "FusionForge".
The branch, master has been updated
via 5263b7f63318692cfcb4478fbf4dbce71e99a792 (commit)
from c51a3c8f7238b2ebecc8db15cd05422a84712289 (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
- Log -----------------------------------------------------------------
https://scm.fusionforge.org/anonscm/gitweb/?p=fusionforge/fusionforge.git;a=commitdiff;h=5263b7f63318692cfcb4478fbf4dbce71e99a792
commit 5263b7f63318692cfcb4478fbf4dbce71e99a792
Author: Franck Villaume <[email protected]>
Date: Sun Aug 18 20:20:22 2019 +0200
Initial commit for feature request: vote for project [#902]
diff --git a/src/common/include/Group.class.php
b/src/common/include/Group.class.php
index 0ca2f42..747b372 100644
--- a/src/common/include/Group.class.php
+++ b/src/common/include/Group.class.php
@@ -252,6 +252,18 @@ class Group extends FFError {
var $membersArr;
/**
+ * cached return value of getVotes
+ * @var int|bool $votes
+ */
+ var $votes = false;
+
+ /**
+ * cached return value of getVoters
+ * @var int|bool $voters
+ */
+ var $voters = false;
+
+ /**
* Group - Group object constructor - use group_get_object() to
instantiate.
*
* @param int|bool $id Required - Id of the group you
want to instantiate.
@@ -3205,6 +3217,126 @@ class Group extends FFError {
$lm = new WidgetLayoutManager();
return $lm->getLayout($this->getID(),
WidgetLayoutManager::OWNER_TYPE_GROUP);
}
+
+ /**
+ * castVote - Vote on this tracker item or retract the vote
+ * @param bool $value true to cast, false to retract
+ * @return bool success (false sets error message)
+ */
+ function castVote($value = true) {
+ if (!($uid = user_getid()) || $uid == 100) {
+ $this->setMissingParamsError(_('User ID not passed'));
+ return false;
+ }
+ if (!$this->canVote()) {
+ $this->setPermissionDeniedError();
+ return false;
+ }
+ $has_vote = $this->hasVote($uid);
+ if ($has_vote == $value) {
+ /* nothing changed */
+ return true;
+ }
+ if ($value) {
+ $res = db_query_params('INSERT INTO group_votes
(group_id, user_id) VALUES ($1, $2)',
+ array($this->getID(), $uid));
+ } else {
+ $res = db_query_params('DELETE FROM group_votes WHERE
group_id = $1 AND user_id = $2',
+ array($this->getID(), $uid));
+ }
+ if (!$res) {
+ $this->setError(db_error());
+ return false;
+ }
+ return true;
+ }
+
+ /**
+ * hasVote - Check if a user has voted on this group item
+ *
+ * @param int|bool $uid user ID (default: current user)
+ * @return bool true if a vote exists
+ */
+ function hasVote($uid = false) {
+ if (!$uid) {
+ $uid = user_getid();
+ }
+ if (!$uid || $uid == 100) {
+ return false;
+ }
+ $res = db_query_params('SELECT * FROM group_votes WHERE
group_id = $1 AND user_id = $2',
+ array($this->getID(), $uid));
+ return (db_numrows($res) == 1);
+ }
+
+ /**
+ * getVotes - get number of valid cast and potential votes
+ *
+ * @return array|bool (votes, voters, percent)
+ */
+ function getVotes() {
+ if ($this->votes !== false) {
+ return $this->votes;
+ }
+
+ $voters = $this->getVoters();
+ unset($voters[0]); /* just in case */
+ unset($voters[100]); /* need users */
+ if (($numvoters = count($voters)) < 1) {
+ $this->votes = array(0, 0, 0);
+ return $this->votes;
+ }
+
+ $res = db_query_params('SELECT COUNT(*) AS count FROM
group_votes WHERE group_id = $1 AND user_id = ANY($2)',
+ array($this->getID(),
db_int_array_to_any_clause($voters)));
+ $db_count = db_fetch_array($res);
+ $numvotes = $db_count['count'];
+
+ /* check for invalid values */
+ if ($numvotes < 0 || $numvoters < $numvotes) {
+ $this->votes = array(-1, -1, 0);
+ } else {
+ $this->votes = array($numvotes, $numvoters,
+ (int)($numvotes * 100 / $numvoters + 0.5));
+ }
+ return $this->votes;
+ }
+
+ /**
+ * canVote - check whether the current user can vote on
+ * items in this tracker
+ *
+ * @return bool true if they can
+ */
+ function canVote() {
+ if (in_array(user_getid(), $this->getVoters())) {
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * getVoters - get IDs of users that may vote on
+ * items in this tracker
+ *
+ * @return array list of user IDs
+ */
+ function getVoters() {
+ if ($this->voters !== false) {
+ return $this->voters;
+ }
+
+ $this->voters = array();
+ if (($engine = RBACEngine::getInstance())
+ && ($voters =
$engine->getUsersByAllowedAction('project_read', $this->getID()))
+ && (count($voters) > 0)) {
+ foreach ($voters as $voter) {
+ $voter_id = $voter->getID();
+ $this->voters[$voter_id] = $voter_id;
+ }
+ }
+ return $this->voters;
+ }
}
/**
diff --git a/src/common/project/actions/pointer_down.php
b/src/common/project/actions/pointer_down.php
new file mode 100644
index 0000000..06237bb
--- /dev/null
+++ b/src/common/project/actions/pointer_down.php
@@ -0,0 +1,33 @@
+<?php
+/**
+ * Project delete vote action
+ *
+ * Copyright 2019, Franck Villaume - TrivialDev
+ * http://fusionforge.org/
+ *
+ * This file is part of FusionForge. FusionForge is free software;
+ * you can redistribute it and/or modify it under the terms of the
+ * GNU General Public License as published by the Free Software
+ * Foundation; either version 2 of the Licence, or (at your option)
+ * any later version.
+ *
+ * FusionForge is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with FusionForge; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+global $group_id;
+global $g;
+
+session_require_perm('project_read', $group_id);
+
+if ($g->castVote(false)) {
+ $feedback = _('Retracted Vote successfully');
+} else {
+ $error_msg = $g->getErrorMessage();
+}
diff --git a/src/common/project/actions/pointer_up.php
b/src/common/project/actions/pointer_up.php
new file mode 100644
index 0000000..3ce022b
--- /dev/null
+++ b/src/common/project/actions/pointer_up.php
@@ -0,0 +1,33 @@
+<?php
+/**
+ * Project add vote action
+ *
+ * Copyright 2019, Franck Villaume - TrivialDev
+ * http://fusionforge.org/
+ *
+ * This file is part of FusionForge. FusionForge is free software;
+ * you can redistribute it and/or modify it under the terms of the
+ * GNU General Public License as published by the Free Software
+ * Foundation; either version 2 of the Licence, or (at your option)
+ * any later version.
+ *
+ * FusionForge is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with FusionForge; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+global $group_id;
+global $g;
+
+session_require_perm('project_read', $group_id);
+
+if ($g->castVote()) {
+ $feedback = _('Cast Vote successfully');
+} else {
+ $error_msg = $g->getErrorMessage();
+}
diff --git a/src/common/widget/Widget_ProjectInfo.class.php
b/src/common/widget/Widget_ProjectInfo.class.php
index 11fdae4..d128bbf 100644
--- a/src/common/widget/Widget_ProjectInfo.class.php
+++ b/src/common/widget/Widget_ProjectInfo.class.php
@@ -118,6 +118,23 @@ class Widget_ProjectInfo extends Widget {
}
}
+ $votes = $project->getVotes();
+ if ($votes[1]) {
+ $result .= html_e('br');
+ $content = html_e('span', array('id' => 'group-votes'),
html_e('strong', array(), _('Votes') . _(': ')).sprintf('%1$d/%2$d (%3$d%%)',
$votes[0], $votes[1], $votes[2]));
+ if ($project->canVote()) {
+ if ($project->hasVote()) {
+ $key = 'pointer_down';
+ $txt = _('Retract Vote');
+ } else {
+ $key = 'pointer_up';
+ $txt = _('Cast Vote');
+ }
+ $content .=
util_make_link('/project/?group_id='.$group_id.'&action='.$key,
html_image('ic/'.$key.'.png', 16, 16), array('id' => 'group-vote', 'alt' =>
$txt));
+ }
+ $result .= $content;
+ }
+
$hook_params = array();
$hook_params['group_id'] = $group_id;
plugin_hook("project_after_description",$hook_params);
diff --git a/src/db/20190511-votes-for-project-and-diary-and-frs-release.sql
b/src/db/20190511-votes-for-project-and-diary-and-frs-release.sql
new file mode 100644
index 0000000..40e8a7e
--- /dev/null
+++ b/src/db/20190511-votes-for-project-and-diary-and-frs-release.sql
@@ -0,0 +1,38 @@
+-- Add a table to count diary votes.
+
+CREATE TABLE diarynotes_votes (
+ diary_id integer NOT NULL,
+ user_id integer NOT NULL,
+ CONSTRAINT diarynotes_votes_fk_did
+ FOREIGN KEY (diary_id) REFERENCES user_diary (id) ON DELETE
CASCADE,
+ CONSTRAINT diarynotes_votes_fk_uid
+ FOREIGN KEY (user_id) REFERENCES users (user_id),
+ CONSTRAINT diarynotes_votes_pk
+ PRIMARY KEY (diary_id, user_id)
+);
+
+-- Add a table to count project votes.
+
+CREATE TABLE groups_votes (
+ group_id integer NOT NULL,
+ user_id integer NOT NULL,
+ CONSTRAINT groups_votes_fk_gid
+ FOREIGN KEY (group_id) REFERENCES groups (group_id) ON DELETE
CASCADE,
+ CONSTRAINT groups_votes_fk_uid
+ FOREIGN KEY (user_id) REFERENCES users (user_id),
+ CONSTRAINT groups_votes_pk
+ PRIMARY KEY (group_id, user_id)
+);
+
+-- Add a table to count frs release votes.
+
+CREATE TABLE frsrelease_votes (
+ release_id integer NOT NULL,
+ user_id integer NOT NULL,
+ CONSTRAINT frsrelease_votes_fk_fid
+ FOREIGN KEY (release_id) REFERENCES frs_release (release_id) ON
DELETE CASCADE,
+ CONSTRAINT frsrelease_votes_fk_uid
+ FOREIGN KEY (user_id) REFERENCES users (user_id),
+ CONSTRAINT frsrelease_votes_pk
+ PRIMARY KEY (release_id, user_id)
+);
-----------------------------------------------------------------------
Summary of changes:
src/common/include/Group.class.php | 132 +++++++++++++++++++++
.../actions/pointer_down.php} | 19 +--
.../archive.php => project/actions/pointer_up.php} | 21 ++--
src/common/widget/Widget_ProjectInfo.class.php | 17 +++
...votes-for-project-and-diary-and-frs-release.sql | 38 ++++++
5 files changed, 210 insertions(+), 17 deletions(-)
copy src/common/{diary/views/archive.php => project/actions/pointer_down.php}
(73%)
copy src/common/{diary/views/archive.php => project/actions/pointer_up.php}
(73%)
create mode 100644
src/db/20190511-votes-for-project-and-diary-and-frs-release.sql
hooks/post-receive
--
FusionForge
_______________________________________________
Fusionforge-commits mailing list
[email protected]
http://lists.fusionforge.org/cgi-bin/mailman/listinfo/fusionforge-commits