4 * ContribTrackerPlugin Class
6 * Copyright 2009, Roland Mas
8 * This file is part of FusionForge.
10 * FusionForge is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
15 * FusionForge is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
20 * You should have received a copy of the GNU General Public License along
21 * with this program; if not, write to the Free Software Foundation, Inc.,
22 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
25 class ContribTrackerPlugin extends Plugin {
26 function ContribTrackerPlugin() {
28 $this->name = "contribtracker";
29 $this->text = "Contribution Tracker"; // To show in the tabs, use...
30 $this->_addHook("groupmenu"); // To put into the project tabs
31 $this->_addHook("groupisactivecheckbox"); // The "use ..." checkbox in editgroupinfo
32 $this->_addHook("groupisactivecheckboxpost"); //
33 $this->_addHook("project_admin_plugins"); // to show up in the admin page for group
34 $this->_addHook("project_before_frs"); // project summary page
35 $this->_addHook("site_admin_option_hook"); // to show in the site admin page
38 function CallHook($hookname, &$params) {
39 if ($hookname == "groupmenu") {
40 $group_id=$params['group'];
41 $project = &group_get_object($group_id);
42 if (!$project || !is_object($project)) {
45 if ($project->isError()) {
48 if (!$project->isProject()) {
51 if ( $project->usesPlugin ( $this->name ) ) {
52 $params['TITLES'][] = '<nobr>'._('Contribution tracker').'</nobr>' ;
53 $params['TOOLTIPS'][] = _('Follow the contributions by contributors to this project');
54 $params['DIRS'][]='/plugins/'.$this->name.'/?group_id=' . $group_id ;
55 $params['ADMIN'][]='';
57 (($params['toptab'] == $this->name) ? $params['selected']=(count($params['TITLES'])-1) : '' );
58 } elseif ($hookname == "groupisactivecheckbox") {
59 //Check if the group is active
60 // this code creates the checkbox in the project edit public info page to activate/deactivate the plugin
61 $group_id=$params['group'];
62 $group = &group_get_object($group_id);
65 echo ' <input type="CHECKBOX" name="use_contribtrackerplugin" value="1" ';
66 // CHECKED OR UNCHECKED?
67 if ( $group->usesPlugin ( $this->name ) ) {
74 echo _('Use the Contribution Tracker plugin') ;
78 } elseif ($hookname == "groupisactivecheckboxpost") {
79 // this code actually activates/deactivates the plugin after the form was submitted in the project edit public info page
80 $group_id=$params['group'];
81 $group = &group_get_object($group_id);
82 $use_contribtrackerplugin = getStringFromRequest('use_contribtrackerplugin');
83 if ( $use_contribtrackerplugin == 1 ) {
84 $group->setPluginUse ( $this->name );
86 $group->setPluginUse ( $this->name, false );
88 } elseif ($hookname == "project_admin_plugins") {
89 // this displays the link in the project admin options page to its ContribTracker administration
90 $group_id = $params['group_id'];
91 $group = &group_get_object($group_id);
92 if ( $group->usesPlugin ( $this->name ) ) {
93 echo util_make_link ("/plugins/".$this->name."/project_admin.php?group_id=".$group->getID(),
94 _('Contribution Tracker admin')) ;
99 elseif ($hookname == "project_before_frs") {
100 $group_id = $params['group_id'];
101 $group = &group_get_object ($group_id);
103 if ($group->usesPlugin($this->name)) {
105 echo '<div id="major-contributions">';
106 echo $HTML->boxTop(_('Latest Major Contributions'), 'Latest_Major_Contributions');
109 <table cellspacing="1" cellpadding="5" width="100%" border="0">
111 <th style="text-align:left">'._('Date').'</th>
112 <th style="text-align:left">'._('Contribution').'</th>
113 <th style="text-align:center" colspan="2">'._('Contributor').'</th>
114 <th style="text-align:left">'._('Role').'</th>
117 $contribs = $this->getContributionsByGroup ($group) ;
119 if (count ($contribs) == 0) {
120 echo '<tr><td colspan="5"><strong>'._('No contributions have been recorded for this project yet.').'</strong></td></tr>';
122 $max_displayed_contribs = 3 ;
124 foreach ($contribs as $c) {
125 $parts = $c->getParticipations () ;
126 if (count ($parts) != 0) {
128 foreach ($parts as $p) {
133 echo '<td rowspan="'.count ($parts).'">' ;
134 echo strftime (_('%Y-%m-%d'), $c->getDate ()) ;
136 echo '<td rowspan="'.count ($parts).'">' ;
137 echo util_make_link ('/plugins/'.$this->name.'/?group_id='.$group_id.'&contrib_id='.$c->getId(),htmlspecialchars($c->getName())) ;
142 if ($p->getActor()->getLogo() != '') {
144 print util_make_link ('/plugins/'.$this->name.'/?actor_id='.$p->getActor()->getId (),
145 '<img type="image/png" src="'.util_make_url ('/plugins/'.$this->name.'/actor_logo.php?actor_id='.$p->getActor()->getId ()).'" />') ;
148 printf (_('%s (%s)'),
149 util_make_link ('/plugins/'.$this->name.'/?actor_id='.$p->getActor()->getId (),
150 htmlspecialchars ($p->getActor()->getName())),
151 htmlspecialchars ($p->getActor()->getLegalStructure()->getName())) ;
153 echo htmlspecialchars ($p->getRole()->getName()) ;
159 if ($i > $max_displayed_contribs) {
165 <div style="text-align:center">
166 <?php echo util_make_link ('/plugins/'.$this->name.'/?group_id='.$group_id,_('[View All Contributions]')); ?>
169 echo $HTML->boxBottom();
172 } elseif ($hookname == "site_admin_option_hook") {
174 <li><?php echo util_make_link ('/plugins/'.$this->name.'/global_admin.php',
175 _('Edit actors and roles'). ' [' . _('Contribution tracker plugin') . ']'); ?></li>
180 function getActors () {
181 $res = db_query_params ('SELECT actor_id FROM plugin_contribtracker_actor',
183 $ids = util_result_column_to_array ($res, 0) ;
185 $results = array () ;
186 foreach ($ids as $id) {
187 $results[] = new ContribTrackerActor ($id) ;
193 function getLegalStructures () {
194 $res = db_query_params ('SELECT struct_id FROM plugin_contribtracker_legal_structure',
196 $ids = util_result_column_to_array ($res, 0) ;
198 $results = array () ;
199 foreach ($ids as $id) {
200 $results[] = new ContribTrackerLegalStructure ($id) ;
206 function getRoles () {
207 $res = db_query_params ('SELECT role_id FROM plugin_contribtracker_role',
209 $ids = util_result_column_to_array ($res, 0) ;
211 $results = array () ;
212 foreach ($ids as $id) {
213 $results[] = new ContribTrackerRole ($id) ;
219 function getContributions () {
220 $res = db_query_params ('SELECT contrib_id FROM plugin_contribtracker_contribution',
222 $ids = util_result_column_to_array ($res, 0) ;
224 $results = array () ;
225 foreach ($ids as $id) {
226 $results[] = new ContribTrackerContribution ($id) ;
229 $plugin = plugin_get_object ('contribtracker') ;
230 usort ($results, array ($plugin, "ContribComparator")) ;
234 function getContributionsByGroup ($group) {
235 $res = db_query_params ('SELECT contrib_id FROM plugin_contribtracker_contribution WHERE group_id = $1',
236 array ($group->getId())) ;
237 $ids = util_result_column_to_array ($res, 0) ;
239 $results = array () ;
240 foreach ($ids as $id) {
241 $results[] = new ContribTrackerContribution ($id) ;
244 $plugin = plugin_get_object ('contribtracker') ;
245 usort ($results, array ($plugin, "ContribComparator")) ;
249 function ContribComparator ($a, $b) {
250 if ($a->getDate() != $b->getDate()) {
251 return ($a->getDate() < $b->getDate()) ? -1 : 1 ;
252 } elseif ($a->getName() != $b->getName()) {
253 return ($a->getName() < $b->getName()) ? -1 : 1 ;
259 function ParticipationComparator ($a, $b) {
260 if ($a->getContribution()->getDate() != $b->getContribution()->getDate()) {
261 return ($a->getContribution()->getDate() < $b->getContribution()->getDate()) ? -1 : 1 ;
262 } elseif ($a->getContribution() != $b->getContribution()) {
263 return ($a->getContribution() < $b->getContribution()) ? -1 : 1 ;
264 } elseif ($a->getIndex() != $b->getIndex()) {
265 return ($a->getIndex() < $b->getIndex()) ? -1 : 1 ;
272 class ContribTrackerRole extends Error {
275 function ContribTrackerRole ($id=false) {
280 return $this->fetchData ($id) ;
283 function fetchData ($id) {
284 $res = db_query_params ('SELECT * FROM plugin_contribtracker_role WHERE role_id=$1',
286 if (!$res || db_numrows($res) < 1) {
287 $this->setError(sprintf('ContribTrackerRole(): %s',db_error()));
291 $this->data_array = db_fetch_array ($res) ;
295 function create ($name, $description) {
296 if ($this->getId ()) {
297 $this->setError(_('Object already exists')) ;
302 $res = db_query_params ('INSERT INTO plugin_contribtracker_role (name, description) VALUES ($1,$2)',
305 if (!$res || db_affected_rows ($res) < 1) {
306 $this->setError (sprintf(_('Could not create object in database: %s.'),
312 $id = db_insertid ($res, 'plugin_contribtracker_role', 'role_id') ;
314 $this->setError (sprintf(_('Could not get ID from object in database: %s.'),
321 return $this->fetchData ($id) ;
324 function update ($name, $description) {
325 if (! $this->getId ()) {
326 $this->setError(_('Object does not exist')) ;
330 $id = $this->getId () ;
333 $res = db_query_params ('UPDATE plugin_contribtracker_role SET (name, description) = ($1,$2) WHERE role_id = $3',
337 if (!$res || db_affected_rows ($res) < 1) {
338 $this->setError (sprintf(_('Could not update object in database: %s.'),
345 return $this->fetchData ($id) ;
349 $id = $this->getId () ;
351 $this->setError (_('Cannot delete a non-existing object.')) ;
355 $res = db_query_params ('DELETE FROM plugin_contribtracker_role WHERE role_id = $1',
358 $this->setError (sprintf(_('Could not delete object in database: %s.'),
363 $this->data_array = array () ;
369 if (isset ($this->data_array['role_id'])) {
370 return $this->data_array['role_id'] ;
375 function getName () { return $this->data_array['name'] ; }
376 function getDescription () { return $this->data_array['description'] ; }
380 class ContribTrackerLegalStructure extends Error {
383 function ContribTrackerLegalStructure ($id=false) {
388 return $this->fetchData ($id) ;
391 function fetchData ($id) {
392 $res = db_query_params ('SELECT * FROM plugin_contribtracker_legal_structure WHERE struct_id=$1',
394 if (!$res || db_numrows($res) < 1) {
395 $this->setError(sprintf('ContribTrackerLegalStructure(): %s',db_error()));
399 $this->data_array = db_fetch_array ($res) ;
403 function create ($name) {
404 if ($this->getId ()) {
405 $this->setError(_('Object already exists')) ;
410 $res = db_query_params ('INSERT INTO plugin_contribtracker_legal_structure (name) VALUES ($1)',
412 if (!$res || db_affected_rows ($res) < 1) {
413 $this->setError (sprintf(_('Could not create object in database: %s.'),
419 $id = db_insertid ($res, 'plugin_contribtracker_legal_structure', 'struct_id') ;
421 $this->setError (sprintf(_('Could not get ID from object in database: %s.'),
428 return $this->fetchData ($id) ;
431 function update ($name) {
432 if (! $this->getId ()) {
433 $this->setError(_('Object does not exist')) ;
437 $id = $this->getId () ;
440 $res = db_query_params ('UPDATE plugin_contribtracker_legal_structure SET (name) = ($1) WHERE struct_id = $2',
443 if (!$res || db_affected_rows ($res) < 1) {
444 $this->setError (sprintf(_('Could not update object in database: %s.'),
451 return $this->fetchData ($id) ;
455 $id = $this->getId () ;
457 $this->setError (_('Cannot delete a non-existing object.')) ;
461 $res = db_query_params ('DELETE FROM plugin_contribtracker_legal_structure WHERE struct_id = $1',
464 $this->setError (sprintf(_('Could not delete object in database: %s.'),
469 $this->data_array = array () ;
475 if (isset ($this->data_array['struct_id'])) {
476 return $this->data_array['struct_id'] ;
481 function getName () { return $this->data_array['name'] ; }
484 class ContribTrackerActor extends Error {
487 function ContribTrackerActor ($id=false) {
492 return $this->fetchData ($id) ;
495 function fetchData ($id) {
496 $res = db_query_params ('SELECT * FROM plugin_contribtracker_actor WHERE actor_id=$1',
498 if (!$res || db_numrows($res) < 1) {
499 $this->setError(sprintf('ContribTrackerActor(): %s',db_error()));
503 $this->data_array = db_fetch_array ($res) ;
507 function create ($name, $url, $email, $description, $logo, $structure) {
508 if ($this->getId ()) {
509 $this->setError(_('Object already exists')) ;
514 $res = db_query_params ('INSERT INTO plugin_contribtracker_actor (name,url,email,description,logo,struct_id) VALUES ($1,$2,$3,$4,$5,$6)',
519 base64_encode ($logo),
520 $structure->getID())) ;
521 if (!$res || db_affected_rows ($res) < 1) {
522 $this->setError (sprintf(_('Could not create object in database: %s.'),
528 $id = db_insertid ($res, 'plugin_contribtracker_actor', 'actor_id') ;
530 $this->setError (sprintf(_('Could not get ID from object in database: %s.'),
537 return $this->fetchData ($id) ;
540 function update ($name, $url, $email, $description, $logo, $structure) {
541 if (! $this->getId ()) {
542 $this->setError(_('Object does not exist')) ;
546 $id = $this->getId () ;
549 $res = db_query_params ('UPDATE plugin_contribtracker_actor SET (name,url,email,description,logo,struct_id) = ($1,$2,$3,$4,$5,$6) WHERE actor_id = $7',
554 base64_encode ($logo),
557 if (!$res || db_affected_rows ($res) < 1) {
558 $this->setError (sprintf(_('Could not update object in database: %s.'),
565 return $this->fetchData ($id) ;
569 $id = $this->getId () ;
571 $this->setError (_('Cannot delete a non-existing object.')) ;
575 $res = db_query_params ('DELETE FROM plugin_contribtracker_actor WHERE actor_id = $1',
578 $this->setError (sprintf(_('Could not delete object in database: %s.'),
583 $this->data_array = array () ;
589 if (isset ($this->data_array['actor_id'])) {
590 return $this->data_array['actor_id'] ;
595 function getName () { return $this->data_array['name'] ; }
596 function getUrl () { return $this->data_array['url'] ; }
597 function getEmail () { return $this->data_array['email'] ; }
598 function getDescription () { return $this->data_array['description'] ; }
599 function getLegalStructure () {
600 return new ContribTrackerLegalStructure ($this->data_array['struct_id']) ;
602 function getLogo () { return base64_decode ($this->data_array['logo']) ; }
604 function getParticipations () {
605 $res = db_query_params ('SELECT participation_id FROM plugin_contribtracker_participation WHERE actor_id = $1',
606 array ($this->getId())) ;
607 $ids = util_result_column_to_array ($res, 0) ;
609 $results = array () ;
610 foreach ($ids as $id) {
611 $results[] = new ContribTrackerParticipation ($id) ;
614 $plugin = plugin_get_object ('contribtracker') ;
615 usort ($results, array ($plugin, "ParticipationComparator")) ;
621 class ContribTrackerContribution extends Error {
624 function ContribTrackerContribution ($id=false) {
629 return $this->fetchData ($id) ;
632 function fetchData ($id) {
633 $res = db_query_params ('SELECT * FROM plugin_contribtracker_contribution WHERE contrib_id=$1',
635 if (!$res || db_numrows($res) < 1) {
636 $this->setError(sprintf('ContribTrackerContribution(): %s',db_error()));
640 $this->data_array = db_fetch_array ($res) ;
644 function create ($name, $date, $description, $group) {
645 if ($this->getId ()) {
646 $this->setError(_('Object already exists')) ;
651 $res = db_query_params ('INSERT INTO plugin_contribtracker_contribution (name,date,description,group_id) VALUES ($1,$2,$3,$4)',
656 if (!$res || db_affected_rows ($res) < 1) {
657 $this->setError (sprintf(_('Could not create object in database: %s.'),
663 $id = db_insertid ($res, 'plugin_contribtracker_contribution', 'contrib_id') ;
665 $this->setError (sprintf(_('Could not get ID from object in database: %s.'),
672 return $this->fetchData ($id) ;
675 function update ($name, $date, $description, $group) {
676 if (! $this->getId ()) {
677 $this->setError(_('Object does not exist')) ;
681 $id = $this->getId () ;
684 $res = db_query_params ('UPDATE plugin_contribtracker_contribution SET (name,date,description,group_id) = ($1,$2,$3,$4) WHERE contrib_id = $5',
690 if (!$res || db_affected_rows ($res) < 1) {
691 $this->setError (sprintf(_('Could not update object in database: %s.'),
698 return $this->fetchData ($id) ;
702 $id = $this->getId () ;
704 $this->setError (_('Cannot delete a non-existing object.')) ;
708 $res = db_query_params ('DELETE FROM plugin_contribtracker_contribution WHERE contrib_id = $1',
711 $this->setError (sprintf(_('Could not delete object in database: %s.'),
716 $this->data_array = array () ;
722 if (isset ($this->data_array['contrib_id'])) {
723 return $this->data_array['contrib_id'] ;
728 function getName () { return $this->data_array['name'] ; }
729 function getDate () { return $this->data_array['date'] ; }
730 function getDescription () { return $this->data_array['description'] ; }
731 function getGroup () {
732 return group_get_object ($this->data_array['group_id']) ;
735 function getParticipations () {
736 $res = db_query_params ('SELECT participation_id FROM plugin_contribtracker_participation WHERE contrib_id = $1',
737 array ($this->getId())) ;
738 $ids = util_result_column_to_array ($res, 0) ;
740 $results = array () ;
741 foreach ($ids as $id) {
742 $results[] = new ContribTrackerParticipation ($id) ;
745 $plugin = plugin_get_object ('contribtracker') ;
746 usort ($results, array ($plugin, "ParticipationComparator")) ;
750 function getLastPartIndex () {
751 $res = db_query_params ('SELECT COUNT(*) AS c FROM plugin_contribtracker_participation WHERE contrib_id = $1',
752 array ($this->getId())) ;
753 $curindex = db_result ($res,0,'c') ;
758 class ContribTrackerParticipation extends Error {
761 function ContribTrackerParticipation ($id=false) {
766 return $this->fetchData ($id) ;
769 function fetchData ($id) {
770 $res = db_query_params ('SELECT * FROM plugin_contribtracker_participation WHERE participation_id=$1',
772 if (!$res || db_numrows($res) < 1) {
773 $this->setError(sprintf('ContribTrackerParticipation(): %s',db_error()));
777 $this->data_array = db_fetch_array ($res) ;
781 function create ($contrib, $actor, $role) {
782 if ($this->getId ()) {
783 $this->setError(_('Object already exists')) ;
788 $index = $contrib->getLastPartIndex () + 1;
790 $res = db_query_params ('INSERT INTO plugin_contribtracker_participation (contrib_id,actor_id,role_id,index) VALUES ($1,$2,$3,$4)',
791 array ($contrib->getID(),
795 if (!$res || db_affected_rows ($res) < 1) {
796 $this->setError (sprintf(_('Could not create object in database: %s.'),
802 $id = db_insertid ($res, 'plugin_contribtracker_participation', 'participation_id') ;
804 $this->setError (sprintf(_('Could not get ID from object in database: %s.'),
811 return $this->fetchData ($id) ;
814 function update ($contrib, $actor, $role) {
815 if (! $this->getId ()) {
816 $this->setError(_('Object does not exist')) ;
820 $id = $this->getId () ;
821 if ($contrib->getID() != $this->getContribution()->getID()) {
822 $this->setError (_('Cannot currently move a participation across contributions.')) ;
827 $res = db_query_params ('UPDATE plugin_contribtracker_participation SET (contrib_id,actor_id,role_id) = ($1,$2,$3) WHERE participation_id = $4',
828 array ($contrib->getID(),
832 if (!$res || db_affected_rows ($res) < 1) {
833 $this->setError (sprintf(_('Could not update object in database: %s.'),
840 return $this->fetchData ($id) ;
844 $id = $this->getId () ;
846 $this->setError (_('Cannot delete a non-existing object.')) ;
851 $curindex = $this->getIndex() ;
852 $res = db_query_params ('DELETE FROM plugin_contribtracker_participation WHERE participation_id = $1',
855 $this->setError (sprintf(_('Could not delete object in database: %s.'),
859 $res = db_query_params ('UPDATE plugin_contribtracker_participation SET index = -index WHERE contrib_id = $1 and index > $2',
860 array ($this->getContribution()->getId(),
863 $this->setError (sprintf(_('Could not update indices in database: %s.'),
867 $res = db_query_params ('UPDATE plugin_contribtracker_participation SET index = -index -1 WHERE contrib_id = $1 and index < 0',
868 array ($this->getContribution()->getId())) ;
870 $this->setError (sprintf(_('Could not update indices in database: %s.'),
876 $this->data_array = array () ;
882 $id = $this->getId () ;
884 $this->setError (_('Cannot update a non-existing object.')) ;
888 $cur = $this->getIndex() ;
892 $contrib_id = $this->getContribution()->getId() ;
895 $res = db_query_params ('UPDATE plugin_contribtracker_participation SET index = 0 WHERE participation_id = $1',
897 $res = db_query_params ('UPDATE plugin_contribtracker_participation SET index = index+1 WHERE contrib_id = $1 AND index = $2',
900 $res = db_query_params ('UPDATE plugin_contribtracker_participation SET index = $1 WHERE contrib_id = $2 AND index = 0',
906 function moveDown () {
907 $id = $this->getId () ;
909 $this->setError (_('Cannot update a non-existing object.')) ;
913 $lastid = $this->getContribution()->getLastPartIndex() ;
915 $cur = $this->getIndex() ;
916 if ($cur == $lastid) {
919 $contrib_id = $this->getContribution()->getId() ;
922 $res = db_query_params ('UPDATE plugin_contribtracker_participation SET index = 0 WHERE participation_id = $1',
924 $res = db_query_params ('UPDATE plugin_contribtracker_participation SET index = index-1 WHERE contrib_id = $1 AND index = $2',
927 $res = db_query_params ('UPDATE plugin_contribtracker_participation SET index = $1 WHERE contrib_id = $2 AND index = 0',
934 if (isset ($this->data_array['participation_id'])) {
935 return $this->data_array['participation_id'] ;
940 function getIndex () {
941 if (isset ($this->data_array['index'])) {
942 return $this->data_array['index'] ;
947 function getActor () {
948 return new ContribTrackerActor ($this->data_array['actor_id']) ;
950 function getRole () {
951 return new ContribTrackerRole ($this->data_array['role_id']) ;
953 function getContribution () {
954 return new ContribTrackerContribution ($this->data_array['contrib_id']) ;
960 // c-file-style: "bsd"