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
21 * along with GForge; if not, write to the Free Software
22 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 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->hooks[] = "groupmenu" ; // To put into the project tabs
31 $this->hooks[] = "groupisactivecheckbox" ; // The "use ..." checkbox in editgroupinfo
32 $this->hooks[] = "groupisactivecheckboxpost" ; //
33 $this->hooks[] = "project_admin_plugins"; // to show up in the admin page for group
34 $this->hooks[] = "project_before_frs"; // project summary page
35 $this->hooks[] = "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['DIRS'][]='/plugins/'.$this->name.'/?group_id=' . $group_id ;
55 (($params['toptab'] == $this->name) ? $params['selected']=(count($params['TITLES'])-1) : '' );
56 } elseif ($hookname == "groupisactivecheckbox") {
57 //Check if the group is active
58 // this code creates the checkbox in the project edit public info page to activate/deactivate the plugin
59 $group_id=$params['group'];
60 $group = &group_get_object($group_id);
63 echo ' <input type="CHECKBOX" name="use_contribtrackerplugin" value="1" ';
64 // CHECKED OR UNCHECKED?
65 if ( $group->usesPlugin ( $this->name ) ) {
72 echo _('Use the Contribution Tracker plugin') ;
76 } elseif ($hookname == "groupisactivecheckboxpost") {
77 // this code actually activates/deactivates the plugin after the form was submitted in the project edit public info page
78 $group_id=$params['group'];
79 $group = &group_get_object($group_id);
80 $use_contribtrackerplugin = getStringFromRequest('use_contribtrackerplugin');
81 if ( $use_contribtrackerplugin == 1 ) {
82 $group->setPluginUse ( $this->name );
84 $group->setPluginUse ( $this->name, false );
86 } elseif ($hookname == "project_admin_plugins") {
87 // this displays the link in the project admin options page to its ContribTracker administration
88 $group_id = $params['group_id'];
89 $group = &group_get_object($group_id);
90 if ( $group->usesPlugin ( $this->name ) ) {
91 echo util_make_link ("/plugins/".$this->name."/project_admin.php?group_id=".$group->getID(),
92 _('Contribution Tracker admin')) ;
97 elseif ($hookname == "project_before_frs") {
98 $group_id = $params['group_id'];
99 $group = &group_get_object ($group_id);
101 if ($group->usesPlugin($this->name)) {
103 echo '<div id="major-contributions">';
104 echo $HTML->boxTop(_('Latest Major Contributions'), 'Latest_Major_Contributions');
107 <table cellspacing="1" cellpadding="5" width="100%" border="0">
109 <th style="text-align:left">'._('Date').'</th>
110 <th style="text-align:left">'._('Contribution').'</th>
111 <th style="text-align:center" colspan="2">'._('Contributor').'</th>
112 <th style="text-align:left">'._('Role').'</th>
115 $contribs = $this->getContributionsByGroup ($group) ;
117 if (count ($contribs) == 0) {
118 echo '<tr><td colspan="5"><strong>'._('No contributions have been recorded for this project yet.').'</strong></td></tr>';
120 $max_displayed_contribs = 3 ;
122 foreach ($contribs as $c) {
123 $parts = $c->getParticipations () ;
124 if (count ($parts) != 0) {
126 foreach ($parts as $p) {
131 echo '<td rowspan="'.count ($parts).'">' ;
132 echo strftime (_('%Y-%m-%d'), $c->getDate ()) ;
134 echo '<td rowspan="'.count ($parts).'">' ;
135 echo util_make_link ('/plugins/'.$this->name.'/?group_id='.$group_id.'&contrib_id='.$c->getId(),htmlspecialchars($c->getName())) ;
140 if ($p->getActor()->getLogo() != '') {
142 print util_make_link ('/plugins/'.$this->name.'/?actor_id='.$p->getActor()->getId (),
143 '<img type="image/png" src="'.util_make_url ('/plugins/'.$this->name.'/actor_logo.php?actor_id='.$p->getActor()->getId ()).'" />') ;
146 printf (_('%s (%s)'),
147 util_make_link ('/plugins/'.$this->name.'/?actor_id='.$p->getActor()->getId (),
148 htmlspecialchars ($p->getActor()->getName())),
149 htmlspecialchars ($p->getActor()->getLegalStructure()->getName())) ;
151 echo htmlspecialchars ($p->getRole()->getName()) ;
157 if ($i > $max_displayed_contribs) {
163 <div style="text-align:center">
164 <?php echo util_make_link ('/plugins/'.$this->name.'/?group_id='.$group_id,_('[View All Contributions]')); ?>
167 echo $HTML->boxBottom();
171 elseif ($hookname == "site_admin_option_hook") {
173 <li><?php echo util_make_link ('/plugins/'.$this->name.'/global_admin.php',
174 _('Edit actors and roles for the contribution tracker plugin')
181 function getActors () {
182 $res = db_query_params ('SELECT actor_id FROM plugin_contribtracker_actor',
184 $ids = util_result_column_to_array ($res, 0) ;
186 $results = array () ;
187 foreach ($ids as $id) {
188 $results[] = new ContribTrackerActor ($id) ;
194 function getLegalStructures () {
195 $res = db_query_params ('SELECT struct_id FROM plugin_contribtracker_legal_structure',
197 $ids = util_result_column_to_array ($res, 0) ;
199 $results = array () ;
200 foreach ($ids as $id) {
201 $results[] = new ContribTrackerLegalStructure ($id) ;
207 function getRoles () {
208 $res = db_query_params ('SELECT role_id FROM plugin_contribtracker_role',
210 $ids = util_result_column_to_array ($res, 0) ;
212 $results = array () ;
213 foreach ($ids as $id) {
214 $results[] = new ContribTrackerRole ($id) ;
220 function getContributions () {
221 $res = db_query_params ('SELECT contrib_id FROM plugin_contribtracker_contribution',
223 $ids = util_result_column_to_array ($res, 0) ;
225 $results = array () ;
226 foreach ($ids as $id) {
227 $results[] = new ContribTrackerContribution ($id) ;
230 $plugin = plugin_get_object ('contribtracker') ;
231 usort ($results, array ($plugin, "ContribComparator")) ;
235 function getContributionsByGroup ($group) {
236 $res = db_query_params ('SELECT contrib_id FROM plugin_contribtracker_contribution WHERE group_id = $1',
237 array ($group->getId())) ;
238 $ids = util_result_column_to_array ($res, 0) ;
240 $results = array () ;
241 foreach ($ids as $id) {
242 $results[] = new ContribTrackerContribution ($id) ;
245 $plugin = plugin_get_object ('contribtracker') ;
246 usort ($results, array ($plugin, "ContribComparator")) ;
250 function ContribComparator ($a, $b) {
251 if ($a->getDate() != $b->getDate()) {
252 return ($a->getDate() < $b->getDate()) ? -1 : 1 ;
253 } elseif ($a->getName() != $b->getName()) {
254 return ($a->getName() < $b->getName()) ? -1 : 1 ;
260 function ParticipationComparator ($a, $b) {
261 if ($a->getContribution()->getDate() != $b->getContribution()->getDate()) {
262 return ($a->getContribution()->getDate() < $b->getContribution()->getDate()) ? -1 : 1 ;
263 } elseif ($a->getContribution() != $b->getContribution()) {
264 return ($a->getContribution() < $b->getContribution()) ? -1 : 1 ;
265 } elseif ($a->getIndex() != $b->getIndex()) {
266 return ($a->getIndex() < $b->getIndex()) ? -1 : 1 ;
273 class ContribTrackerRole extends Error {
276 function ContribTrackerRole ($id=false) {
281 return $this->fetchData ($id) ;
284 function fetchData ($id) {
285 $res = db_query_params ('SELECT * FROM plugin_contribtracker_role WHERE role_id=$1',
287 if (!$res || db_numrows($res) < 1) {
288 $this->setError(sprintf('ContribTrackerRole(): %s',db_error()));
292 $this->data_array = db_fetch_array ($res) ;
296 function create ($name, $description) {
297 if ($this->getId ()) {
298 $this->setError(_('Object already exists')) ;
303 $res = db_query_params ('INSERT INTO plugin_contribtracker_role (name, description) VALUES ($1,$2)',
306 if (!$res || db_affected_rows ($res) < 1) {
307 $this->setError (sprintf(_('Could not create object in database: %s.'),
313 $id = db_insertid ($res, 'plugin_contribtracker_role', 'role_id') ;
315 $this->setError (sprintf(_('Could not get ID from object in database: %s.'),
322 return $this->fetchData ($id) ;
325 function update ($name, $description) {
326 if (! $this->getId ()) {
327 $this->setError(_('Object does not exist')) ;
331 $id = $this->getId () ;
334 $res = db_query_params ('UPDATE plugin_contribtracker_role SET (name, description) = ($1,$2) WHERE role_id = $3',
338 if (!$res || db_affected_rows ($res) < 1) {
339 $this->setError (sprintf(_('Could not update object in database: %s.'),
346 return $this->fetchData ($id) ;
350 $id = $this->getId () ;
352 $this->setError (_('Cannot delete a non-existing object.')) ;
356 $res = db_query_params ('DELETE FROM plugin_contribtracker_role WHERE role_id = $1',
359 $this->setError (sprintf(_('Could not delete object in database: %s.'),
364 $this->data_array = array () ;
370 if (isset ($this->data_array['role_id'])) {
371 return $this->data_array['role_id'] ;
376 function getName () { return $this->data_array['name'] ; }
377 function getDescription () { return $this->data_array['description'] ; }
381 class ContribTrackerLegalStructure extends Error {
384 function ContribTrackerLegalStructure ($id=false) {
389 return $this->fetchData ($id) ;
392 function fetchData ($id) {
393 $res = db_query_params ('SELECT * FROM plugin_contribtracker_legal_structure WHERE struct_id=$1',
395 if (!$res || db_numrows($res) < 1) {
396 $this->setError(sprintf('ContribTrackerLegalStructure(): %s',db_error()));
400 $this->data_array = db_fetch_array ($res) ;
404 function create ($name) {
405 if ($this->getId ()) {
406 $this->setError(_('Object already exists')) ;
411 $res = db_query_params ('INSERT INTO plugin_contribtracker_legal_structure (name) VALUES ($1)',
413 if (!$res || db_affected_rows ($res) < 1) {
414 $this->setError (sprintf(_('Could not create object in database: %s.'),
420 $id = db_insertid ($res, 'plugin_contribtracker_legal_structure', 'struct_id') ;
422 $this->setError (sprintf(_('Could not get ID from object in database: %s.'),
429 return $this->fetchData ($id) ;
432 function update ($name) {
433 if (! $this->getId ()) {
434 $this->setError(_('Object does not exist')) ;
438 $id = $this->getId () ;
441 $res = db_query_params ('UPDATE plugin_contribtracker_legal_structure SET (name) = ($1) WHERE struct_id = $2',
444 if (!$res || db_affected_rows ($res) < 1) {
445 $this->setError (sprintf(_('Could not update object in database: %s.'),
452 return $this->fetchData ($id) ;
456 $id = $this->getId () ;
458 $this->setError (_('Cannot delete a non-existing object.')) ;
462 $res = db_query_params ('DELETE FROM plugin_contribtracker_legal_structure WHERE struct_id = $1',
465 $this->setError (sprintf(_('Could not delete object in database: %s.'),
470 $this->data_array = array () ;
476 if (isset ($this->data_array['struct_id'])) {
477 return $this->data_array['struct_id'] ;
482 function getName () { return $this->data_array['name'] ; }
485 class ContribTrackerActor extends Error {
488 function ContribTrackerActor ($id=false) {
493 return $this->fetchData ($id) ;
496 function fetchData ($id) {
497 $res = db_query_params ('SELECT * FROM plugin_contribtracker_actor WHERE actor_id=$1',
499 if (!$res || db_numrows($res) < 1) {
500 $this->setError(sprintf('ContribTrackerActor(): %s',db_error()));
504 $this->data_array = db_fetch_array ($res) ;
508 function create ($name, $url, $email, $description, $logo, $structure) {
509 if ($this->getId ()) {
510 $this->setError(_('Object already exists')) ;
515 $res = db_query_params ('INSERT INTO plugin_contribtracker_actor (name,url,email,description,logo,struct_id) VALUES ($1,$2,$3,$4,$5,$6)',
520 base64_encode ($logo),
521 $structure->getID())) ;
522 if (!$res || db_affected_rows ($res) < 1) {
523 $this->setError (sprintf(_('Could not create object in database: %s.'),
529 $id = db_insertid ($res, 'plugin_contribtracker_actor', 'actor_id') ;
531 $this->setError (sprintf(_('Could not get ID from object in database: %s.'),
538 return $this->fetchData ($id) ;
541 function update ($name, $url, $email, $description, $logo, $structure) {
542 if (! $this->getId ()) {
543 $this->setError(_('Object does not exist')) ;
547 $id = $this->getId () ;
550 $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',
555 base64_encode ($logo),
558 if (!$res || db_affected_rows ($res) < 1) {
559 $this->setError (sprintf(_('Could not update object in database: %s.'),
566 return $this->fetchData ($id) ;
570 $id = $this->getId () ;
572 $this->setError (_('Cannot delete a non-existing object.')) ;
576 $res = db_query_params ('DELETE FROM plugin_contribtracker_actor WHERE actor_id = $1',
579 $this->setError (sprintf(_('Could not delete object in database: %s.'),
584 $this->data_array = array () ;
590 if (isset ($this->data_array['actor_id'])) {
591 return $this->data_array['actor_id'] ;
596 function getName () { return $this->data_array['name'] ; }
597 function getUrl () { return $this->data_array['url'] ; }
598 function getEmail () { return $this->data_array['email'] ; }
599 function getDescription () { return $this->data_array['description'] ; }
600 function getLegalStructure () {
601 return new ContribTrackerLegalStructure ($this->data_array['struct_id']) ;
603 function getLogo () { return base64_decode ($this->data_array['logo']) ; }
605 function getParticipations () {
606 $res = db_query_params ('SELECT participation_id FROM plugin_contribtracker_participation WHERE actor_id = $1',
607 array ($this->getId())) ;
608 $ids = util_result_column_to_array ($res, 0) ;
610 $results = array () ;
611 foreach ($ids as $id) {
612 $results[] = new ContribTrackerParticipation ($id) ;
615 $plugin = plugin_get_object ('contribtracker') ;
616 usort ($results, array ($plugin, "ParticipationComparator")) ;
622 class ContribTrackerContribution extends Error {
625 function ContribTrackerContribution ($id=false) {
630 return $this->fetchData ($id) ;
633 function fetchData ($id) {
634 $res = db_query_params ('SELECT * FROM plugin_contribtracker_contribution WHERE contrib_id=$1',
636 if (!$res || db_numrows($res) < 1) {
637 $this->setError(sprintf('ContribTrackerContribution(): %s',db_error()));
641 $this->data_array = db_fetch_array ($res) ;
645 function create ($name, $date, $description, $group) {
646 if ($this->getId ()) {
647 $this->setError(_('Object already exists')) ;
652 $res = db_query_params ('INSERT INTO plugin_contribtracker_contribution (name,date,description,group_id) VALUES ($1,$2,$3,$4)',
657 if (!$res || db_affected_rows ($res) < 1) {
658 $this->setError (sprintf(_('Could not create object in database: %s.'),
664 $id = db_insertid ($res, 'plugin_contribtracker_contribution', 'contrib_id') ;
666 $this->setError (sprintf(_('Could not get ID from object in database: %s.'),
673 return $this->fetchData ($id) ;
676 function update ($name, $date, $description, $group) {
677 if (! $this->getId ()) {
678 $this->setError(_('Object does not exist')) ;
682 $id = $this->getId () ;
685 $res = db_query_params ('UPDATE plugin_contribtracker_contribution SET (name,date,description,group_id) = ($1,$2,$3,$4) WHERE contrib_id = $5',
691 if (!$res || db_affected_rows ($res) < 1) {
692 $this->setError (sprintf(_('Could not update object in database: %s.'),
699 return $this->fetchData ($id) ;
703 $id = $this->getId () ;
705 $this->setError (_('Cannot delete a non-existing object.')) ;
709 $res = db_query_params ('DELETE FROM plugin_contribtracker_contribution WHERE contrib_id = $1',
712 $this->setError (sprintf(_('Could not delete object in database: %s.'),
717 $this->data_array = array () ;
723 if (isset ($this->data_array['contrib_id'])) {
724 return $this->data_array['contrib_id'] ;
729 function getName () { return $this->data_array['name'] ; }
730 function getDate () { return $this->data_array['date'] ; }
731 function getDescription () { return $this->data_array['description'] ; }
732 function getGroup () {
733 return group_get_object ($this->data_array['group_id']) ;
736 function getParticipations () {
737 $res = db_query_params ('SELECT participation_id FROM plugin_contribtracker_participation WHERE contrib_id = $1',
738 array ($this->getId())) ;
739 $ids = util_result_column_to_array ($res, 0) ;
741 $results = array () ;
742 foreach ($ids as $id) {
743 $results[] = new ContribTrackerParticipation ($id) ;
746 $plugin = plugin_get_object ('contribtracker') ;
747 usort ($results, array ($plugin, "ParticipationComparator")) ;
751 function getLastPartIndex () {
752 $res = db_query_params ('SELECT COUNT(*) AS c FROM plugin_contribtracker_participation WHERE contrib_id = $1',
753 array ($this->getId())) ;
754 $curindex = db_result ($res,0,'c') ;
759 class ContribTrackerParticipation extends Error {
762 function ContribTrackerParticipation ($id=false) {
767 return $this->fetchData ($id) ;
770 function fetchData ($id) {
771 $res = db_query_params ('SELECT * FROM plugin_contribtracker_participation WHERE participation_id=$1',
773 if (!$res || db_numrows($res) < 1) {
774 $this->setError(sprintf('ContribTrackerParticipation(): %s',db_error()));
778 $this->data_array = db_fetch_array ($res) ;
782 function create ($contrib, $actor, $role) {
783 if ($this->getId ()) {
784 $this->setError(_('Object already exists')) ;
789 $index = $contrib->getLastPartIndex () + 1;
791 $res = db_query_params ('INSERT INTO plugin_contribtracker_participation (contrib_id,actor_id,role_id,index) VALUES ($1,$2,$3,$4)',
792 array ($contrib->getID(),
796 if (!$res || db_affected_rows ($res) < 1) {
797 $this->setError (sprintf(_('Could not create object in database: %s.'),
803 $id = db_insertid ($res, 'plugin_contribtracker_participation', 'participation_id') ;
805 $this->setError (sprintf(_('Could not get ID from object in database: %s.'),
812 return $this->fetchData ($id) ;
815 function update ($contrib, $actor, $role) {
816 if (! $this->getId ()) {
817 $this->setError(_('Object does not exist')) ;
821 $id = $this->getId () ;
822 if ($contrib->getID() != $this->getContribution()->getID()) {
823 $this->setError (_('Cannot currently move a participation across contributions.')) ;
828 $res = db_query_params ('UPDATE plugin_contribtracker_participation SET (contrib_id,actor_id,role_id) = ($1,$2,$3) WHERE participation_id = $4',
829 array ($contrib->getID(),
833 if (!$res || db_affected_rows ($res) < 1) {
834 $this->setError (sprintf(_('Could not update object in database: %s.'),
841 return $this->fetchData ($id) ;
845 $id = $this->getId () ;
847 $this->setError (_('Cannot delete a non-existing object.')) ;
852 $curindex = $this->getIndex() ;
853 $res = db_query_params ('DELETE FROM plugin_contribtracker_participation WHERE participation_id = $1',
856 $this->setError (sprintf(_('Could not delete object in database: %s.'),
860 $res = db_query_params ('UPDATE plugin_contribtracker_participation SET index = -index WHERE contrib_id = $1 and index > $2',
861 array ($this->getContribution()->getId(),
864 $this->setError (sprintf(_('Could not update indices in database: %s.'),
868 $res = db_query_params ('UPDATE plugin_contribtracker_participation SET index = -index -1 WHERE contrib_id = $1 and index < 0',
869 array ($this->getContribution()->getId())) ;
871 $this->setError (sprintf(_('Could not update indices in database: %s.'),
877 $this->data_array = array () ;
883 $id = $this->getId () ;
885 $this->setError (_('Cannot update a non-existing object.')) ;
889 $cur = $this->getIndex() ;
893 $contrib_id = $this->getContribution()->getId() ;
896 $res = db_query_params ('UPDATE plugin_contribtracker_participation SET index = 0 WHERE participation_id = $1',
898 $res = db_query_params ('UPDATE plugin_contribtracker_participation SET index = index+1 WHERE contrib_id = $1 AND index = $2',
901 $res = db_query_params ('UPDATE plugin_contribtracker_participation SET index = $1 WHERE contrib_id = $2 AND index = 0',
907 function moveDown () {
908 $id = $this->getId () ;
910 $this->setError (_('Cannot update a non-existing object.')) ;
914 $lastid = $this->getContribution()->getLastPartIndex() ;
916 $cur = $this->getIndex() ;
917 if ($cur == $lastid) {
920 $contrib_id = $this->getContribution()->getId() ;
923 $res = db_query_params ('UPDATE plugin_contribtracker_participation SET index = 0 WHERE participation_id = $1',
925 $res = db_query_params ('UPDATE plugin_contribtracker_participation SET index = index-1 WHERE contrib_id = $1 AND index = $2',
928 $res = db_query_params ('UPDATE plugin_contribtracker_participation SET index = $1 WHERE contrib_id = $2 AND index = 0',
935 if (isset ($this->data_array['participation_id'])) {
936 return $this->data_array['participation_id'] ;
941 function getIndex () {
942 if (isset ($this->data_array['index'])) {
943 return $this->data_array['index'] ;
948 function getActor () {
949 return new ContribTrackerActor ($this->data_array['actor_id']) ;
951 function getRole () {
952 return new ContribTrackerRole ($this->data_array['role_id']) ;
954 function getContribution () {
955 return new ContribTrackerContribution ($this->data_array['contrib_id']) ;
961 // c-file-style: "bsd"