5 * Copyright 1999-2001, VA Linux Systems, Inc.
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
12 * by the Free Software Foundation; either version 2 of the License,
13 * or (at your option) any later version.
15 * FusionForge is distributed in the hope that it will be useful, but
16 * WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 * General Public License for more details.
20 * You should have received a copy of the GNU General Public License
21 * along with FusionForge; if not, write to the Free Software
22 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
26 require_once $gfcommon.'tracker/ArtifactTypes.class.php';
27 require_once $gfcommon.'tracker/ArtifactTypeFactory.class.php';
28 require_once $gfcommon.'forum/Forum.class.php';
29 require_once $gfcommon.'forum/ForumFactory.class.php';
30 require_once $gfcommon.'pm/ProjectGroup.class.php';
31 require_once $gfcommon.'pm/ProjectGroupFactory.class.php';
32 require_once $gfcommon.'include/Role.class.php';
33 require_once $gfcommon.'frs/FRSPackage.class.php';
34 require_once $gfcommon.'docman/DocumentGroup.class.php';
35 require_once $gfcommon.'mail/MailingList.class.php';
36 require_once $gfcommon.'mail/MailingListFactory.class.php';
37 require_once $gfcommon.'survey/SurveyFactory.class.php';
38 require_once $gfcommon.'survey/SurveyQuestionFactory.class.php';
39 require_once $gfcommon.'include/gettext.php';
41 //the license_id of "Other/proprietary" license
42 define('GROUP_LICENSE_OTHER',126);
44 $LICENSE_NAMES=array();
47 * group_get_licences() - get the licenses list
49 * @return array list of licenses
51 function & group_get_licenses() {
52 global $LICENSE_NAMES;
53 if(empty($LICENSE_NAMES)) {
54 $result = db_query_params ('select * from licenses', array());
55 while($data = db_fetch_array($result)) {
56 $LICENSE_NAMES[$data['license_id']] = $data['license_name'];
59 return $LICENSE_NAMES;
65 * group_get_object() - Get the group object.
67 * group_get_object() is useful so you can pool group objects/save database queries
68 * You should always use this instead of instantiating the object directly.
70 * You can now optionally pass in a db result handle. If you do, it re-uses that query
71 * to instantiate the objects.
73 * IMPORTANT! That db result must contain all fields
74 * from groups table or you will have problems
77 * @param int Result set handle ("SELECT * FROM groups WHERE group_id=xx")
78 * @return a group object or false on failure
80 function &group_get_object($group_id,$res=false) {
81 //create a common set of group objects
82 //saves a little wear on the database
84 //automatically checks group_type and
85 //returns appropriate object
88 if (!isset($GROUP_OBJ["_".$group_id."_"])) {
90 //the db result handle was passed in
92 $res = db_query_params ('SELECT * FROM groups WHERE group_id=$1', array ($group_id)) ;
94 if (!$res || db_numrows($res) < 1) {
95 $GROUP_OBJ["_".$group_id."_"]=false;
98 check group type and set up object
100 if (db_result($res,0,'type_id')==1) {
102 $GROUP_OBJ["_".$group_id."_"]= new Group($group_id,$res);
105 $GROUP_OBJ["_".$group_id."_"]=false;
109 return $GROUP_OBJ["_".$group_id."_"];
112 function &group_get_objects($id_arr) {
115 // Note: if we don't do this, the result may be corrupted
119 for ($i=0; $i<count($id_arr); $i++) {
121 // See if this ID already has been fetched in the cache
126 if (!isset($GROUP_OBJ["_".$id_arr[$i]."_"])) {
127 $fetch[]=$id_arr[$i];
129 $return[] =& $GROUP_OBJ["_".$id_arr[$i]."_"];
132 if (count($fetch) > 0) {
133 $res=db_query_params ('SELECT * FROM groups WHERE group_id = ANY ($1)',
134 array (db_int_array_to_any_clause ($fetch))) ;
135 while ($arr =& db_fetch_array($res)) {
136 $GROUP_OBJ["_".$arr['group_id']."_"] = new Group($arr['group_id'],$arr);
137 $return[] =& $GROUP_OBJ["_".$arr['group_id']."_"];
143 function &group_get_object_by_name($groupname) {
144 $res=db_query_params('SELECT * FROM groups WHERE unix_group_name=$1', array ($groupname)) ;
145 return group_get_object(db_result($res,0,'group_id'),$res);
148 function &group_get_objects_by_name($groupname_arr) {
149 $res=db_query_params ('SELECT group_id FROM groups WHERE unix_group_name = ANY ($1)',
150 array (db_string_array_to_any_clause ($groupname_arr))
152 $arr =& util_result_column_to_array($res,0);
153 return group_get_objects($arr);
156 function &group_get_object_by_publicname($groupname) {
157 $res=db_query_params ('SELECT * FROM groups WHERE lower(group_name) LIKE $1',
158 array (htmlspecialchars (strtolower ($groupname)))) ;
160 return group_get_object(db_result($res,0,'group_id'),$res);
163 class Group extends Error {
165 * Associative array of data from db.
167 * @var array $data_array.
172 * array of User objects.
174 * @var array $membersArr.
179 * Whether the use is an admin/super user of this project.
181 * @var bool $is_admin.
186 * Artifact types result handle.
188 * @var int $types_res.
193 * Associative array of data for plugins.
195 * @var array $plugins_data.
201 * Associative array of data for the group menu.
203 * @var array $menu_data.
208 * Group - Group object constructor - use group_get_object() to instantiate.
210 * @param int Required - group_id of the group you want to instantiate.
211 * @param int Database result from select query OR associative array of all columns.
213 function Group($id=false, $res=false) {
216 //setting up an empty object
217 //probably going to call create()
221 if (!$this->fetchData($id)) {
226 // Assoc array was passed in
228 if (is_array($res)) {
229 $this->data_array =& $res;
231 if (db_numrows($res) < 1) {
232 //function in class we extended
233 $this->setError(_('Group Not Found'));
234 $this->data_array=array();
237 //set up an associative array for use by other functions
238 db_reset_result($res);
239 $this->data_array = db_fetch_array($res);
244 $systemGroups = array(GROUP_IS_NEWS, GROUP_IS_STATS, GROUP_IS_PEER_RATINGS);
245 if(!$this->isPublic() && !in_array($id, $systemGroups)) {
246 $perm =& $this->getPermission(session_get_user());
248 if (!$perm || !is_object($perm) || !$perm->isMember()) {
249 $this->setError(_('Permission denied'), ERROR__PERMISSION_DENIED_ERROR);
257 * fetchData - May need to refresh database fields if an update occurred.
259 * @param int The group_id.
261 function fetchData($group_id) {
262 $res = db_query_params ('SELECT * FROM groups WHERE group_id=$1',
264 if (!$res || db_numrows($res) < 1) {
265 $this->setError(sprintf(_('fetchData():: %s'),db_error()));
268 $this->data_array =& db_fetch_array($res);
273 * create - Create new group.
275 * This method should be called on empty Group object.
277 * @param object The User object.
278 * @param string The full name of the user.
279 * @param string The Unix name of the user.
280 * @param string The new group description.
281 * @param string The purpose of the group.
282 * @param bool Whether to send an email or not
284 function create(&$user, $group_name, $unix_name, $description, $purpose, $unix_box='shell1', $scm_box='cvs1', $is_public=1, $send_mail=true) {
285 // $user is ignored - anyone can create pending group
288 if ($this->getID()!=0) {
289 $this->setError(_('Group::create: Group object already exists'));
291 } else if (!$this->validateGroupName($group_name)) {
293 } else if (!account_groupnamevalid($unix_name)) {
294 $this->setError(_('Invalid Unix name'));
296 } else if (!$SYS->sysUseUnixName($unix_name)) {
297 $this->setError(_('Unix name already taken'));
299 } else if (db_numrows(db_query_params('SELECT group_id FROM groups WHERE unix_group_name=$1',
300 array ($unix_name))) > 0) {
301 $this->setError(_('Unix name already taken'));
303 } else if (strlen($purpose)<10) {
304 $this->setError(_('Please describe your Registration Purpose in a more comprehensive manner'));
306 } else if (strlen($purpose)>1500) {
307 $this->setError(_('The Registration Purpose text is too long. Please make it smaller than 1500 bytes.'));
309 } else if (strlen($description)<10) {
310 $this->setError(_('Describe in a more comprehensive manner your project.'));
312 } else if (strlen($description)>255) {
313 $this->setError(_('Your project description is too long. Please make it smaller than 256 bytes.'));
317 srand((double)microtime()*1000000);
318 $random_num = rand(0,1000000);
322 $res = db_query_params ('
338 VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13)',
339 array (htmlspecialchars ($group_name),
342 htmlspecialchars($description),
343 $unix_name.".".$GLOBALS['sys_default_domain'],
344 $unix_name.".".$GLOBALS['sys_default_domain'],
348 htmlspecialchars($purpose),
351 md5($random_num) )) ;
352 if (!$res || db_affected_rows($res) < 1) {
353 $this->setError(sprintf(_('ERROR: Could not create group: %s'),db_error()));
358 $id = db_insertid($res, 'groups', 'group_id');
360 $this->setError(sprintf(_('ERROR: Could not get group id: %s'),db_error()));
366 // Now, make the user an admin
368 $res=db_query_params ('INSERT INTO user_group (user_id, group_id, admin_flags,
369 cvs_flags, artifact_flags, forum_flags, role_id)
370 VALUES ($1, $2, $3, $4, $5, $6, $7)',
371 array ($user->getID(),
378 if (!$res || db_affected_rows($res) < 1) {
379 $this->setError(sprintf(_('ERROR: Could not add admin to newly created group: %s'),db_error()));
384 if (!$this->fetchData($id)) {
389 $hook_params = array ();
390 $hook_params['group'] = $this;
391 $hook_params['group_id'] = $this->getID();
392 $hook_params['group_name'] = $group_name;
393 $hook_params['unix_group_name'] = $unix_name;
394 plugin_hook ("group_create", $hook_params);
398 $this->sendNewProjectNotificationEmail();
406 * updateAdmin - Update core properties of group object.
408 * This function require site admin privilege.
410 * @param object User requesting operation (for access control).
411 * @param bool Whether group is publicly accessible (0/1).
412 * @param int Group type (1-project, 2-foundry).
413 * @param string Machine on which group's home directory located.
414 * @param string Domain which serves group's WWW.
418 function updateAdmin(&$user, $is_public, $type_id, $unix_box, $http_domain) {
419 $perm =& $this->getPermission($user);
421 if (!$perm || !is_object($perm)) {
422 $this->setError(_('Could not get permission.'));
426 if (!$perm->isSuperUser()) {
427 $this->setError(_('Permission denied.'));
433 $res = db_query_params ('
435 SET is_public=$1, type_id=$2,
436 unix_box=$3, http_domain=$4
444 if (!$res || db_affected_rows($res) < 1) {
445 $this->setError(_('ERROR: DB: Could not change group properties: %s'),db_error());
450 // Log the audit trail
451 if ($is_public != $this->isPublic()) {
452 $this->addHistory('is_public', $this->isPublic());
454 if ($type_id != $this->data_array['type_id']) {
455 $this->addHistory('type_id', $this->data_array['type_id']);
457 if ($unix_box != $this->data_array['unix_box']) {
458 $this->addHistory('unix_box', $this->data_array['unix_box']);
460 if ($http_domain != $this->data_array['http_domain']) {
461 $this->addHistory('http_domain', $this->data_array['http_domain']);
464 if (!$this->fetchData($this->getID())) {
473 * update - Update number of common properties.
475 * Unlike updateAdmin(), this function accessible to project admin.
477 * @param object User requesting operation (for access control).
478 * @param bool Whether group is publicly accessible (0/1).
479 * @param string Project's license (string ident).
480 * @param int Group type (1-project, 2-foundry).
481 * @param string Machine on which group's home directory located.
482 * @param string Domain which serves group's WWW.
483 * @return int status.
486 function update(&$user, $group_name,$homepage,$short_description,$use_mail,$use_survey,$use_forum,
487 $use_pm,$use_pm_depend_box,$use_scm,$use_news,$use_docman,
488 $new_doc_address,$send_all_docs,$logo_image_id,
489 $use_ftp,$use_tracker,$use_frs,$use_stats,$tags,$is_public) {
491 $perm =& $this->getPermission($user);
493 if (!$perm || !is_object($perm)) {
494 $this->setError(_('Could not get permission.'));
498 if (!$perm->isAdmin()) {
499 $this->setError(_('Permission denied.'));
503 // Validate some values
504 if ($this->getPublicName() != $group_name) {
505 if (!$this->validateGroupName($group_name)) {
510 if ($new_doc_address) {
511 $invalid_mails = validate_emails($new_doc_address);
512 if (count($invalid_mails) > 0) {
513 $this->setError(sprintf (ngettext('New Doc Address Appeared Invalid: %s', 'New Doc Addresses Appeared Invalid: %s', count($invalid_mails)),implode(',',$invalid_mails)));
518 // in the database, these all default to '1',
519 // so we have to explicity set 0
532 if (!$use_pm_depend_box) {
533 $use_pm_depend_box=0;
556 if (!$send_all_docs) {
560 $homepage = ltrim($homepage);
562 $homepage=$GLOBALS['sys_default_domain'].'/projects/'.$this->getUnixName().'/';
565 if (strlen(htmlspecialchars($short_description))>255) {
566 $this->setError(_('Error updating project information: Maximum length for Project Description is 255 chars.'));
572 //XXX not yet actived logo_image_id='$logo_image_id',
573 $res = db_query_params ('UPDATE groups
576 short_description=$3,
581 use_pm_depend_box=$8,
593 array (htmlspecialchars($group_name),
595 htmlspecialchars($short_description),
614 $this->setError(sprintf(_('Error updating project information: %s'), db_error()));
619 if ($this->setTags($tags) === false) {
624 $hook_params = array ();
625 $hook_params['group'] = $this;
626 $hook_params['group_id'] = $this->getID();
627 $hook_params['group_homepage'] = $homepage;
628 $hook_params['group_name'] = htmlspecialchars($group_name);
629 $hook_params['group_description'] = htmlspecialchars($short_description);
630 plugin_hook ("group_update", $hook_params);
632 // Log the audit trail
633 $this->addHistory('Changed Public Info', '');
635 if (!$this->fetchData($this->getID())) {
644 * getID - Simply return the group_id for this object.
646 * @return int group_id.
649 return $this->data_array['group_id'];
653 * getType() - Foundry, project, etc.
655 * @return int The type flag from the database.
658 return $this->data_array['type_id'];
663 * getStatus - the status code.
665 * Statuses char include I,H,A,D.
667 function getStatus() {
668 return $this->data_array['status'];
672 * setStatus - set the status code.
674 * Statuses include I,H,A,D.
676 * @param object User requesting operation (for access control).
677 * @param string Status value.
678 * @return boolean success.
681 function setStatus(&$user, $status) {
684 $perm =& $this->getPermission($user);
685 if (!$perm || !is_object($perm)) {
686 $this->setPermissionDeniedError();
688 } elseif (!$perm->isSuperUser()) {
689 $this->setPermissionDeniedError();
693 // Projects in 'A' status can only go to 'H' or 'D'
694 // Projects in 'D' status can only go to 'A'
695 // Projects in 'P' status can only go to 'A' OR 'D'
696 // Projects in 'I' status can only go to 'P'
697 // Projects in 'H' status can only go to 'A' OR 'D'
698 $allowed_status_changes = array(
699 'AH'=>1,'AD'=>1,'DA'=>1,'PA'=>1,'PD'=>1,
700 'IP'=>1,'HA'=>1,'HD'=>1
703 // Check that status transition is valid
704 if ($this->getStatus() != $status
705 && !$allowed_status_changes[$this->getStatus().$status]) {
706 $this->setError(_('Invalid Status Change'));
712 $res = db_query_params ('UPDATE groups
714 WHERE group_id=$2', array ($status, $this->getID())) ;
716 if (!$res || db_affected_rows($res) < 1) {
717 $this->setError(sprintf(_('ERROR: DB: Could not change group status: %s'),db_error()));
723 // Activate system group, if not yet
724 if (!$SYS->sysCheckGroup($this->getID())) {
725 if (!$SYS->sysCreateGroup($this->getID())) {
726 $this->setError($SYS->getErrorMessage());
731 if (!$this->activateUsers()) {
736 /* Otherwise, the group is not active, and make sure that
737 System group is not active either */
738 } else if ($SYS->sysCheckGroup($this->getID())) {
739 if (!$SYS->sysRemoveGroup($this->getID())) {
740 $this->setError($SYS->getErrorMessage());
746 $hook_params = array ();
747 $hook_params['group'] = $this;
748 $hook_params['group_id'] = $this->getID();
749 $hook_params['status'] = $status;
750 plugin_hook ("group_setstatus", $hook_params);
754 // Log the audit trail
755 if ($status != $this->getStatus()) {
756 $this->addHistory('Status', $this->getStatus());
759 $this->data_array['status'] = $status;
764 * isProject - Simple boolean test to see if it's a project or not.
766 * @return boolean is_project.
768 function isProject() {
769 if ($this->getType()==1) {
777 * isPublic - Simply returns the is_public flag from the database.
779 * @return boolean is_public.
781 function isPublic() {
782 return $this->data_array['is_public'];
786 * isActive - Database field status of 'A' returns true.
788 * @return boolean is_active.
790 function isActive() {
791 if ($this->getStatus()=='A') {
799 * getUnixName - the unix_name
801 * @return string unix_name.
803 function getUnixName() {
804 return strtolower($this->data_array['unix_group_name']);
808 * getPublicName - the full-length public name.
810 * @return string The group_name.
812 function getPublicName() {
813 return $this->data_array['group_name'];
817 * getRegisterPurpose - the text description of the purpose of this project.
819 * @return string The description.
821 function getRegisterPurpose() {
822 return $this->data_array['register_purpose'];
826 * getDescription - the text description of this project.
828 * @return string The description.
830 function getDescription() {
831 return $this->data_array['short_description'];
835 * getStartDate - the unix time this project was registered.
837 * @return int (unix time) of registration.
839 function getStartDate() {
840 return $this->data_array['register_time'];
844 * getLogoImageID - the id of the logo in the database for this project.
846 * @return int The ID of logo image in db_images table (or 100 if none).
848 function getLogoImageID() {
849 return $this->data_array['logo_image_id'];
853 * getUnixBox - the hostname of the unix box where this project is located.
855 * @return string The name of the unix machine for the group.
857 function getUnixBox() {
858 return $this->data_array['unix_box'];
862 * getSCMBox - the hostname of the scm box where this project is located.
864 * @return string The name of the unix machine for the group.
866 function getSCMBox() {
867 return $this->data_array['scm_box'];
870 * setSCMBox - the hostname of the scm box where this project is located.
872 * @param string The name of the new SCM_BOX
874 function setSCMBox($scm_box) {
877 $res = db_query_params ('UPDATE groups SET scm_box=$1 WHERE group_id=$2', array ($scm_box, $this->getID ()));
879 $this->addHistory('scm_box', $this->data_array['scm_box']);
880 $this->data_array['scm_box']=$scm_box;
885 $this->setError(_("Couldn't insert SCM_BOX to database"));
889 $this->setError(_("SCM Box can't be empty"));
895 * getDomain - the hostname.domain where their web page is located.
897 * @return string The name of the group [web] domain.
899 function getDomain() {
900 return $this->data_array['http_domain'];
904 * getLicense - the license they chose.
906 * @return int ident of group license.
908 function getLicense() {
909 return $this->data_array['license'];
913 * getLicenseName - the name of the license
915 * @return string license name
917 function getLicenseName() {
918 $licenses =& group_get_licenses();
919 if(isset($licenses[$this->data_array['license']])) {
920 return $licenses[$this->data_array['license']];
927 * getLicenseOther - optional string describing license.
929 * @return string The custom license.
931 function getLicenseOther() {
932 if ($this->getLicense() == GROUP_LICENSE_OTHER) {
933 return $this->data_array['license_other'];
940 * getRegistrationPurpose - the text description of the purpose of this project.
942 * @return string The application for project hosting.
944 function getRegistrationPurpose() {
945 return $this->data_array['register_purpose'];
950 * getAdmins() - Get array of Admin user objects.
952 * @return array Array of User objects.
954 function &getAdmins() {
955 // this function gets all group admins in order to send Jabber and mail messages
956 $res = db_query_params ('SELECT user_id FROM user_group WHERE admin_flags=$1 AND group_id=$2',
957 array ('A', $this->getID()));
958 $user_ids=util_result_column_to_array($res);
959 return user_get_objects($user_ids);
964 Common Group preferences for tools
969 * enableAnonSCM - whether or not this group has opted to enable Anonymous SCM.
971 * @return boolean enable_scm.
973 function enableAnonSCM() {
974 if ($this->isPublic() && $this->usesSCM()) {
975 return $this->data_array['enable_anonscm'];
981 function SetUsesAnonSCM ($booleanparam) {
983 $booleanparam = $booleanparam ? 1 : 0 ;
984 $res = db_query_params ('UPDATE groups SET enable_anonscm=$1 WHERE group_id=$2',
985 array ($booleanparam, $this->getID()));
987 $this->data_array['enable_anonscm']=$booleanparam;
995 function setUsesSCM ($booleanparam) {
997 $booleanparam = $booleanparam ? 1 : 0 ;
998 $res = db_query_params ('UPDATE groups SET use_scm=$1 WHERE group_id=$2',
999 array ($booleanparam, $this->getID()));
1001 $this->data_array['use_scm']=$booleanparam;
1010 * enablePserver - whether or not this group has opted to enable Pserver.
1012 * @return boolean enable_pserver.
1014 function enablePserver() {
1015 if ($this->usesSCM()) {
1016 return $this->data_array['enable_pserver'];
1022 function SetUsesPserver ($booleanparam) {
1024 $booleanparam = $booleanparam ? 1 : 0 ;
1025 $res = db_query_params ('UPDATE groups SET enable_pserver=$1 WHERE group_id=$2',
1026 array ($booleanparam, $this->getID()));
1028 $this->data_array['enable_pserver']=$booleanparam;
1037 * usesSCM - whether or not this group has opted to use SCM.
1039 * @return boolean uses_scm.
1041 function usesSCM() {
1042 global $sys_use_scm;
1044 return $this->data_array['use_scm'];
1051 * usesMail - whether or not this group has opted to use mailing lists.
1053 * @return boolean uses_mail.
1055 function usesMail() {
1056 global $sys_use_mail;
1057 if ($sys_use_mail) {
1058 return $this->data_array['use_mail'];
1065 * usesNews - whether or not this group has opted to use news.
1067 * @return boolean uses_news.
1069 function usesNews() {
1070 global $sys_use_news;
1071 if ($sys_use_news) {
1072 return $this->data_array['use_news'];
1079 * usesForum - whether or not this group has opted to use discussion forums.
1081 * @return boolean uses_forum.
1083 function usesForum() {
1084 global $sys_use_forum;
1085 if ($sys_use_forum) {
1086 return $this->data_array['use_forum'];
1093 * usesStats - whether or not this group has opted to use stats.
1095 * @return boolean uses_stats.
1097 function usesStats() {
1098 return $this->data_array['use_stats'];
1102 * usesFRS - whether or not this group has opted to use file release system.
1104 * @return boolean uses_frs.
1106 function usesFRS() {
1107 global $sys_use_frs;
1109 return $this->data_array['use_frs'];
1116 * usesTracker - whether or not this group has opted to use tracker.
1118 * @return boolean uses_tracker.
1120 function usesTracker() {
1121 global $sys_use_tracker;
1122 if ($sys_use_tracker) {
1123 return $this->data_array['use_tracker'];
1130 * usesDocman - whether or not this group has opted to use docman.
1132 * @return boolean uses_docman.
1134 function usesDocman() {
1135 global $sys_use_docman;
1136 if ($sys_use_docman) {
1137 return $this->data_array['use_docman'];
1144 * usesFTP - whether or not this group has opted to use FTP.
1146 * @return boolean uses_ftp.
1148 function usesFTP() {
1149 global $sys_use_ftp;
1151 return $this->data_array['use_ftp'];
1158 * usesSurvey - whether or not this group has opted to use surveys.
1160 * @return boolean uses_survey.
1162 function usesSurvey() {
1163 global $sys_use_survey;
1164 if ($sys_use_survey) {
1165 return $this->data_array['use_survey'];
1172 * usesPM - whether or not this group has opted to Project Manager.
1174 * @return boolean uses_projman.
1179 return $this->data_array['use_pm'];
1186 * getPlugins - get a list of all available group plugins
1188 * @return array array containing plugin_id => plugin_name
1190 function getPlugins() {
1191 if (!isset($this->plugins_data)) {
1192 $this->plugins_data = array () ;
1193 $res = db_query_params ('SELECT group_plugin.plugin_id, plugins.plugin_name
1194 FROM group_plugin, plugins
1195 WHERE group_plugin.group_id=$1
1196 AND group_plugin.plugin_id=plugins.plugin_id', array ($this->getID()));
1197 $rows = db_numrows($res);
1199 for ($i=0; $i<$rows; $i++) {
1200 $plugin_id = db_result($res,$i,'plugin_id');
1201 $this->plugins_data[$plugin_id] = db_result($res,$i,'plugin_name');
1204 return $this->plugins_data ;
1208 * usesPlugin - returns true if the group uses a particular plugin
1210 * @param string name of the plugin
1211 * @return boolean whether plugin is being used or not
1213 function usesPlugin($pluginname) {
1214 $plugins_data = $this->getPlugins() ;
1215 foreach ($plugins_data as $p_id => $p_name) {
1216 if ($p_name == $pluginname) {
1224 * setPluginUse - enables/disables plugins for the group
1226 * @param string name of the plugin
1227 * @param boolean the new state
1228 * @return string database result
1230 function setPluginUse($pluginname, $val=true) {
1231 if ($val == $this->usesPlugin($pluginname)) {
1232 // State is already good, returning
1235 $res = db_query_params ('SELECT plugin_id FROM plugins WHERE plugin_name=$1',
1236 array ($pluginname));
1237 $rows = db_numrows($res);
1239 // Error: no plugin by that name
1242 $plugin_id = db_result($res,0,'plugin_id');
1244 unset ($this->plugins_data) ;
1246 $res = db_query_params ('INSERT INTO group_plugin (group_id, plugin_id) VALUES ($1, $2)',
1247 array ($this->getID(),
1251 $res = db_query_params ('DELETE FROM group_plugin WHERE group_id=$1 AND plugin_id=$2',
1252 array ($this->getID(),
1259 * getDocEmailAddress - get email address(es) to send doc notifications to.
1261 * @return string email address.
1263 function getDocEmailAddress() {
1264 return $this->data_array['new_doc_address'];
1268 * DocEmailAll - whether or not this group has opted to use receive notices on all doc updates.
1270 * @return boolean email_on_all_doc_updates.
1272 function docEmailAll() {
1273 return $this->data_array['send_all_docs'];
1278 * getHomePage - The URL for this project's home page.
1280 * @return string homepage URL.
1282 function getHomePage() {
1283 return $this->data_array['homepage'];
1287 * getTags - Tags of this project.
1289 * @return string List of tags.
1291 function getTags() {
1292 $sql = 'SELECT name FROM project_tags WHERE group_id = $1';
1293 $res = db_query_params($sql, array($this->getID()));
1294 return join(', ', util_result_column_to_array($res));
1298 * setTags - Set tags of this project.
1300 * @return string database result.
1302 function setTags($tags) {
1304 $sql='DELETE FROM project_tags WHERE group_id=$1';
1305 $res=db_query_params($sql, array($this->getID()));
1307 $this->setError('Deleting old tags: '.db_error());
1311 $inserted = array();
1312 $tags_array = split('[;,]', $tags);
1313 foreach ($tags_array as $tag) {
1314 $tag = stripslashes($tag);
1315 $tag = preg_replace('/[\t\r\n]/', ' ', $tag);
1316 // Allowed caracteres: [A-Z][a-z][0-9] -_&'#+.
1317 if (preg_match('/[^[:alnum:]| |\-|_|\&|\'|#|\+|\.]/', $tag)) {
1318 $this->setError(_('Bad tag name, you only can use the following characters: [A-Z][a-z][0-9]-_&\'#+. and space'));
1323 $tag = addslashes($tag);
1324 if ($tag == '' || array_search($tag, $inserted) !== false) continue;
1325 $sql='INSERT INTO project_tags (group_id,name) VALUES ($1, $2)';
1326 $res=db_query_params($sql, array($this->getID(), $tag));
1328 $this->setError(_('Setting tags: ').db_error());
1339 * getPermission - Return a Permission for this Group and the specified User.
1341 * @param object The user you wish to get permission for (usually the logged in user).
1342 * @return object The Permission.
1344 function &getPermission(&$_user) {
1345 return permission_get_object($this, $_user);
1350 * userIsAdmin - Return if for this Group the User is admin.
1352 * @return boolean is_admin.
1354 function userIsAdmin() {
1355 $perm =& $this->getPermission( session_get_user() );
1356 if (!$perm || !is_object($perm)) {
1358 } elseif ($perm->isError()) {
1361 return $perm->isAdmin();
1364 function delete($sure,$really_sure,$really_really_sure) {
1365 if (!$sure || !$really_sure || !$really_really_sure) {
1366 $this->setMissingParamsError();
1369 if ($this->getID() == $GLOBALS['sys_news_group'] ||
1370 $this->getID() == 1 ||
1371 $this->getID() == $GLOBALS['sys_stats_group'] ||
1372 $this->getID() == $GLOBALS['sys_peer_rating_group']) {
1373 $this->setError(_('Cannot Delete System Group'));
1376 $perm =& $this->getPermission( session_get_user() );
1377 if (!$perm || !is_object($perm)) {
1378 $this->setPermissionDeniedError();
1380 } elseif ($perm->isError()) {
1381 $this->setPermissionDeniedError();
1383 } elseif (!$perm->isSuperUser()) {
1384 $this->setPermissionDeniedError();
1390 // Remove all the members
1392 $members =& $this->getMembers();
1393 for ($i=0; $i<count($members); $i++) {
1394 $this->removeUser($members[$i]->getID());
1399 $atf = new ArtifactTypeFactory($this);
1400 $at_arr =& $atf->getArtifactTypes();
1401 for ($i=0; $i<count($at_arr); $i++) {
1402 if (!is_object($at_arr[$i])) {
1403 printf (_("Not Object: ArtifactType: %d"),$i);
1406 $at_arr[$i]->delete(1,1);
1411 $ff = new ForumFactory($this);
1412 $f_arr =& $ff->getForums();
1413 for ($i=0; $i<count($f_arr); $i++) {
1414 if (!is_object($f_arr[$i])) {
1415 printf (_("Not Object: Forum: %d"),$i);
1418 $f_arr[$i]->delete(1,1);
1419 //echo 'ForumFactory'.db_error();
1422 // Delete Subprojects
1424 $pgf = new ProjectGroupFactory($this);
1425 $pg_arr =& $pgf->getProjectGroups();
1426 for ($i=0; $i<count($pg_arr); $i++) {
1427 if (!is_object($pg_arr[$i])) {
1428 printf (_("Not Object: ProjectGroup: %d"),$i);
1431 $pg_arr[$i]->delete(1,1);
1432 //echo 'ProjectGroupFactory'.db_error();
1435 // Delete FRS Packages
1437 //$frspf = new FRSPackageFactory($this);
1438 $res = db_query_params ('SELECT * FROM frs_package WHERE group_id=$1',
1439 array ($this->getID())) ;
1440 //echo 'frs_package'.db_error();
1441 //$frsp_arr =& $frspf->getPackages();
1442 while ($arr = db_fetch_array($res)) {
1443 //if (!is_object($pg_arr[$i])) {
1444 // echo "Not Object: ProjectGroup: ".$i;
1447 $frsp=new FRSPackage($this,$arr['package_id'],$arr);
1453 $news_group=&group_get_object($GLOBALS['sys_news_group']);
1454 $res = db_query_params ('SELECT forum_id FROM news_bytes WHERE group_id=$1',
1455 array ($this->getID())) ;
1456 for ($i=0; $i<db_numrows($res); $i++) {
1457 $Forum = new Forum($news_group,db_result($res,$i,'forum_id'));
1458 if (!$Forum->delete(1,1)) {
1459 printf (_("Could Not Delete News Forum: %d"),$Forum->getID());
1462 $res = db_query_params ('DELETE FROM news_bytes WHERE group_id=$1',
1463 array ($this->getID())) ;
1468 $res = db_query_params ('DELETE FROM doc_data WHERE group_id=$1',
1469 array ($this->getID())) ;
1470 //echo 'doc_data'.db_error();
1471 $res = db_query_params ('DELETE FROM doc_groups WHERE group_id=$1',
1472 array ($this->getID())) ;
1473 //echo 'doc_groups'.db_error();
1478 $res=db_query_params('DELETE FROM project_tags WHERE group_id=$1', array($this->getID()));
1481 // Delete group history
1483 $res = db_query_params ('DELETE FROM group_history WHERE group_id=$1',
1484 array ($this->getID())) ;
1485 //echo 'group_history'.db_error();
1487 // Delete group plugins
1489 $res = db_query_params ('DELETE FROM group_plugin WHERE group_id=$1',
1490 array ($this->getID())) ;
1491 //echo 'group_plugin'.db_error();
1493 // Delete group cvs stats
1495 $res = db_query_params ('DELETE FROM stats_cvs_group WHERE group_id=$1',
1496 array ($this->getID())) ;
1497 //echo 'stats_cvs_group'.db_error();
1501 $sf = new SurveyFactory($this);
1502 $s_arr =& $sf->getSurveys();
1503 for ($i=0; $i<count($s_arr); $i++) {
1504 if (!is_object($s_arr[$i])) {
1505 printf (_("Not Object: Survey: %d"),$i);
1508 $s_arr[$i]->delete();
1509 //echo 'SurveyFactory'.db_error();
1512 // Delete SurveyQuestions
1514 $sqf = new SurveyQuestionFactory($this);
1515 $sq_arr =& $sqf->getSurveyQuestions();
1516 for ($i=0; $i<count($sq_arr); $i++) {
1517 if (!is_object($sq_arr[$i])) {
1518 printf (_("Not Object: SurveyQuestion: %d"),$i);
1521 $sq_arr[$i]->delete();
1522 //echo 'SurveyQuestionFactory'.db_error();
1525 // Delete Mailing List Factory
1527 $mlf = new MailingListFactory($this);
1528 $ml_arr =& $mlf->getMailingLists();
1529 for ($i=0; $i<count($ml_arr); $i++) {
1530 if (!is_object($ml_arr[$i])) {
1531 printf (_("Not Object: MailingList: %d"),$i);
1534 if (!$ml_arr[$i]->delete(1,1)) {
1535 $this->setError(_('Could not properly delete the mailing list'));
1537 //echo 'MailingListFactory'.db_error();
1542 $res = db_query_params ('DELETE FROM trove_group_link WHERE group_id=$1',
1543 array ($this->getID())) ;
1544 $res = db_query_params ('DELETE FROM trove_agg WHERE group_id=$1',
1545 array ($this->getID())) ;
1549 $res = db_query_params ('DELETE FROM project_sums_agg WHERE group_id=$1',
1550 array ($this->getID())) ;
1551 //echo 'project_sums_agg'.db_error();
1552 $res = db_query_params ('INSERT INTO deleted_groups (unix_group_name,delete_date,isdeleted) VALUES ($1, $2, $3)',
1553 array ($this->getUnixName(),
1556 //echo 'InsertIntoDeleteQueue'.db_error();
1557 $res = db_query_params ('DELETE FROM groups WHERE group_id=$1',
1558 array ($this->getID())) ;
1559 //echo 'DeleteGroup'.db_error();
1565 $hook_params = array ();
1566 $hook_params['group'] = $this;
1567 $hook_params['group_id'] = $this->getID();
1568 plugin_hook ("group_delete", $hook_params);
1570 if (isset($GLOBALS['sys_upload_dir']) && $this->getUnixName()) {
1571 exec('/bin/rm -rf '.$GLOBALS['sys_upload_dir'].'/'.$this->getUnixName().'/');
1573 if (isset($GLOBALS['sys_ftp_upload_dir']) && $this->getUnixName()) {
1574 exec('/bin/rm -rf '.$GLOBALS['sys_ftp_upload_dir'].'/'.$this->getUnixName().'/');
1579 $res = db_query_params ('DELETE FROM rep_group_act_monthly WHERE group_id=$1',
1580 array ($this->getID())) ;
1581 //echo 'rep_group_act_monthly'.db_error();
1582 $res = db_query_params ('DELETE FROM rep_group_act_weekly WHERE group_id=$1',
1583 array ($this->getID())) ;
1584 //echo 'rep_group_act_weekly'.db_error();
1585 $res = db_query_params ('DELETE FROM rep_group_act_daily WHERE group_id=$1',
1586 array ($this->getID())) ;
1587 //echo 'rep_group_act_daily'.db_error();
1588 unset($this->data_array);
1596 Basic functions to add/remove users to/from a group
1597 and update their permissions
1603 * addUser - controls adding a user to a group.
1605 * @param string Unix name of the user to add OR integer user_id.
1606 * @param int The role_id this user should have.
1607 * @return boolean success.
1610 function addUser($user_identifier,$role_id) {
1613 Admins can add users to groups
1616 $perm =& $this->getPermission( session_get_user() );
1617 if (!$perm || !is_object($perm) || !$perm->isAdmin()) {
1618 $this->setPermissionDeniedError();
1624 get user id for this user's unix_name
1626 if (is_int ($user_identifier)) { // user_id or user_name
1627 $res_newuser = db_query_params ('SELECT * FROM users WHERE user_id=$1', array ($user_identifier)) ;
1629 $res_newuser = db_query_params ('SELECT * FROM users WHERE user_name=$1', array ($user_identifier)) ;
1631 if (db_numrows($res_newuser) > 0) {
1633 // make sure user is active
1635 if (db_result($res_newuser,0,'status') != 'A') {
1636 $this->setError(_('User is not active. Only active users can be added.'));
1642 // user was found - set new user_id var
1644 $user_id = db_result($res_newuser,0,'user_id');
1647 // if not already a member, add them
1649 $res_member = db_query_params ('SELECT user_id
1651 WHERE user_id=$1 AND group_id=$2',
1652 array ($user_id, $this->getID())) ;
1654 if (db_numrows($res_member) < 1) {
1656 // Create this user's row in the user_group table
1658 $res = db_query_params ('INSERT INTO user_group
1659 (user_id,group_id,admin_flags,forum_flags,project_flags,
1660 doc_flags,cvs_flags,member_role,release_flags,artifact_flags)
1661 VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10)',
1673 //verify the insert worked
1674 if (!$res || db_affected_rows($res) < 1) {
1675 $this->setError(sprintf(_('ERROR: Could Not Add User To Group: %s'),db_error()));
1680 // check and create if group doesn't exists
1682 //echo "<h2>Group::addUser SYS->sysCheckCreateGroup(".$this->getID().")</h2>";
1683 if (!$SYS->sysCheckCreateGroup($this->getID())){
1684 $this->setError($SYS->getErrorMessage());
1689 // check and create if user doesn't exists
1691 //echo "<h2>Group::addUser SYS->sysCheckCreateUser($user_id)</h2>";
1692 if (!$SYS->sysCheckCreateUser($user_id)) {
1693 $this->setError($SYS->getErrorMessage());
1700 $role = new Role($this,$role_id);
1701 if (!$role || !is_object($role)) {
1702 $this->setError(_('Error Getting Role Object'));
1705 } elseif ($role->isError()) {
1706 $this->setError('addUser::roleget::'.$role->getErrorMessage());
1710 //echo "<h2>Group::addUser role->setUser($user_id)</h2>";
1711 if (!$role->setUser($user_id)) {
1712 $this->setError('addUser::role::setUser'.$role->getErrorMessage());
1718 // user was already a member
1719 // make sure they are set up
1721 $user=&user_get_object($user_id,$res_newuser);
1722 $user->fetchData($user->getID());
1723 $role = new Role($this,$role_id);
1724 if (!$role || !is_object($role)) {
1725 $this->setError(_('Error Getting Role Object'));
1728 } elseif ($role->isError()) {
1729 $this->setError('addUser::roleget::'.$role->getErrorMessage());
1733 //echo "<h2>Already Member Group::addUser role->setUser($user_id)</h2>";
1734 if (!$role->setUser($user_id)) {
1735 $this->setError('addUser::role::setUser'.$role->getErrorMessage());
1740 // set up their system info
1742 //echo "<h2>Already Member Group::addUser SYS->sysCheckCreateUser($user_id)</h2>";
1743 if (!$SYS->sysCheckCreateUser($user_id)) {
1744 $this->setError($SYS->getErrorMessage());
1751 // user doesn't exist
1753 $this->setError(_('ERROR: User does not exist'));
1758 $hook_params['group'] = $this;
1759 $hook_params['group_id'] = $this->getID();
1760 $hook_params['user'] = &user_get_object($user_id);
1761 $hook_params['user_id'] = $user_id;
1762 plugin_hook ("group_adduser", $hook_params);
1767 $this->addHistory('Added User',$user_identifier);
1773 * removeUser - controls removing a user from a group.
1775 * Users can remove themselves.
1777 * @param int The ID of the user to remove.
1778 * @return boolean success.
1780 function removeUser($user_id) {
1781 global $SYS,$sys_database_type;
1783 if ($user_id==user_getid()) {
1784 //users can remove themselves
1785 //everyone else must be a project admin
1787 $perm =& $this->getPermission( session_get_user() );
1789 if (!$perm || !is_object($perm) || !$perm->isAdmin()) {
1790 $this->setPermissionDeniedError();
1796 $res = db_query_params ('DELETE FROM user_group WHERE group_id=$1 AND user_id=$2',
1797 array ($this->getID(),
1799 if (!$res || db_affected_rows($res) < 1) {
1800 $this->setError(sprintf(_('ERROR: User not removed: %s'),db_error()));
1805 // reassign open artifacts to id=100
1807 $res = db_query_params ('UPDATE artifact SET assigned_to=100
1808 WHERE group_artifact_id
1809 IN (SELECT group_artifact_id
1810 FROM artifact_group_list
1811 WHERE group_id=$1 AND status_id=1 AND assigned_to=$2)',
1812 array ($this->getID(),
1815 $this->setError(sprintf(_('ERROR: DB: artifact: %s'),db_error()));
1821 // reassign open tasks to id=100
1822 // first have to purge any assignments that would cause
1823 // conflict with existing assignment to 100
1825 if ($sys_database_type == 'mysql') {
1827 SELECT pt.project_task_id
1828 FROM project_task pt, project_group_list pgl, project_assigned_to pat
1829 WHERE pt.group_project_id = pgl.group_project_id
1830 AND pat.project_task_id=pt.project_task_id
1831 AND pt.status_id='1' AND pgl.group_id='".$this->getID()."'
1832 AND pat.assigned_to_id='$user_id' INTO @task_list;
1833 DELETE FROM project_assigned_to WHERE project_task_id IN ( @task_list ) AND assigned_to_id='100'");
1835 $res = db_next_result();
1838 $res = db_query_params ('DELETE FROM project_assigned_to
1839 WHERE project_task_id IN (SELECT pt.project_task_id
1840 FROM project_task pt, project_group_list pgl, project_assigned_to pat
1841 WHERE pt.group_project_id = pgl.group_project_id
1842 AND pat.project_task_id=pt.project_task_id
1843 AND pt.status_id=1 AND pgl.group_id=$1
1844 AND pat.assigned_to_id=$2)
1845 AND assigned_to_id=100',
1846 array ($this->getID(),
1850 $this->setError(sprintf(_('ERROR: DB: project_assigned_to %d: %s'),1,db_error()));
1854 $res = db_query_params ('UPDATE project_assigned_to SET assigned_to_id=100
1855 WHERE project_task_id IN (SELECT pt.project_task_id
1856 FROM project_task pt, project_group_list pgl
1857 WHERE pt.group_project_id = pgl.group_project_id
1858 AND pt.status_id=1 AND pgl.group_id=$1)
1859 AND assigned_to_id=$2',
1860 array ($this->getID(),
1863 $this->setError(sprintf(_('ERROR: DB: project_assigned_to %d: %s'),2,db_error()));
1869 // Remove user from system
1871 //echo "<h2>Group::addUser SYS->sysGroupRemoveUser(".$this->getID().",$user_id)</h2>";
1872 if (!$SYS->sysGroupRemoveUser($this->getID(),$user_id)) {
1873 $this->setError($SYS->getErrorMessage());
1878 $hook_params['group'] = $this;
1879 $hook_params['group_id'] = $this->getID();
1880 $hook_params['user'] = &user_get_object($user_id);
1881 $hook_params['user_id'] = $user_id;
1882 plugin_hook ("group_removeuser", $hook_params);
1885 $this->addHistory('Removed User',$user_id);
1892 * updateUser - controls updating a user's role in this group.
1894 * @param int The ID of the user.
1895 * @param int The role_id to set this user to.
1896 * @return boolean success.
1898 function updateUser($user_id,$role_id) {
1901 $perm =& $this->getPermission( session_get_user() );
1902 if (!$perm || !is_object($perm) || !$perm->isAdmin()) {
1903 $this->setPermissionDeniedError();
1907 $role = new Role($this,$role_id);
1908 if (!$role || !is_object($role)) {
1909 $this->setError(_('Could Not Get Role'));
1911 } elseif ($role->isError()) {
1912 $this->setError(sprintf(_('Role: %s'),$role->getErrorMessage()));
1915 //echo "<h3>Group::updateUser role->setUser($user_id)</h3>";
1916 if (!$role->setUser($user_id)) {
1917 $this->setError(sprintf(_('Role: %s'),$role->getErrorMessage()));
1922 $this->addHistory('Updated User',$user_id);
1927 * addHistory - Makes an audit trail entry for this project.
1929 * @param string The name of the field.
1930 * @param string The Old Value for this $field_name.
1931 * @return database result handle.
1934 function addHistory($field_name, $old_value) {
1935 return db_query_params ('INSERT INTO group_history(group_id,field_name,old_value,mod_by,adddate)
1936 VALUES ($1,$2,$3,$4,$5)',
1937 array ($this->getID(),
1945 * activateUsers - Make sure that group members have unix accounts.
1947 * Setup unix accounts for group members. Can be called even
1948 * if members are already active.
1952 function activateUsers() {
1955 Activate member(s) of the project
1958 $member_res = db_query_params ('SELECT user_id, role_id FROM user_group WHERE group_id=$1',
1959 array ($this->getID())) ;
1961 $rows = db_numrows($member_res);
1965 for ($i=0; $i<$rows; $i++) {
1967 $member =& user_get_object(db_result($member_res,$i,'user_id'));
1968 $roleId = db_result($member_res,$i,'role_id');
1970 if (!$member || !is_object($member)) {
1971 $this->setError(_('Error getting member object'));
1973 } else if ($member->isError()) {
1974 $this->setError(sprintf(_('Error getting member object: %s'),$member->getErrorMessage()));
1978 if (!$this->addUser($member->getUnixName(),$roleId)) {
1989 * getMembers - returns array of User objects for this project
1991 * @return array of User objects for this group.
1993 function &getMembers() {
1994 if (!isset($this->membersArr)) {
1995 $res = db_query_params ('SELECT users.* FROM users INNER JOIN user_group ON users.user_id=user_group.user_id WHERE user_group.group_id=$1',
1996 array ($this->getID())) ;
1997 while ($arr =& db_fetch_array($res)) {
1998 $this->membersArr[] =& new GFUser($arr['user_id'],$arr);
2001 return $this->membersArr;
2005 * approve - Approve pending project.
2007 * @param object The User object who is doing the updating.
2010 function approve(&$user) {
2012 if ($this->getStatus()=='A') {
2013 $this->setError(_("Group already active"));
2019 // Step 1: Activate group and create LDAP entries
2020 if (!$this->setStatus($user, 'A')) {
2025 // Switch to system language for item creation
2026 setup_gettext_from_sys_lang ();
2031 // Tracker Integration
2034 $ats = new ArtifactTypes($this);
2035 if (!$ats || !is_object($ats)) {
2036 $this->setError(_('Error creating ArtifactTypes object'));
2038 setup_gettext_from_context();
2040 } else if ($ats->isError()) {
2041 $this->setError(sprintf (_('ATS%d: %s'), 1, $ats->getErrorMessage()));
2043 setup_gettext_from_context();
2046 if (!$ats->createTrackers()) {
2047 $this->setError(sprintf (_('ATS%d: %s'), 2, $ats->getErrorMessage()));
2049 setup_gettext_from_context();
2055 // Forum Integration
2058 $f = new Forum($this);
2059 if (!$f->create(_('Open-Discussion'),_('General Discussion'),1,'',1,0)) {
2060 $this->setError(sprintf (_('F%d: %s'), 1, $f->getErrorMessage()));
2062 setup_gettext_from_context();
2065 $f = new Forum($this);
2066 if (!$f->create(_('Help'),_('Get Public Help'),1,'',1,0)) {
2067 $this->setError(sprintf (_('F%d: %s'), 2, $f->getErrorMessage()));
2069 setup_gettext_from_context();
2072 $f = new Forum($this);
2073 if (!$f->create(_('Developers-Discussion'),_('Project Developer Discussion'),0,'',1,0)) {
2074 $this->setError(sprintf (_('F%d: %s'), 3, $f->getErrorMessage()));
2076 setup_gettext_from_context();
2082 // Doc Mgr Integration
2085 $dg = new DocumentGroup($this);
2086 if (!$dg->create(_('Uncategorized Submissions'))) {
2087 $this->setError(sprintf(_('DG: %s'),$dg->getErrorMessage()));
2089 setup_gettext_from_context();
2098 $frs = new FRSPackage($this);
2099 if (!$frs->create($this->getUnixName())) {
2100 $this->setError(sprintf(_('FRSP: %s'),$frs->getErrorMessage()));
2102 setup_gettext_from_context();
2111 $pg = new ProjectGroup($this);
2112 if (!$pg->create(_('To Do'),_('Things We Have To Do'),1)) {
2113 $this->setError(sprintf(_('PG%d: %s'),1,$pg->getErrorMessage()));
2115 setup_gettext_from_context();
2118 $pg = new ProjectGroup($this);
2119 if (!$pg->create(_('Next Release'),_('Items For Our Next Release'),1)) {
2120 $this->setError(sprintf(_('PG%d: %s'),2,$pg->getErrorMessage()));
2122 setup_gettext_from_context();
2128 // Set Default Roles
2132 $admin_group = db_query_params ('SELECT user_id FROM user_group WHERE group_id=$1 AND admin_flags=$2',
2133 array ($this->getID(),
2135 if (db_numrows($admin_group) > 0) {
2136 $idadmin_group = db_result($admin_group,0,'user_id');
2138 $idadmin_group = $user->getID();
2139 db_query_params ('INSERT INTO user_group (user_id, group_id, admin_flags) VALUES ($1, $2, $3)',
2140 array ($idadmin_group,
2145 $role = new Role($this);
2146 $todo = array_keys($role->defaults);
2147 for ($c=0; $c<count($todo); $c++) {
2148 $role = new Role($this);
2149 if (! ($role_id = $role->createDefault($todo[$c]))) {
2150 $this->setError(sprintf(_('R%d: %s'),$c,$role->getErrorMessage()));
2152 setup_gettext_from_context();
2155 $role = new Role($this, $role_id);
2156 if ($role->getVal('projectadmin',0)=='A') {
2157 $role->setUser($idadmin_group);
2164 // Create MailingList
2167 if ($GLOBALS['sys_use_mail']) {
2168 $mlist = new MailingList($this);
2169 if (!$mlist->create('commits',_('Commits'),1,$idadmin_group)) {
2170 $this->setError(sprintf(_('ML: %s'),$mlist->getErrorMessage()));
2172 setup_gettext_from_context();
2177 // Switch back to user preference
2178 setup_gettext_from_context();
2182 $this->sendApprovalEmail();
2183 $this->addHistory('Approved', 'x');
2186 // Plugin can make approve operation there
2189 $params[0] = $idadmin_group ;
2190 $params[1] = $this->getID();
2191 plugin_hook('group_approve',$params);
2199 * sendApprovalEmail - Send new project email.
2201 * @return boolean success.
2204 function sendApprovalEmail() {
2205 $res_admins = db_query_params ('
2206 SELECT users.user_name,users.email,users.language,users.user_id
2207 FROM users,user_group
2208 WHERE users.user_id=user_group.user_id
2209 AND user_group.group_id=$1
2210 AND user_group.admin_flags=$2',
2211 array ($this->getID(),
2214 if (db_numrows($res_admins) < 1) {
2215 $this->setError(_("Group does not have any administrators."));
2219 // send one email per admin
2220 while ($row_admins = db_fetch_array($res_admins)) {
2221 $admin =& user_get_object($row_admins['user_id']);
2222 setup_gettext_for_user ($admin) ;
2224 $message=sprintf(_('Your project registration for %4$s has been approved.
2226 Project Full Name: %1$s
2227 Project Unix Name: %2$s
2229 Your DNS will take up to a day to become active on our site.
2230 Your web site is accessible through your shell account. Please read
2231 site documentation (see link below) about intended usage, available
2232 services, and directory layout of the account.
2235 own project page in %4$s while logged in, you will find
2236 additional menu functions to your left labeled \'Project Admin\'.
2238 We highly suggest that you now visit %4$s and create a public
2239 description for your project. This can be done by visiting your project
2240 page while logged in, and selecting \'Project Admin\' from the menus
2241 on the left (or by visiting %3$s
2244 Your project will also not appear in the Trove Software Map (primary
2245 list of projects hosted on %4$s which offers great flexibility in
2246 browsing and search) until you categorize it in the project administration
2247 screens. So that people can find your project, you should do this now.
2248 Visit your project while logged in, and select \'Project Admin\' from the
2251 Enjoy the system, and please tell others about %4$s. Let us know
2252 if there is anything we can do to help you.
2255 $this->getPublicName(),
2256 $this->getUnixName(),
2257 util_make_url ('/project/admin/?group_id='.$this->getID()),
2258 $GLOBALS['sys_name']);
2260 util_send_message($row_admins['email'], sprintf(_('%1$s Project Approved'), $GLOBALS['sys_name']), $message);
2262 setup_gettext_from_context();
2270 * sendRejectionEmail - Send project rejection email.
2272 * This function sends out a rejection message to a user who
2273 * registered a project.
2275 * @param int The id of the response to use.
2276 * @param string The rejection message.
2277 * @return completion status.
2280 function sendRejectionEmail($response_id, $message="zxcv") {
2281 $res_admins = db_query_params ('
2282 SELECT u.email, u.language, u.user_id
2283 FROM users u, user_group ug
2284 WHERE ug.group_id=$1
2285 AND u.user_id=ug.user_id',
2286 array ($this->getID())) ;
2287 if (db_numrows($res_admins) < 1) {
2288 $this->setError(_("Group does not have any administrators."));
2292 while ($row_admins = db_fetch_array($res_admins)) {
2293 $admin =& user_get_object($row_admins['user_id']);
2294 setup_gettext_for_user ($admin) ;
2296 $response=sprintf(_('Your project registration for %3$s has been denied.
2298 Project Full Name: %1$s
2299 Project Unix Name: %2$s
2301 Reasons for negative decision:
2303 '), $this->getPublicName(), $this->getUnixName(), $GLOBALS['sys_name']);
2305 // Check to see if they want to send a custom rejection response
2306 if ($response_id == 0) {
2307 $response .= $message;
2309 $response .= db_result (
2310 db_query_params('SELECT response_text FROM canned_responses WHERE response_id=$1', array ($response_id)),
2315 util_send_message($row_admins['email'], sprintf(_('%1$s Project Denied'), $GLOBALS['sys_name']), $response);
2316 setup_gettext_from_context();
2323 * sendNewProjectNotificationEmail - Send new project notification email.
2325 * This function sends out a notification email to the
2326 * SourceForge admin user when a new project is
2329 * @return boolean success.
2332 function sendNewProjectNotificationEmail() {
2333 // Get the user who wants to register the project
2334 $res = db_query_params ('SELECT user_id FROM user_group WHERE group_id=$1',
2335 array ($this->getID())) ;
2337 if (db_numrows($res) < 1) {
2338 $this->setError(_("Could not find user who has submitted the project."));
2342 $submitter =& user_get_object(db_result($res,0,'user_id'));
2345 $res = db_query_params ('SELECT users.email, users.language, users.user_id
2346 FROM users, user_group
2348 AND user_group.admin_flags=$1
2349 AND users.user_id=user_group.user_id',
2352 if (db_numrows($res) < 1) {
2353 $this->setError(_("There is no administrator to send the mail."));
2357 for ($i=0; $i<db_numrows($res) ; $i++) {
2358 $admin_email = db_result($res,$i,'email') ;
2359 $admin =& user_get_object(db_result($res,$i,'user_id'));
2360 setup_gettext_for_user ($admin) ;
2362 $message=sprintf(_('New %1$s Project Submitted
2364 Project Full Name: %2$s
2365 Submitted Description: %3$s
2366 Submitter: %5$s (%6$s)
2368 Please visit the following URL to approve or reject this project:
2370 $GLOBALS['sys_name'],
2371 $this->getPublicName(),
2372 util_unconvert_htmlspecialchars($this->getRegistrationPurpose()),
2373 util_make_url ('/admin/approve-pending.php'),
2374 $submitter->getRealName(),
2375 $submitter->getUnixName());
2376 util_send_message($admin_email, sprintf(_('New %1$s Project Submitted'), $GLOBALS['sys_name']), $message);
2377 setup_gettext_from_context();
2381 $email = $submitter->getEmail() ;
2382 setup_gettext_for_user ($submitter) ;
2384 $message=sprintf(_('New %1$s Project Submitted
2386 Project Full Name: %2$s
2387 Submitted Description: %3$s
2389 The %1$s admin team will now examine your project submission. You will be notified of their decision.'), $GLOBALS['sys_name'], $this->getPublicName(), util_unconvert_htmlspecialchars($this->getRegistrationPurpose()), $GLOBALS['sys_default_domain']);
2391 util_send_message($email, sprintf(_('New %1$s Project Submitted'), $GLOBALS['sys_name']), $message);
2392 setup_gettext_from_context();
2401 * validateGroupName - Validate the group name
2403 * @param string Group name.
2405 * @return an error false and set an error is the group name is invalide otherwise return true
2407 function validateGroupName($group_name) {
2408 if (strlen($group_name)<3) {
2409 $this->setError(_('Group name is too short'));
2411 } else if (strlen(htmlspecialchars($group_name))>50) {
2412 $this->setError(_('Group name is too long'));
2414 } else if ($group=group_get_object_by_publicname($group_name)) {
2415 $this->setError(_('Group name already taken'));
2423 * getRoles - Get the roles of the group.
2425 * @return array of Role id of this group.
2427 function getRolesId () {
2431 $roles_group_res = db_query_params ('SELECT role_id FROM role WHERE group_id=$1',
2432 array ($this->getID()));
2433 if (!$roles_group_res) {
2434 $this->setError('Error: Roles from group id '. $this->getID() . ' ' .db_error());
2437 for ($i=0; $i<db_numrows($roles_group_res); $i++) {
2438 $rolesId[$i] = db_result($roles_group_res,$i,'role_id');
2446 * getUnixStatus - Status of activation of unix account.
2448 * @return char (N)one, (A)ctive, (S)uspended or (D)eleted
2450 function getUnixStatus() {
2451 return $this->data_array['unix_status'];
2455 * setUnixStatus - Sets status of activation of unix account.
2457 * @param string The unix status.
2463 * @return boolean success.
2465 function setUnixStatus($status) {
2468 $res = db_query_params ('UPDATE groups SET unix_status=$1 WHERE group_id=$2',
2473 $this->setError(sprintf(_('ERROR - Could Not Update Group Unix Status: %s'),db_error()));
2477 if ($status == 'A') {
2478 if (!$SYS->sysCheckCreateGroup($this->getID())) {
2479 $this->setError($SYS->getErrorMessage());
2484 if ($SYS->sysCheckGroup($this->getID())) {
2485 if (!$SYS->sysRemoveGroup($this->getID())) {
2486 $this->setError($SYS->getErrorMessage());
2493 $this->data_array['unix_status']=$status;
2500 * getUsers - Get the users of a group
2502 * @return array of user's objects.
2504 function getUsers() {
2507 $users_group_res = db_query_params ('SELECT u.user_id FROM users u, user_group ug WHERE ug.group_id=$1 AND ug.user_id=u.user_id AND u.status=$2',
2508 array ($this->getID(),
2510 if (!$users_group_res) {
2511 $this->setError('Error: Enable to get users from group '. $this->getID() . ' ' .db_error());
2515 for ($i=0; $i<db_numrows($users_group_res); $i++) {
2516 $users[$i] = new GFUser(db_result($users_group_res,$i,'user_id'),false);
2523 * getMenu - get an array that contains data for the group menu
2525 * @param string contains the name of the selected menu item
2526 * @return array array containing:
2527 * 'titles': array that stores the titles of the menu entries
2528 * 'dirs': array that stores the URLs of the menu entries
2529 * 'start': URL of the starting page of the project
2530 * 'admindirs': array that stores the URLs of the admin pages
2531 * for the menu entries, if accessible, false otherwise
2532 * 'selected': number of the menu entry selected by $toptab
2533 * 'last_toptab': required internally: stores the
2534 * value of $toptab for the last call to getMenu()
2536 function &getMenu($toptab = "") {
2537 // rebuild menu if it has never been built before, or
2538 // if the toptab was set differently
2539 if (!isset($this->menu_data)
2541 || ($toptab != $this->menu_data['last_toptab']))
2544 $group = $this->getId();
2546 $this->menu_data = array () ;
2547 $this->menu_data['titles'] = array();
2548 $this->menu_data['dirs'] = array();
2549 $this->menu_data['admindirs'] = array();
2552 $this->menu_data['titles'][] = _('Summary');
2553 if (isset ($GLOBALS['sys_noforcetype']) && $GLOBALS['sys_noforcetype']) {
2554 $dir = util_make_url ('/project/?group_id=' . $group);
2556 $dir = util_make_url ('/projects/' . $this->getUnixName() .'/');
2558 $this->menu_data['dirs'][] = $dir;
2559 $this->menu_data['admindirs'][] = false;
2560 if ($toptab == "home") {
2561 $selected = (count($this->menu_data['dirs'])-1);
2563 // setting 'start' allows to change the
2564 // projects start page
2565 $this->menu_data['start'] = $dir;
2568 $perm =& $this->getPermission( session_get_user() );
2569 if ($perm->isAdmin()) {
2570 $this->menu_data['titles'][] = _('Admin');
2571 $this->menu_data['dirs'][] = util_make_url ('/project/admin/?group_id=' . $group);
2572 $this->menu_data['admindirs'][] = false;
2573 if ($toptab == "admin") {
2574 $selected = (count($this->menu_data['dirs'])-1);
2579 // check for use_home_tab?
2580 $TABS_DIRS[]='http://'. $this->getHomePage();
2581 $TABS_TITLES[]=_('Home Page');
2584 // Project Activity tab
2585 $this->menu_data['titles'][] = _('Activity');
2586 $this->menu_data['dirs'][] = util_make_url ('/activity/?group_id=' . $group);
2587 $this->menu_data['admindirs'][] = false;
2588 if ($toptab == "activity") {
2589 $selected = (count($this->menu_data['dirs'])-1);
2593 if ($this->usesForum()) {
2594 $this->menu_data['titles'][] = _('Forums');
2595 $this->menu_data['dirs'][] = util_make_url ('/forum/?group_id=' . $group);
2596 if ($perm->isAdmin() || $perm->isForumAdmin()) {
2597 $this->menu_data['admindirs'][] = util_make_url('/forum/admin/?group_id='.$group);
2599 $this->menu_data['admindirs'][] = false;
2601 if ($toptab == "forums") {
2602 $selected = (count($this->menu_data['dirs'])-1);
2606 // Artifact Tracking
2607 if ($this->usesTracker()) {
2608 $this->menu_data['titles'][] = _('Tracker');
2609 $this->menu_data['dirs'][] = util_make_url ('/tracker/?group_id=' . $group);
2610 if ($perm->isAdmin() || $perm->isArtifactAdmin()) {
2611 $this->menu_data['admindirs'][] = util_make_url('/tracker/admin/?group_id='.$group);
2613 $this->menu_data['admindirs'][] = false;
2615 if ($toptab == "tracker" ||
2616 $toptab == "bugs" ||
2617 $toptab == "support" ||
2618 $toptab == "patch") {
2619 $selected = (count($this->menu_data['dirs'])-1);
2625 if ($this->usesMail()) {
2626 $this->menu_data['titles'][] = _('Lists');
2627 $this->menu_data['dirs'][] = util_make_url ('/mail/?group_id=' . $group);
2628 if ($perm->isAdmin()) {
2629 $this->menu_data['admindirs'][] = util_make_url('/mail/admin/?group_id='.$group);
2631 $this->menu_data['admindirs'][] = false;
2633 if ($toptab == "mail") {
2634 $selected = (count($this->menu_data['dirs'])-1);
2639 // Project/Task Manager
2640 if ($this->usesPm()) {
2641 $this->menu_data['titles'][] = _('Tasks');
2642 $this->menu_data['dirs'][] = util_make_url ('/pm/?group_id=' . $group);
2643 if ($perm->isAdmin() || $perm->isPMAdmin()) {
2644 $this->menu_data['admindirs'][] = util_make_url ('/pm/admin/?group_id='.$group);
2646 $this->menu_data['admindirs'][] = false;
2648 if ($toptab == "pm") {
2649 $selected = (count($this->menu_data['dirs'])-1);
2655 if ($this->usesDocman()) {
2656 $this->menu_data['titles'][] = _('Docs');
2657 $this->menu_data['dirs'][] = util_make_url ('/docman/?group_id=' . $group);
2658 if ($perm->isAdmin() || $perm->isDocEditor()) {
2659 $this->menu_data['admindirs'][] = util_make_url ('/docman/admin/?group_id='.$group);
2661 $this->menu_data['admindirs'][] = false;
2663 if ($toptab == "docman") {
2664 $selected = (count($this->menu_data['dirs'])-1);
2670 if ($this->usesSurvey()) {
2671 $this->menu_data['titles'][] = _('Surveys');
2672 $this->menu_data['dirs'][] = util_make_url ('/survey/?group_id=' . $group);
2673 if ($perm->isAdmin()) {
2674 $this->menu_data['admindirs'][] = util_make_url ('/survey/admin/?group_id='.$group);
2676 $this->menu_data['admindirs'][] = false;
2678 if ($toptab == "surveys") {
2679 $selected = (count($this->menu_data['dirs'])-1);
2684 if ($this->usesNews()) {
2685 $this->menu_data['titles'][] = _('News');
2686 $this->menu_data['dirs'][] = util_make_url ('/news/?group_id=' . $group);
2687 if ($perm->isAdmin()) {
2688 $this->menu_data['admindirs'][] = util_make_url ('/news/admin/?group_id='.$group);
2690 $this->menu_data['admindirs'][] = false;
2692 if ($toptab == "news") {
2693 $selected = (count($this->menu_data['dirs'])-1);
2698 if ($this->usesSCM()) {
2699 $this->menu_data['titles'][] = _('SCM');
2700 $this->menu_data['dirs'][] = util_make_url ('/scm/?group_id=' . $group);
2702 if ($perm->isAdmin()) {
2703 $this->menu_data['admindirs'][] = util_make_url ('/scm/admin/?group_id='.$group);
2705 $this->menu_data['admindirs'][] = false;
2707 if ($toptab == "scm") {
2708 $selected = (count($this->menu_data['dirs'])-1);
2712 // groupmenu_after_scm hook
2713 $hookParams = array();
2714 $hookParams['group_id'] = $group ;
2715 $hookParams['DIRS'] =& $this->menu_data['dirs'];
2716 $hookParams['TITLES'] =& $this->menu_data['titles'];
2717 $hookParams['toptab'] =& $toptab;
2718 $hookParams['selected'] =& $selected;
2720 plugin_hook ("groupmenu_scm", $hookParams) ;
2722 // fill up admindirs
2724 $i < count($this->menu_data['dirs']) - count($this->menu_data['admindirs']);
2726 $this->menu_data['admindirs'][] = false;
2730 if ($this->usesFRS()) {
2731 $this->menu_data['titles'][] = _('Files');
2732 $this->menu_data['dirs'][] = util_make_url ('/frs/?group_id=' . $group);
2733 if ($perm->isAdmin() || $perm->isReleaseTechnician()) {
2734 $this->menu_data['admindirs'][] = util_make_url ('/frs/admin/?group_id='.$group);
2736 $this->menu_data['admindirs'][] = false;
2738 if ($toptab == "frs") {
2739 $selected = (count($this->menu_data['dirs'])-1);
2744 $hookParams = array();
2745 $hookParams['group'] = $group ;
2746 $hookParams['DIRS'] =& $this->menu_data['dirs'];
2747 $hookParams['TITLES'] =& $this->menu_data['titles'];
2748 $hookParams['toptab'] =& $toptab;
2749 $hookParams['selected'] =& $selected;
2751 plugin_hook ("groupmenu", $hookParams) ;
2753 // fill up admindirs
2755 $i < count($this->menu_data['dirs']) - count($this->menu_data['admindirs']);
2757 $this->menu_data['admindirs'][] = false;
2760 // store selected menu item (if any)
2761 $this->menu_data['selected'] = $selected;
2762 if ($toptab != "") {
2763 $this->menu_data['last_toptab'] = $toptab;
2766 return $this->menu_data ;
2771 * group_getname() - get the group name
2773 * @param int The group ID
2777 function group_getname ($group_id = 0) {
2778 $grp = &group_get_object($group_id);
2780 return $grp->getPublicName();
2787 * group_getunixname() - get the unixname for a group
2789 * @param int The group ID
2793 function group_getunixname ($group_id) {
2794 $grp = &group_get_object($group_id);
2796 return $grp->getUnixName();
2803 * group_get_result() - Get the group object result ID.
2805 * @param int The group ID
2809 function &group_get_result($group_id=0) {
2810 $grp = &group_get_object($group_id);
2812 return $grp->getData();
2821 // c-file-style: "bsd"