5 * Copyright 1999-2001, VA Linux Systems, Inc.
6 * Copyright 2009-2010, Roland Mas
7 * Copyright 2010, Franck Villaume - Capgemini
8 * Copyright (C) 2010 Alain Peyrat - Alcatel-Lucent
10 * This file is part of FusionForge.
12 * FusionForge is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License as published
14 * by the Free Software Foundation; either version 2 of the License,
15 * or (at your option) any later version.
17 * FusionForge is distributed in the hope that it will be useful, but
18 * WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 * General Public License for more details.
22 * You should have received a copy of the GNU General Public License
23 * along with FusionForge; if not, write to the Free Software
24 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
28 require_once $gfcommon.'tracker/ArtifactTypes.class.php';
29 require_once $gfcommon.'tracker/ArtifactTypeFactory.class.php';
30 require_once $gfcommon.'forum/Forum.class.php';
31 require_once $gfcommon.'forum/ForumFactory.class.php';
32 require_once $gfcommon.'pm/ProjectGroup.class.php';
33 require_once $gfcommon.'pm/ProjectGroupFactory.class.php';
34 require_once $gfcommon.'include/Role.class.php';
35 require_once $gfcommon.'frs/FRSPackage.class.php';
36 require_once $gfcommon.'docman/DocumentGroup.class.php';
37 require_once $gfcommon.'docman/DocumentGroupFactory.class.php';
38 require_once $gfcommon.'mail/MailingList.class.php';
39 require_once $gfcommon.'mail/MailingListFactory.class.php';
40 require_once $gfcommon.'survey/SurveyFactory.class.php';
41 require_once $gfcommon.'survey/SurveyQuestionFactory.class.php';
42 require_once $gfcommon.'include/gettext.php';
43 require_once $gfcommon.'include/GroupJoinRequest.class.php';
45 //the license_id of "Other/proprietary" license
46 define('GROUP_LICENSE_OTHER',126);
48 $LICENSE_NAMES=array();
51 * group_get_licences() - get the licenses list
53 * @return array list of licenses
55 function & group_get_licenses() {
56 global $LICENSE_NAMES;
57 if(empty($LICENSE_NAMES)) {
58 $result = db_query_params ('SELECT * FROM licenses', array());
59 while($data = db_fetch_array($result)) {
60 $LICENSE_NAMES[$data['license_id']] = $data['license_name'];
63 return $LICENSE_NAMES;
69 * group_get_object() - Get the group object.
71 * group_get_object() is useful so you can pool group objects/save database queries
72 * You should always use this instead of instantiating the object directly.
74 * You can now optionally pass in a db result handle. If you do, it re-uses that query
75 * to instantiate the objects.
77 * IMPORTANT! That db result must contain all fields
78 * from groups table or you will have problems
81 * @param int Result set handle ("SELECT * FROM groups WHERE group_id=xx")
82 * @return a group object or false on failure
84 function &group_get_object($group_id,$res=false) {
85 //create a common set of group objects
86 //saves a little wear on the database
88 //automatically checks group_type and
89 //returns appropriate object
92 if (!isset($GROUP_OBJ["_".$group_id."_"])) {
94 //the db result handle was passed in
96 $res = db_query_params ('SELECT * FROM groups WHERE group_id=$1', array ($group_id)) ;
98 if (!$res || db_numrows($res) < 1) {
99 $GROUP_OBJ["_".$group_id."_"]=false;
102 check group type and set up object
104 if (db_result($res,0,'type_id')==1) {
106 $GROUP_OBJ["_".$group_id."_"]= new Group($group_id,$res);
109 $GROUP_OBJ["_".$group_id."_"]=false;
113 return $GROUP_OBJ["_".$group_id."_"];
116 function &group_get_objects($id_arr) {
119 // Note: if we don't do this, the result may be corrupted
123 foreach ($id_arr as $id) {
125 // See if this ID already has been fetched in the cache
127 if (!isset($GROUP_OBJ["_".$id."_"])) {
131 if (count($fetch) > 0) {
132 $res=db_query_params ('SELECT * FROM groups WHERE group_id = ANY ($1)',
133 array (db_int_array_to_any_clause ($fetch))) ;
134 while ($arr = db_fetch_array($res)) {
135 $GROUP_OBJ["_".$arr['group_id']."_"] = new Group($arr['group_id'],$arr);
138 foreach ($id_arr as $id) {
139 $return[] =& $GROUP_OBJ["_".$id."_"];
144 function &group_get_active_projects() {
145 $res=db_query_params ('SELECT group_id FROM groups WHERE status=$1',
147 return group_get_objects (util_result_column_to_array($res,0)) ;
150 function &group_get_template_projects() {
151 $res=db_query_params ('SELECT group_id FROM groups WHERE is_template=1 AND status != $1',
153 return group_get_objects (util_result_column_to_array($res,0)) ;
156 function &group_get_object_by_name($groupname) {
157 $res=db_query_params('SELECT * FROM groups WHERE unix_group_name=$1', array ($groupname)) ;
158 return group_get_object(db_result($res,0,'group_id'),$res);
161 function &group_get_objects_by_name($groupname_arr) {
162 $res=db_query_params ('SELECT group_id FROM groups WHERE unix_group_name = ANY ($1)',
163 array (db_string_array_to_any_clause ($groupname_arr))
165 $arr =& util_result_column_to_array($res,0);
166 return group_get_objects($arr);
169 function &group_get_object_by_publicname($groupname) {
170 $res=db_query_params ('SELECT * FROM groups WHERE lower(group_name) LIKE $1',
171 array (htmlspecialchars (strtolower ($groupname)))) ;
173 return group_get_object(db_result($res,0,'group_id'),$res);
176 class Group extends Error {
178 * Associative array of data from db.
180 * @var array $data_array.
185 * array of User objects.
187 * @var array $membersArr.
192 * Whether the use is an admin/super user of this project.
194 * @var bool $is_admin.
199 * Artifact types result handle.
201 * @var int $types_res.
206 * Associative array of data for plugins.
208 * @var array $plugins_data.
214 * Associative array of data for the group menu.
216 * @var array $menu_data.
221 * Group - Group object constructor - use group_get_object() to instantiate.
223 * @param int Required - group_id of the group you want to instantiate.
224 * @param int Database result from select query OR associative array of all columns.
226 function Group($id=false, $res=false) {
229 //setting up an empty object
230 //probably going to call create()
234 if (!$this->fetchData($id)) {
239 // Assoc array was passed in
241 if (is_array($res)) {
242 $this->data_array =& $res;
244 if (db_numrows($res) < 1) {
245 //function in class we extended
246 $this->setError(_('Group Not Found'));
247 $this->data_array=array();
250 //set up an associative array for use by other functions
251 $this->data_array = db_fetch_array_by_row($res, 0);
260 * fetchData - May need to refresh database fields if an update occurred.
262 * @param int The group_id.
264 function fetchData($group_id) {
265 $res = db_query_params ('SELECT * FROM groups WHERE group_id=$1',
267 if (!$res || db_numrows($res) < 1) {
268 $this->setError(sprintf(_('fetchData():: %s'),db_error()));
271 $this->data_array = db_fetch_array($res);
276 * create - Create new group.
278 * This method should be called on empty Group object.
280 * @param object The User object.
281 * @param string The full name of the user.
282 * @param string The Unix name of the user.
283 * @param string The new group description.
284 * @param string The purpose of the group.
285 * @param bool Whether to send an email or not
286 * @param int The id of the project this new project is based on
288 function create(&$user, $group_name, $unix_name, $description, $purpose, $unix_box='shell1', $scm_box='cvs1', $is_public=1, $send_mail=true, $built_from_template=0) {
289 // $user is ignored - anyone can create pending group
292 if ($this->getID()!=0) {
293 $this->setError(_('Group::create: Group object already exists'));
295 } else if (!$this->validateGroupName($group_name)) {
297 } else if (!account_groupnamevalid($unix_name)) {
298 $this->setError(_('Invalid Unix name'));
300 } else if (!$SYS->sysUseUnixName($unix_name)) {
301 $this->setError(_('Unix name already taken'));
303 } else if (db_numrows(db_query_params('SELECT group_id FROM groups WHERE unix_group_name=$1',
304 array ($unix_name))) > 0) {
305 $this->setError(_('Unix name already taken'));
307 } else if (strlen($purpose)<10) {
308 $this->setError(_('Please describe your Registration Purpose in a more comprehensive manner'));
310 } else if (strlen($purpose)>1500) {
311 $this->setError(_('The Registration Purpose text is too long. Please make it smaller than 1500 bytes.'));
313 } else if (strlen($description)<10) {
314 $this->setError(_('Describe in a more comprehensive manner your project.'));
316 } else if (strlen($description)>255) {
317 $this->setError(_('Your project description is too long. Please make it smaller than 256 bytes.'));
323 $res = db_query_params ('
340 VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14)',
341 array (htmlspecialchars ($group_name),
344 htmlspecialchars($description),
345 $unix_name.".".forge_get_config('web_host'),
346 $unix_name.".".forge_get_config('web_host'),
350 htmlspecialchars($purpose),
353 md5(util_randbytes()),
354 $built_from_template)) ;
355 if (!$res || db_affected_rows($res) < 1) {
356 $this->setError(sprintf(_('ERROR: Could not create group: %s'),db_error()));
361 $id = db_insertid($res, 'groups', 'group_id');
363 $this->setError(sprintf(_('ERROR: Could not get group id: %s'),db_error()));
368 if (!$this->fetchData($id)) {
374 $gjr = new GroupJoinRequest ($this) ;
375 $gjr->create ($user->getID(),
376 'Fake GroupJoinRequest to store the creator of a project',
380 // Now, make the user an admin
382 $res=db_query_params ('INSERT INTO user_group (user_id, group_id, admin_flags,
383 cvs_flags, artifact_flags, forum_flags, role_id)
384 VALUES ($1, $2, $3, $4, $5, $6, $7)',
385 array ($user->getID(),
392 if (!$res || db_affected_rows($res) < 1) {
393 $this->setError(sprintf(_('ERROR: Could not add admin to newly created group: %s'),db_error()));
399 $hook_params = array ();
400 $hook_params['group'] = $this;
401 $hook_params['group_id'] = $this->getID();
402 $hook_params['group_name'] = $group_name;
403 $hook_params['unix_group_name'] = $unix_name;
404 plugin_hook ("group_create", $hook_params);
408 $this->sendNewProjectNotificationEmail();
416 * updateAdmin - Update core properties of group object.
418 * This function require site admin privilege.
420 * @param object User requesting operation (for access control).
421 * @param bool Whether group is publicly accessible (0/1).
422 * @param int Group type (1-project, 2-foundry).
423 * @param string Machine on which group's home directory located.
424 * @param string Domain which serves group's WWW.
428 function updateAdmin(&$user, $is_public, $type_id, $unix_box, $http_domain) {
429 $perm =& $this->getPermission ();
431 if (!$perm || !is_object($perm)) {
432 $this->setError(_('Could not get permission.'));
436 if (!$perm->isSuperUser()) {
437 $this->setError(_('Permission denied.'));
443 $res = db_query_params ('
445 SET is_public=$1, type_id=$2,
446 unix_box=$3, http_domain=$4
454 if (!$res || db_affected_rows($res) < 1) {
455 $this->setError(_('ERROR: DB: Could not change group properties: %s'),db_error());
460 // Log the audit trail
461 if ($is_public != $this->isPublic()) {
462 $this->addHistory('is_public', $this->isPublic());
464 if ($type_id != $this->data_array['type_id']) {
465 $this->addHistory('type_id', $this->data_array['type_id']);
467 if ($unix_box != $this->data_array['unix_box']) {
468 $this->addHistory('unix_box', $this->data_array['unix_box']);
470 if ($http_domain != $this->data_array['http_domain']) {
471 $this->addHistory('http_domain', $this->data_array['http_domain']);
474 if (!$this->fetchData($this->getID())) {
483 * update - Update number of common properties.
485 * Unlike updateAdmin(), this function accessible to project admin.
487 * @param object User requesting operation (for access control).
488 * @param bool Whether group is publicly accessible (0/1).
489 * @param string Project's license (string ident).
490 * @param int Group type (1-project, 2-foundry).
491 * @param string Machine on which group's home directory located.
492 * @param string Domain which serves group's WWW.
493 * @return int status.
496 function update(&$user, $group_name,$homepage,$short_description,$use_mail,$use_survey,$use_forum,
497 $use_pm,$use_pm_depend_box,$use_scm,$use_news,$use_docman,
498 $new_doc_address,$send_all_docs,$logo_image_id,
499 $use_ftp,$use_tracker,$use_frs,$use_stats,$tags,$is_public) {
501 $perm =& $this->getPermission ();
503 if (!$perm || !is_object($perm)) {
504 $this->setError(_('Could not get permission.'));
508 if (!$perm->isAdmin()) {
509 $this->setError(_('Permission denied.'));
513 // Validate some values
514 if ($this->getPublicName() != $group_name) {
515 if (!$this->validateGroupName($group_name)) {
520 if ($new_doc_address) {
521 $invalid_mails = validate_emails($new_doc_address);
522 if (count($invalid_mails) > 0) {
523 $this->setError(sprintf (ngettext('New Doc Address Appeared Invalid: %s', 'New Doc Addresses Appeared Invalid: %s', count($invalid_mails)),implode(',',$invalid_mails)));
528 // in the database, these all default to '1',
529 // so we have to explicity set 0
542 if (!$use_pm_depend_box) {
543 $use_pm_depend_box=0;
566 if (!$send_all_docs) {
570 $homepage = ltrim($homepage);
572 $homepage=forge_get_config('web_host').'/projects/'.$this->getUnixName().'/';
575 if (strlen(htmlspecialchars($short_description))>255) {
576 $this->setError(_('Error updating project information: Maximum length for Project Description is 255 chars.'));
582 //XXX not yet actived logo_image_id='$logo_image_id',
583 $res = db_query_params ('UPDATE groups
586 short_description=$3,
591 use_pm_depend_box=$8,
603 array (htmlspecialchars($group_name),
605 htmlspecialchars($short_description),
624 $this->setError(sprintf(_('Error updating project information: %s'), db_error()));
629 if ($this->setTags($tags) === false) {
634 $hook_params = array ();
635 $hook_params['group'] = $this;
636 $hook_params['group_id'] = $this->getID();
637 $hook_params['group_homepage'] = $homepage;
638 $hook_params['group_name'] = htmlspecialchars($group_name);
639 $hook_params['group_description'] = htmlspecialchars($short_description);
640 plugin_hook ("group_update", $hook_params);
642 // Log the audit trail
643 $this->addHistory('Changed Public Info', '');
645 if (!$this->fetchData($this->getID())) {
654 * getID - Simply return the group_id for this object.
656 * @return int group_id.
659 return $this->data_array['group_id'];
663 * getType() - Foundry, project, etc.
665 * @return int The type flag from the database.
668 return $this->data_array['type_id'];
673 * getStatus - the status code.
675 * Statuses char include I,H,A,D.
677 function getStatus() {
678 return $this->data_array['status'];
682 * setStatus - set the status code.
684 * Statuses include I,H,A,D.
686 * @param object User requesting operation (for access control).
687 * @param string Status value.
688 * @return boolean success.
691 function setStatus(&$user, $status) {
694 if (!forge_check_global_perm ('approve_projects')) {
695 $this->setPermissionDeniedError();
699 // Projects in 'A' status can only go to 'H' or 'D'
700 // Projects in 'D' status can only go to 'A'
701 // Projects in 'P' status can only go to 'A' OR 'D'
702 // Projects in 'I' status can only go to 'P'
703 // Projects in 'H' status can only go to 'A' OR 'D'
704 $allowed_status_changes = array(
705 'AH'=>1,'AD'=>1,'DA'=>1,'PA'=>1,'PD'=>1,
706 'IP'=>1,'HA'=>1,'HD'=>1
709 // Check that status transition is valid
710 if ($this->getStatus() != $status
711 && !$allowed_status_changes[$this->getStatus().$status]) {
712 $this->setError(_('Invalid Status Change'));
718 $res = db_query_params ('UPDATE groups
720 WHERE group_id=$2', array ($status, $this->getID())) ;
722 if (!$res || db_affected_rows($res) < 1) {
723 $this->setError(sprintf(_('ERROR: DB: Could not change group status: %s'),db_error()));
729 // Activate system group, if not yet
730 if (!$SYS->sysCheckGroup($this->getID())) {
731 if (!$SYS->sysCreateGroup($this->getID())) {
732 $this->setError($SYS->getErrorMessage());
737 if (!$this->activateUsers()) {
742 /* Otherwise, the group is not active, and make sure that
743 System group is not active either */
744 } else if ($SYS->sysCheckGroup($this->getID())) {
745 if (!$SYS->sysRemoveGroup($this->getID())) {
746 $this->setError($SYS->getErrorMessage());
752 $hook_params = array ();
753 $hook_params['group'] = $this;
754 $hook_params['group_id'] = $this->getID();
755 $hook_params['status'] = $status;
756 plugin_hook ("group_setstatus", $hook_params);
760 // Log the audit trail
761 if ($status != $this->getStatus()) {
762 $this->addHistory('Status', $this->getStatus());
765 $this->data_array['status'] = $status;
770 * isProject - Simple boolean test to see if it's a project or not.
772 * @return boolean is_project.
774 function isProject() {
775 if ($this->getType()==1) {
783 * isPublic - Simply returns the is_public flag from the database.
785 * @return boolean is_public.
787 function isPublic() {
788 return $this->data_array['is_public'];
792 * isActive - Database field status of 'A' returns true.
794 * @return boolean is_active.
796 function isActive() {
797 if ($this->getStatus()=='A') {
805 * isTemplate - Simply returns the is_template flag from the database.
807 * @return boolean is_template.
809 function isTemplate() {
810 return $this->data_array['is_template'];
814 * setAsTemplate - Set the template status of a project
816 * @param boolean is_template.
818 function setAsTemplate ($booleanparam) {
820 $booleanparam = $booleanparam ? 1 : 0 ;
821 $res = db_query_params ('UPDATE groups SET is_template=$1 WHERE group_id=$2',
822 array ($booleanparam, $this->getID()));
824 $this->data_array['is_template']=$booleanparam;
834 * getTemplateProject - Return the project template this project is built from
836 * @return object The template project
838 function getTemplateProject() {
839 return group_get_object($this->data_array['built_from_template']);
843 * getUnixName - the unix_name
845 * @return string unix_name.
847 function getUnixName() {
848 return strtolower($this->data_array['unix_group_name']);
852 * getPublicName - the full-length public name.
854 * @return string The group_name.
856 function getPublicName() {
857 return $this->data_array['group_name'];
861 * getRegisterPurpose - the text description of the purpose of this project.
863 * @return string The description.
865 function getRegisterPurpose() {
866 return $this->data_array['register_purpose'];
870 * getDescription - the text description of this project.
872 * @return string The description.
874 function getDescription() {
875 return $this->data_array['short_description'];
879 * getStartDate - the unix time this project was registered.
881 * @return int (unix time) of registration.
883 function getStartDate() {
884 return $this->data_array['register_time'];
888 * getLogoImageID - the id of the logo in the database for this project.
890 * @return int The ID of logo image in db_images table (or 100 if none).
892 function getLogoImageID() {
893 return $this->data_array['logo_image_id'];
897 * getUnixBox - the hostname of the unix box where this project is located.
899 * @return string The name of the unix machine for the group.
901 function getUnixBox() {
902 return $this->data_array['unix_box'];
906 * getSCMBox - the hostname of the scm box where this project is located.
908 * @return string The name of the unix machine for the group.
910 function getSCMBox() {
911 return $this->data_array['scm_box'];
914 * setSCMBox - the hostname of the scm box where this project is located.
916 * @param string The name of the new SCM_BOX
918 function setSCMBox($scm_box) {
920 if ($scm_box == $this->data_array['scm_box']) {
925 $res = db_query_params ('UPDATE groups SET scm_box=$1 WHERE group_id=$2', array ($scm_box, $this->getID ()));
927 $this->addHistory('scm_box', $this->data_array['scm_box']);
928 $this->data_array['scm_box']=$scm_box;
933 $this->setError(_("Couldn't insert SCM_BOX to database"));
937 $this->setError(_("SCM Box can't be empty"));
943 * getDomain - the hostname.domain where their web page is located.
945 * @return string The name of the group [web] domain.
947 function getDomain() {
948 return $this->data_array['http_domain'];
952 * getLicense - the license they chose.
954 * @return int ident of group license.
956 function getLicense() {
957 return $this->data_array['license'];
961 * getLicenseName - the name of the license
963 * @return string license name
965 function getLicenseName() {
966 $licenses =& group_get_licenses();
967 if(isset($licenses[$this->data_array['license']])) {
968 return $licenses[$this->data_array['license']];
975 * getLicenseOther - optional string describing license.
977 * @return string The custom license.
979 function getLicenseOther() {
980 if ($this->getLicense() == GROUP_LICENSE_OTHER) {
981 return $this->data_array['license_other'];
988 * getRegistrationPurpose - the text description of the purpose of this project.
990 * @return string The application for project hosting.
992 function getRegistrationPurpose() {
993 return $this->data_array['register_purpose'];
998 * getAdmins() - Get array of Admin user objects.
1000 * @return array Array of User objects.
1002 function &getAdmins() {
1003 $roles = RBACEngine::getInstance()->getRolesByAllowedAction ('project_admin', $this->getID()) ;
1005 $user_ids = array () ;
1007 foreach ($roles as $role) {
1008 if (! ($role instanceof RoleExplicit)) {
1011 if ($role->getHomeProject() == NULL
1012 || $role->getHomeProject()->getID() != $this->getID()) {
1016 foreach ($role->getUsers() as $u) {
1017 $user_ids[] = $u->getID() ;
1021 return user_get_objects(array_unique($user_ids));
1026 Common Group preferences for tools
1031 * enableAnonSCM - whether or not this group has opted to enable Anonymous SCM.
1033 * @return boolean enable_scm.
1035 function enableAnonSCM() {
1037 $r = RoleAnonymous::getInstance () ;
1038 return $r->hasPermission ('scm', $this->getID(), 'read') ;
1040 if ($this->isPublic() && $this->usesSCM()) {
1041 return $this->data_array['enable_anonscm'];
1048 function SetUsesAnonSCM ($booleanparam) {
1050 $booleanparam = $booleanparam ? 1 : 0 ;
1052 $r = RoleAnonymous::getInstance () ;
1053 $r->setSetting ('scm', $this->getID(), $booleanparam) ;
1056 $res = db_query_params ('UPDATE groups SET enable_anonscm=$1 WHERE group_id=$2',
1057 array ($booleanparam, $this->getID()));
1059 $this->data_array['enable_anonscm']=$booleanparam;
1068 function setUsesSCM ($booleanparam) {
1070 $booleanparam = $booleanparam ? 1 : 0 ;
1071 $res = db_query_params ('UPDATE groups SET use_scm=$1 WHERE group_id=$2',
1072 array ($booleanparam, $this->getID()));
1074 $this->data_array['use_scm']=$booleanparam;
1083 * enablePserver - whether or not this group has opted to enable Pserver.
1085 * @return boolean enable_pserver.
1087 function enablePserver() {
1088 if ($this->usesSCM()) {
1089 return $this->data_array['enable_pserver'];
1095 function SetUsesPserver ($booleanparam) {
1097 $booleanparam = $booleanparam ? 1 : 0 ;
1098 $res = db_query_params ('UPDATE groups SET enable_pserver=$1 WHERE group_id=$2',
1099 array ($booleanparam, $this->getID()));
1101 $this->data_array['enable_pserver']=$booleanparam;
1110 * usesSCM - whether or not this group has opted to use SCM.
1112 * @return boolean uses_scm.
1114 function usesSCM() {
1116 if (forge_get_config('use_scm')) {
1117 return $this->data_array['use_scm'];
1124 * setUseSCM - Set the SCM usage
1126 * @param boolean enabled/disabled
1128 function setUseSCM ($booleanparam) {
1130 $booleanparam = $booleanparam ? 1 : 0 ;
1131 $res = db_query_params ('UPDATE groups SET use_scm=$1 WHERE group_id=$2',
1132 array ($booleanparam, $this->getID()));
1134 $this->data_array['use_scm']=$booleanparam;
1144 * usesMail - whether or not this group has opted to use mailing lists.
1146 * @return boolean uses_mail.
1148 function usesMail() {
1150 if (forge_get_config('use_mail')) {
1151 return $this->data_array['use_mail'];
1158 * setUseMail - Set the mailing-list usage
1160 * @param boolean enabled/disabled
1162 function setUseMail ($booleanparam) {
1164 $booleanparam = $booleanparam ? 1 : 0 ;
1165 $res = db_query_params ('UPDATE groups SET use_mail=$1 WHERE group_id=$2',
1166 array ($booleanparam, $this->getID()));
1168 $this->data_array['use_mail']=$booleanparam;
1178 * usesNews - whether or not this group has opted to use news.
1180 * @return boolean uses_news.
1182 function usesNews() {
1184 if (forge_get_config('use_news')) {
1185 return $this->data_array['use_news'];
1192 * usesForum - whether or not this group has opted to use discussion forums.
1194 * @return boolean uses_forum.
1196 function usesForum() {
1198 if (forge_get_config('use_forum')) {
1199 return $this->data_array['use_forum'];
1206 * setUseForum - Set the forum usage
1208 * @param boolean enabled/disabled
1210 function setUseForum ($booleanparam) {
1212 $booleanparam = $booleanparam ? 1 : 0 ;
1213 $res = db_query_params ('UPDATE groups SET use_forum=$1 WHERE group_id=$2',
1214 array ($booleanparam, $this->getID()));
1216 $this->data_array['use_forum']=$booleanparam;
1226 * usesStats - whether or not this group has opted to use stats.
1228 * @return boolean uses_stats.
1230 function usesStats() {
1231 return $this->data_array['use_stats'];
1235 * usesFRS - whether or not this group has opted to use file release system.
1237 * @return boolean uses_frs.
1239 function usesFRS() {
1241 if (forge_get_config('use_frs')) {
1242 return $this->data_array['use_frs'];
1249 * setUseFRS - Set the FRS usage
1251 * @param boolean enabled/disabled
1253 function setUseFRS ($booleanparam) {
1255 $booleanparam = $booleanparam ? 1 : 0 ;
1256 $res = db_query_params ('UPDATE groups SET use_frs=$1 WHERE group_id=$2',
1257 array ($booleanparam, $this->getID()));
1259 $this->data_array['use_frs']=$booleanparam;
1269 * usesTracker - whether or not this group has opted to use tracker.
1271 * @return boolean uses_tracker.
1273 function usesTracker() {
1275 if (forge_get_config('use_tracker')) {
1276 return $this->data_array['use_tracker'];
1283 * setUseTracker - Set the tracker usage
1285 * @param boolean enabled/disabled
1287 function setUseTracker ($booleanparam) {
1289 $booleanparam = $booleanparam ? 1 : 0 ;
1290 $res = db_query_params ('UPDATE groups SET use_tracker=$1 WHERE group_id=$2',
1291 array ($booleanparam, $this->getID()));
1293 $this->data_array['use_tracker']=$booleanparam;
1303 * useCreateOnline - whether or not this group has opted to use create online documents option.
1305 * @return boolean use_docman_create_online.
1307 function useCreateOnline() {
1309 if (forge_get_config('use_docman')) {
1310 return $this->data_array['use_docman_create_online'];
1317 * usesDocman - whether or not this group has opted to use docman.
1319 * @return boolean use_docman.
1321 function usesDocman() {
1323 if (forge_get_config('use_docman')) {
1324 return $this->data_array['use_docman'];
1331 * setUseDocman - Set the docman usage
1333 * @param boolean enabled/disabled
1335 function setUseDocman ($booleanparam) {
1337 $booleanparam = $booleanparam ? 1 : 0 ;
1338 $res = db_query_params ('UPDATE groups SET use_docman=$1 WHERE group_id=$2',
1339 array ($booleanparam, $this->getID()));
1341 $this->data_array['use_docman']=$booleanparam;
1351 * useDocmanSearch - whether or not this group has opted to use docman search engine.
1353 * @return boolean use_docman_search.
1355 function useDocmanSearch() {
1357 if (forge_get_config('use_docman')) {
1358 return $this->data_array['use_docman_search'];
1365 * useWebdav - whether or not this group has opted to use webdav interface.
1367 * @return boolean use_docman_search.
1369 function useWebdav() {
1371 if (forge_get_config('use_webdav')) {
1372 return $this->data_array['use_webdav'];
1379 * usesFTP - whether or not this group has opted to use FTP.
1381 * @return boolean uses_ftp.
1383 function usesFTP() {
1385 if (forge_get_config('use_ftp')) {
1386 return $this->data_array['use_ftp'];
1393 * usesSurvey - whether or not this group has opted to use surveys.
1395 * @return boolean uses_survey.
1397 function usesSurvey() {
1399 if (forge_get_config('use_survey')) {
1400 return $this->data_array['use_survey'];
1407 * usesPM - whether or not this group has opted to Project Manager.
1409 * @return boolean uses_projman.
1413 if (forge_get_config('use_pm')) {
1414 return $this->data_array['use_pm'];
1421 * setUsePM - Set the PM usage
1423 * @param boolean enabled/disabled
1425 function setUsePM ($booleanparam) {
1427 $booleanparam = $booleanparam ? 1 : 0 ;
1428 $res = db_query_params ('UPDATE groups SET use_pm=$1 WHERE group_id=$2',
1429 array ($booleanparam, $this->getID()));
1431 $this->data_array['use_pm']=$booleanparam;
1441 * getPlugins - get a list of all available group plugins
1443 * @return array array containing plugin_id => plugin_name
1445 function getPlugins() {
1446 if (!isset($this->plugins_data)) {
1447 $this->plugins_data = array () ;
1448 $res = db_query_params ('SELECT group_plugin.plugin_id, plugins.plugin_name
1449 FROM group_plugin, plugins
1450 WHERE group_plugin.group_id=$1
1451 AND group_plugin.plugin_id=plugins.plugin_id', array ($this->getID()));
1452 $rows = db_numrows($res);
1454 for ($i=0; $i<$rows; $i++) {
1455 $plugin_id = db_result($res,$i,'plugin_id');
1456 $this->plugins_data[$plugin_id] = db_result($res,$i,'plugin_name');
1459 return $this->plugins_data ;
1463 * usesPlugin - returns true if the group uses a particular plugin
1465 * @param string name of the plugin
1466 * @return boolean whether plugin is being used or not
1468 function usesPlugin($pluginname) {
1469 $plugins_data = $this->getPlugins() ;
1470 foreach ($plugins_data as $p_id => $p_name) {
1471 if ($p_name == $pluginname) {
1478 * added for Codendi compatibility
1479 * usesServices - returns true if the group uses a particular plugin or feature
1481 * @param string name of the plugin
1482 * @return boolean whether plugin is being used or not
1484 function usesService($feature) {
1485 $plugins_data = $this->getPlugins() ;
1486 $pm = plugin_manager_get_object();
1487 foreach ($plugins_data as $p_id => $p_name) {
1488 if ($p_name == $feature) {
1491 if ($pm->getPluginByName($p_name)->provide($feature) ) {
1499 * setPluginUse - enables/disables plugins for the group
1501 * @param string name of the plugin
1502 * @param boolean the new state
1503 * @return string database result
1505 function setPluginUse($pluginname, $val=true) {
1506 if ($val == $this->usesPlugin($pluginname)) {
1507 // State is already good, returning
1510 $res = db_query_params ('SELECT plugin_id FROM plugins WHERE plugin_name=$1',
1511 array ($pluginname));
1512 $rows = db_numrows($res);
1514 // Error: no plugin by that name
1517 $plugin_id = db_result($res,0,'plugin_id');
1519 unset ($this->plugins_data) ;
1521 $res = db_query_params ('INSERT INTO group_plugin (group_id, plugin_id) VALUES ($1, $2)',
1522 array ($this->getID(),
1526 $res = db_query_params ('DELETE FROM group_plugin WHERE group_id=$1 AND plugin_id=$2',
1527 array ($this->getID(),
1534 * getDocEmailAddress - get email address(es) to send doc notifications to.
1536 * @return string email address.
1538 function getDocEmailAddress() {
1539 return $this->data_array['new_doc_address'];
1543 * DocEmailAll - whether or not this group has opted to use receive notices on all doc updates.
1545 * @return boolean email_on_all_doc_updates.
1547 function docEmailAll() {
1548 return $this->data_array['send_all_docs'];
1553 * getHomePage - The URL for this project's home page.
1555 * @return string homepage URL.
1557 function getHomePage() {
1558 return $this->data_array['homepage'];
1562 * getTags - Tags of this project.
1564 * @return string List of tags.
1566 function getTags() {
1567 $sql = 'SELECT name FROM project_tags WHERE group_id = $1';
1568 $res = db_query_params($sql, array($this->getID()));
1569 return join(', ', util_result_column_to_array($res));
1573 * setTags - Set tags of this project.
1575 * @return string database result.
1577 function setTags($tags) {
1579 $sql='DELETE FROM project_tags WHERE group_id=$1';
1580 $res=db_query_params($sql, array($this->getID()));
1582 $this->setError('Deleting old tags: '.db_error());
1586 $inserted = array();
1587 $tags_array = preg_split('/[;,]/', $tags);
1588 foreach ($tags_array as $tag) {
1589 $tag = preg_replace('/[\t\r\n]/', ' ', $tag);
1590 // Allowed caracteres: [A-Z][a-z][0-9] -_&'#+.
1591 if (preg_match('/[^[:alnum:]| |\-|_|\&|\'|#|\+|\.]/', $tag)) {
1592 $this->setError(_('Bad tag name, you only can use the following characters: [A-Z][a-z][0-9]-_&\'#+. and space'));
1597 if ($tag == '' || array_search($tag, $inserted) !== false) continue;
1598 $sql='INSERT INTO project_tags (group_id,name) VALUES ($1, $2)';
1599 $res=db_query_params($sql, array($this->getID(), $tag));
1601 $this->setError(_('Setting tags: ').db_error());
1612 * getPermission - Return a Permission for this Group
1614 * @return object The Permission.
1616 function &getPermission() {
1617 return permission_get_object($this);
1621 function delete($sure,$really_sure,$really_really_sure) {
1622 if (!$sure || !$really_sure || !$really_really_sure) {
1623 $this->setMissingParamsError(_('Please tick all checkboxes.'));
1626 if ($this->getID() == forge_get_config('news_group') ||
1627 $this->getID() == 1 ||
1628 $this->getID() == forge_get_config('stats_group') ||
1629 $this->getID() == forge_get_config('peer_rating_group')) {
1630 $this->setError(_('Cannot Delete System Group'));
1633 $perm =& $this->getPermission ();
1634 if (!$perm || !is_object($perm)) {
1635 $this->setPermissionDeniedError();
1637 } elseif ($perm->isError()) {
1638 $this->setPermissionDeniedError();
1640 } elseif (!$perm->isSuperUser()) {
1641 $this->setPermissionDeniedError();
1647 // Remove all the members
1649 $members =& $this->getMembers();
1650 foreach ($members as $i) {
1651 $this->removeUser($i->getID());
1653 // Failsafe until user_group table is gone
1654 $res = db_query_params ('DELETE FROM user_group WHERE group_id=$1',
1655 array ($this->getID())) ;
1657 // unlink roles to this project
1658 if ($this->isPublic()) {
1659 $ra = RoleAnonymous::getInstance();
1660 $rl = RoleLoggedIn::getInstance();
1661 $ra->unlinkProject($this);
1662 $rl->unlinkProject($this);
1664 // @todo : unlink all the other roles created in the project...
1669 $atf = new ArtifactTypeFactory($this);
1670 $at_arr =& $atf->getArtifactTypes();
1671 foreach ($at_arr as $i) {
1672 if (!is_object($i)) {
1680 $ff = new ForumFactory($this);
1681 $f_arr =& $ff->getForums();
1682 foreach ($f_arr as $i) {
1683 if (!is_object($i)) {
1689 // Delete Subprojects
1691 $pgf = new ProjectGroupFactory($this);
1692 $pg_arr =& $pgf->getProjectGroups();
1693 foreach ($pg_arr as $i) {
1694 if (!is_object($i)) {
1700 // Delete FRS Packages
1702 //$frspf = new FRSPackageFactory($this);
1703 $res = db_query_params ('SELECT * FROM frs_package WHERE group_id=$1',
1704 array ($this->getID())) ;
1705 //echo 'frs_package'.db_error();
1706 //$frsp_arr =& $frspf->getPackages();
1707 while ($arr = db_fetch_array($res)) {
1708 //if (!is_object($pg_arr[$i])) {
1709 // echo "Not Object: ProjectGroup: ".$i;
1712 $frsp=new FRSPackage($this,$arr['package_id'],$arr);
1718 $news_group=group_get_object(forge_get_config('news_group'));
1719 $res = db_query_params ('SELECT forum_id FROM news_bytes WHERE group_id=$1',
1720 array ($this->getID())) ;
1722 $this->setError(_('Error Deleting News: ').db_error());
1727 for ($i=0; $i<db_numrows($res); $i++) {
1728 $Forum = new Forum($news_group,db_result($res,$i,'forum_id'));
1729 if (!$Forum->delete(1,1)) {
1730 printf (_("Could Not Delete News Forum: %d"),$Forum->getID());
1733 $res = db_query_params ('DELETE FROM news_bytes WHERE group_id=$1',
1734 array ($this->getID())) ;
1736 $this->setError(_('Error Deleting News: ').db_error());
1744 $res = db_query_params ('DELETE FROM doc_data WHERE group_id=$1',
1745 array ($this->getID())) ;
1747 $this->setError(_('Error Deleting Documents: ').db_error());
1752 $res = db_query_params ('DELETE FROM doc_groups WHERE group_id=$1',
1753 array ($this->getID())) ;
1755 $this->setError(_('Error Deleting Documents: ').db_error());
1763 $res=db_query_params('DELETE FROM project_tags WHERE group_id=$1', array($this->getID()));
1765 $this->setError(_('Error Deleting Tags: ').db_error());
1771 // Delete group history
1773 $res = db_query_params ('DELETE FROM group_history WHERE group_id=$1',
1774 array ($this->getID())) ;
1776 $this->setError(_('Error Deleting Project History: ').db_error());
1782 // Delete group plugins
1784 $res = db_query_params ('DELETE FROM group_plugin WHERE group_id=$1',
1785 array ($this->getID())) ;
1787 $this->setError(_('Error Deleting Project Plugins: ').db_error());
1793 // Delete group cvs stats
1795 $res = db_query_params ('DELETE FROM stats_cvs_group WHERE group_id=$1',
1796 array ($this->getID())) ;
1798 $this->setError(_('Error Deleting SCM Statistics: ').db_error());
1806 $sf = new SurveyFactory($this);
1807 $s_arr =& $sf->getSurveys();
1808 foreach ($s_arr as $i) {
1809 if (!is_object($i)) {
1815 // Delete SurveyQuestions
1817 $sqf = new SurveyQuestionFactory($this);
1818 $sq_arr =& $sqf->getSurveyQuestions();
1819 foreach ($sq_arr as $i) {
1820 if (!is_object($i)) {
1826 // Delete Mailing List Factory
1828 $mlf = new MailingListFactory($this);
1829 $ml_arr =& $mlf->getMailingLists();
1830 foreach ($ml_arr as $i) {
1831 if (!is_object($i)) {
1834 if (!$i->delete(1,1)) {
1835 $this->setError(_('Could not properly delete the mailing list'));
1841 $res = db_query_params ('DELETE FROM trove_group_link WHERE group_id=$1',
1842 array ($this->getID())) ;
1844 $this->setError(_('Error Deleting Trove: ').db_error());
1849 $res = db_query_params ('DELETE FROM trove_agg WHERE group_id=$1',
1850 array ($this->getID())) ;
1852 $this->setError(_('Error Deleting Trove: ').db_error());
1860 $res = db_query_params ('DELETE FROM project_sums_agg WHERE group_id=$1',
1861 array ($this->getID())) ;
1863 $this->setError(_('Error Deleting Counters: ').db_error());
1868 $res = db_query_params ('INSERT INTO deleted_groups (unix_group_name,delete_date,isdeleted) VALUES ($1, $2, $3)',
1869 array ($this->getUnixName(),
1873 $this->setError(_('Error Deleting Project: ').db_error());
1878 $res = db_query_params ('DELETE FROM groups WHERE group_id=$1',
1879 array ($this->getID())) ;
1881 $this->setError(_('Error Deleting Project: ').db_error());
1891 $hook_params = array ();
1892 $hook_params['group'] = $this;
1893 $hook_params['group_id'] = $this->getID();
1894 plugin_hook ("group_delete", $hook_params);
1896 if (forge_get_config('upload_dir') != '' && $this->getUnixName()) {
1897 exec('/bin/rm -rf '.forge_get_config('upload_dir').'/'.$this->getUnixName().'/');
1899 if (forge_get_config('ftp_upload_dir') != '' && $this->getUnixName()) {
1900 exec('/bin/rm -rf '.forge_get_config('ftp_upload_dir').'/'.$this->getUnixName().'/');
1905 $res = db_query_params ('DELETE FROM rep_group_act_monthly WHERE group_id=$1',
1906 array ($this->getID())) ;
1907 //echo 'rep_group_act_monthly'.db_error();
1908 $res = db_query_params ('DELETE FROM rep_group_act_weekly WHERE group_id=$1',
1909 array ($this->getID())) ;
1910 //echo 'rep_group_act_weekly'.db_error();
1911 $res = db_query_params ('DELETE FROM rep_group_act_daily WHERE group_id=$1',
1912 array ($this->getID())) ;
1913 //echo 'rep_group_act_daily'.db_error();
1914 unset($this->data_array);
1922 Basic functions to add/remove users to/from a group
1923 and update their permissions
1929 * addUser - controls adding a user to a group.
1931 * @param string Unix name of the user to add OR integer user_id.
1932 * @param int The role_id this user should have.
1933 * @return boolean success.
1936 function addUser($user_identifier,$role_id) {
1939 Admins can add users to groups
1942 if (!forge_check_perm ('project_admin', $this->getID())) {
1943 $this->setPermissionDeniedError();
1949 get user id for this user's unix_name
1951 if (is_int ($user_identifier)) { // user_id or user_name
1952 $res_newuser = db_query_params ('SELECT * FROM users WHERE user_id=$1', array ($user_identifier)) ;
1954 $res_newuser = db_query_params ('SELECT * FROM users WHERE user_name=$1', array ($user_identifier)) ;
1956 if (db_numrows($res_newuser) > 0) {
1958 // make sure user is active
1960 if (db_result($res_newuser,0,'status') != 'A') {
1961 $this->setError(_('User is not active. Only active users can be added.'));
1967 // user was found - set new user_id var
1969 $user_id = db_result($res_newuser,0,'user_id');
1971 $role = new Role($this,$role_id);
1972 if (!$role || !is_object($role)) {
1973 $this->setError(_('Error Getting Role Object'));
1976 } elseif ($role->isError()) {
1977 $this->setError('addUser::roleget::'.$role->getErrorMessage());
1983 $role->addUser (user_get_object ($user_id)) ;
1984 if (!$SYS->sysCheckCreateGroup($this->getID())){
1985 $this->setError($SYS->getErrorMessage());
1989 if (!$SYS->sysCheckCreateUser($user_id)) {
1990 $this->setError($SYS->getErrorMessage());
1997 // if not already a member, add them
1999 $res_member = db_query_params ('SELECT user_id
2001 WHERE user_id=$1 AND group_id=$2',
2002 array ($user_id, $this->getID())) ;
2004 if (db_numrows($res_member) < 1) {
2006 // Create this user's row in the user_group table
2008 $res = db_query_params ('INSERT INTO user_group
2009 (user_id,group_id,admin_flags,forum_flags,project_flags,
2010 doc_flags,cvs_flags,member_role,release_flags,artifact_flags)
2011 VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10)',
2023 //verify the insert worked
2024 if (!$res || db_affected_rows($res) < 1) {
2025 $this->setError(sprintf(_('ERROR: Could Not Add User To Group: %s'),db_error()));
2030 // check and create if group doesn't exists
2032 //echo "<h2>Group::addUser SYS->sysCheckCreateGroup(".$this->getID().")</h2>";
2033 if (!$SYS->sysCheckCreateGroup($this->getID())){
2034 $this->setError($SYS->getErrorMessage());
2039 // check and create if user doesn't exists
2041 //echo "<h2>Group::addUser SYS->sysCheckCreateUser($user_id)</h2>";
2042 if (!$SYS->sysCheckCreateUser($user_id)) {
2043 $this->setError($SYS->getErrorMessage());
2050 //echo "<h2>Group::addUser role->setUser($user_id)</h2>";
2051 if (!$role->setUser($user_id)) {
2052 $this->setError('addUser::role::setUser'.$role->getErrorMessage());
2058 // user was already a member
2059 // make sure they are set up
2061 $user=&user_get_object($user_id,$res_newuser);
2062 $user->fetchData($user->getID());
2063 $role = new Role($this,$role_id);
2064 if (!$role || !is_object($role)) {
2065 $this->setError(_('Error Getting Role Object'));
2068 } elseif ($role->isError()) {
2069 $this->setError('addUser::roleget::'.$role->getErrorMessage());
2073 //echo "<h2>Already Member Group::addUser role->setUser($user_id)</h2>";
2074 if (!$role->setUser($user_id)) {
2075 $this->setError('addUser::role::setUser'.$role->getErrorMessage());
2080 // set up their system info
2082 //echo "<h2>Already Member Group::addUser SYS->sysCheckCreateUser($user_id)</h2>";
2083 if (!$SYS->sysCheckCreateUser($user_id)) {
2084 $this->setError($SYS->getErrorMessage());
2092 // user doesn't exist
2094 $this->setError(_('ERROR: User does not exist'));
2099 $hook_params['group'] = $this;
2100 $hook_params['group_id'] = $this->getID();
2101 $hook_params['user'] = &user_get_object($user_id);
2102 $hook_params['user_id'] = $user_id;
2103 plugin_hook ("group_adduser", $hook_params);
2108 $this->addHistory('Added User',$user_identifier);
2114 * removeUser - controls removing a user from a group.
2116 * Users can remove themselves.
2118 * @param int The ID of the user to remove.
2119 * @return boolean success.
2121 function removeUser($user_id) {
2124 if ($user_id != user_getid()
2125 || !forge_check_perm ('project_admin', $this->getID())) {
2126 $this->setPermissionDeniedError();
2133 $user = user_get_object ($user_id) ;
2134 $roles = RBACEngine::getInstance()->getAvailableRolesForUser ($user) ;
2135 $found_role = NULL ;
2136 foreach ($roles as $role) {
2137 if ($role->getHomeProject() && $role->getHomeProject()->getID() == $this->getID()) {
2138 $found_role = $role ;
2142 if ($found_role == NULL) {
2143 $this->setError(sprintf(_('ERROR: User not removed: %s')));
2147 $found_role->removeUser ($user) ;
2148 if (!$SYS->sysGroupCheckUser($this->getID(),$user_id)) {
2149 $this->setError($SYS->getErrorMessage());
2155 $res = db_query_params ('DELETE FROM user_group WHERE group_id=$1 AND user_id=$2',
2156 array ($this->getID(),
2158 if (!$res || db_affected_rows($res) < 1) {
2159 $this->setError(sprintf(_('ERROR: User not removed: %s'),db_error()));
2166 // reassign open artifacts to id=100
2168 $res = db_query_params ('UPDATE artifact SET assigned_to=100
2169 WHERE group_artifact_id
2170 IN (SELECT group_artifact_id
2171 FROM artifact_group_list
2172 WHERE group_id=$1 AND status_id=1 AND assigned_to=$2)',
2173 array ($this->getID(),
2176 $this->setError(sprintf(_('ERROR: DB: artifact: %s'),db_error()));
2182 // reassign open tasks to id=100
2183 // first have to purge any assignments that would cause
2184 // conflict with existing assignment to 100
2186 $res = db_query_params ('DELETE FROM project_assigned_to
2187 WHERE project_task_id IN (SELECT pt.project_task_id
2188 FROM project_task pt, project_group_list pgl, project_assigned_to pat
2189 WHERE pt.group_project_id = pgl.group_project_id
2190 AND pat.project_task_id=pt.project_task_id
2191 AND pt.status_id=1 AND pgl.group_id=$1
2192 AND pat.assigned_to_id=$2)
2193 AND assigned_to_id=100',
2194 array ($this->getID(),
2197 $this->setError(sprintf(_('ERROR: DB: project_assigned_to %d: %s'),1,db_error()));
2201 $res = db_query_params ('UPDATE project_assigned_to SET assigned_to_id=100
2202 WHERE project_task_id IN (SELECT pt.project_task_id
2203 FROM project_task pt, project_group_list pgl
2204 WHERE pt.group_project_id = pgl.group_project_id
2205 AND pt.status_id=1 AND pgl.group_id=$1)
2206 AND assigned_to_id=$2',
2207 array ($this->getID(),
2210 $this->setError(sprintf(_('ERROR: DB: project_assigned_to %d: %s'),2,db_error()));
2216 // Remove user from system
2218 if (!$SYS->sysGroupRemoveUser($this->getID(),$user_id)) {
2219 $this->setError($SYS->getErrorMessage());
2224 $hook_params['group'] = $this;
2225 $hook_params['group_id'] = $this->getID();
2226 $hook_params['user'] = &user_get_object($user_id);
2227 $hook_params['user_id'] = $user_id;
2228 plugin_hook ("group_removeuser", $hook_params);
2231 $this->addHistory('Removed User',$user_id);
2238 * updateUser - controls updating a user's role in this group.
2240 * @param int The ID of the user.
2241 * @param int The role_id to set this user to.
2242 * @return boolean success.
2244 function updateUser($user_id,$role_id) {
2247 if (!forge_check_perm ('project_admin', $this->getID())) {
2248 $this->setPermissionDeniedError();
2253 $newrole = RBACEngine::getInstance()->getRoleById ($role_id) ;
2254 if (!$newrole || !is_object($newrole)) {
2255 $this->setError(_('Could Not Get Role'));
2257 } elseif ($newrole->isError()) {
2258 $this->setError(sprintf(_('Role: %s'),$role->getErrorMessage()));
2260 } elseif ($newrole->getHomeProject() == NULL
2261 || $newrole->getHomeProject()->getID() != $this->getID()) {
2262 $this->setError(_('Wrong destination role'));
2265 $user = user_get_object ($user_id) ;
2266 $roles = RBACEngine::getInstance()->getAvailableRolesForUser ($user) ;
2267 $found_role = NULL ;
2268 foreach ($roles as $role) {
2269 if ($role->getHomeProject() && $role->getHomeProject()->getID() == $this->getID()) {
2270 $found_role = $role ;
2274 if ($found_role == NULL) {
2275 $this->setError(sprintf(_('ERROR: User not removed: %s')));
2279 $found_role->removeUser ($user) ;
2280 $newrole->addUser ($user) ;
2282 $role = new Role($this,$role_id);
2283 if (!$role || !is_object($role)) {
2284 $this->setError(_('Could Not Get Role'));
2286 } elseif ($role->isError()) {
2287 $this->setError(sprintf(_('Role: %s'),$role->getErrorMessage()));
2290 //echo "<h3>Group::updateUser role->setUser($user_id)</h3>";
2291 if (!$role->setUser($user_id)) {
2292 $this->setError(sprintf(_('Role: %s'),$role->getErrorMessage()));
2297 $this->addHistory('Updated User',$user_id);
2302 * addHistory - Makes an audit trail entry for this project.
2304 * @param string The name of the field.
2305 * @param string The Old Value for this $field_name.
2306 * @return database result handle.
2309 function addHistory($field_name, $old_value) {
2310 return db_query_params ('INSERT INTO group_history(group_id,field_name,old_value,mod_by,adddate)
2311 VALUES ($1,$2,$3,$4,$5)',
2312 array ($this->getID(),
2320 * activateUsers - Make sure that group members have unix accounts.
2322 * Setup unix accounts for group members. Can be called even
2323 * if members are already active.
2327 function activateUsers() {
2329 Activate member(s) of the project
2333 $members = $this->getUsers (true) ;
2335 foreach ($members as $member) {
2337 foreach (RBACEngine::getInstance()->getAvailableRolesForUser ($member) as $role) {
2338 if ($role->getHomeProject() && $role->getHomeProject()->getID() == $this->getID()) {
2341 if (!$this->addUser($member->getUnixName(),$role->getID())) {
2348 $res_member = db_query_params ('SELECT user_id,role_id FROM user_group WHERE group_id=$1',
2349 array ($this->getID())) ;
2350 while ($row_member = db_fetch_array($res_member)) {
2351 $u = user_get_object($row_member['user_id']) ;
2352 if (!$this->addUser($u->getUnixName(),$row_member['role_id'])) {
2362 * getMembers - returns array of User objects for this project
2364 * @return array of User objects for this group.
2366 function getMembers() {
2367 return $this->getUsers (true) ;
2371 * replaceTemplateStrings - fill-in some blanks with project name
2373 * @param string Template string
2374 * @return string String after replacements
2376 function replaceTemplateStrings($string) {
2377 $string = str_replace ('UNIXNAME', $this->getUnixName(), $string) ;
2378 $string = str_replace ('PUBLICNAME', $this->getPublicName(), $string) ;
2379 $string = str_replace ('DESCRIPTION', $this->getDescription(), $string) ;
2384 * approve - Approve pending project.
2386 * @param object The User object who is doing the updating.
2389 function approve(&$user) {
2391 require_once $gfcommon.'widget/WidgetLayoutManager.class.php';
2393 if ($this->getStatus()=='A') {
2394 $this->setError(_("Group already active"));
2400 // Step 1: Activate group and create LDAP entries
2401 if (!$this->setStatus($user, 'A')) {
2406 // Switch to system language for item creation
2407 setup_gettext_from_sys_lang ();
2409 // Create default roles
2411 $idadmin_group = NULL ;
2412 foreach (get_group_join_requests ($this) as $gjr) {
2413 $idadmin_group = $gjr->getUserID() ;
2416 if ($idadmin_group == NULL) {
2417 $idadmin_group = $user->getID();
2420 $admin_group = db_query_params ('SELECT user_id FROM user_group WHERE group_id=$1 AND admin_flags=$2',
2421 array ($this->getID(),
2423 if (db_numrows($admin_group) > 0) {
2424 $idadmin_group = db_result($admin_group,0,'user_id');
2426 $idadmin_group = $user->getID();
2427 db_query_params ('INSERT INTO user_group (user_id, group_id, admin_flags) VALUES ($1, $2, $3)',
2428 array ($idadmin_group,
2434 $template = $this->getTemplateProject() ;
2435 $id_mappings = array ();
2436 $seen_local_roles = false ;
2438 // Copy roles from template project
2439 foreach ($template->getRoles() as $oldrole) {
2440 if ($oldrole->getHomeProject() != NULL) {
2441 $role = new Role ($this) ;
2443 // Need to use a different role name so that the permissions aren't set from the hardcoded defaults
2444 $role->create ('TEMPORARY ROLE NAME', $data, true) ;
2445 $role->setName ($oldrole->getName()) ;
2446 $seen_local_roles = true ;
2449 $role->linkProject ($this) ;
2451 $id_mappings['role'][$oldrole->getID()] = $role->getID() ;
2452 // Reuse the project_admin permission
2453 $role->setSetting ('project_admin', $this->getID(), $oldrole->getSetting ('project_admin', $template->getID())) ;
2457 if (!$seen_local_roles) {
2458 $role = new Role($this);
2459 $adminperms = array ('project_admin' => array ($this->getID() => 1)) ;
2460 $role_id = $role->create ('Admin', $adminperms, true) ;
2464 $roles = $this->getRoles() ;
2465 foreach ($roles as $r) {
2466 if ($r->getSetting ('project_admin', $this->getID())) {
2467 $r->addUser (user_get_object ($idadmin_group)) ;
2472 // Temporarily switch to the submitter's identity
2473 $saved_session = session_get_user () ;
2474 session_set_internal ($idadmin_group) ;
2477 if (forge_get_config ('use_tracker')) {
2478 $this->setUseTracker ($template->usesTracker()) ;
2479 if ($template->usesTracker()) {
2480 $oldatf = new ArtifactTypeFactory ($template) ;
2481 foreach ($oldatf->getArtifactTypes() as $o) {
2482 $t = new ArtifactType ($this) ;
2483 $t->create ($this->replaceTemplateStrings($o->getName()),$this->replaceTemplateStrings($o->getDescription()),$o->isPublic(),$o->allowsAnon(),$o->emailAll(),$o->getEmailAddress(),$o->getDuePeriod()/86400,0,$o->getSubmitInstructions(),$o->getBrowseInstructions()) ;
2484 $id_mappings['tracker'][$o->getID()] = $t->getID() ;
2485 $t->cloneFieldsFrom ($o->getID()) ;
2490 if (forge_get_config ('use_pm')) {
2491 $this->setUsePM ($template->usesPM()) ;
2492 if ($template->usesPM()) {
2493 $oldpgf = new ProjectGroupFactory ($template) ;
2494 foreach ($oldpgf->getProjectGroups() as $o) {
2495 $pg = new ProjectGroup ($this) ;
2496 $pg->create ($this->replaceTemplateStrings($o->getName()),$this->replaceTemplateStrings($o->getDescription()),$o->isPublic(),$o->getSendAllPostsTo()) ;
2497 $id_mappings['pm'][$o->getID()] = $pg->getID() ;
2502 if (forge_get_config ('use_forum')) {
2503 $this->setUseForum ($template->usesForum()) ;
2504 if ($template->usesForum()) {
2505 $oldff = new ForumFactory ($template) ;
2506 foreach ($oldff->getForums() as $o) {
2507 $f = new Forum ($this) ;
2508 $f->create ($this->replaceTemplateStrings($o->getName()),$this->replaceTemplateStrings($o->getDescription()),$o->isPublic(),$o->getSendAllPostsTo(),1,$o->allowAnonymous(),$o->getModerationLevel()) ;
2509 $id_mappings['forum'][$o->getID()] = $f->getID() ;
2514 if (forge_get_config ('use_docman')) {
2515 $this->setUseDocman ($template->usesDocman()) ;
2516 if ($template->usesDocman()) {
2517 $olddgf = new DocumentGroupFactory ($template) ;
2518 // First pass: create all docgroups
2519 $id_mappings['docman_docgroup'][0] = 0 ;
2520 foreach ($olddgf->getDocumentGroups() as $o) {
2521 $ndgf = new DocumentGroup ($this) ;
2522 $ndgf->create($this->replaceTemplateStrings($o->getName())) ;
2523 $id_mappings['docman_docgroup'][$o->getID()] = $ndgf->getID() ;
2525 // Second pass: restore hierarchy links
2526 foreach ($olddgf->getDocumentGroups() as $o) {
2527 $ndgf = new DocumentGroup ($this) ;
2528 $ndgf->fetchData ($id_mappings['docman_docgroup'][$o->getID()]) ;
2529 $ndgf->update ($ndgf->getName(),$id_mappings['docman_docgroup'][$o->getParentID()]) ;
2534 if (forge_get_config ('use_frs')) {
2535 $this->setUseFRS ($template->usesFRS()) ;
2536 if ($template->usesFRS()) {
2537 foreach (get_frs_packages ($template) as $o) {
2538 $newp = new FRSPackage ($this) ;
2539 $nname = $this->replaceTemplateStrings($o->getName()) ;
2540 $newp->create ($nname, $o->isPublic()) ;
2545 if (forge_get_config ('use_mail')) {
2546 $this->setUseMail ($template->usesMail()) ;
2547 if ($template->usesMail()) {
2548 $oldmlf = new MailingListFactory ($template) ;
2549 foreach ($oldmlf->getMailingLists() as $o) {
2550 $ml = new MailingList ($this) ;
2551 $nname = preg_replace ('/^'.$template->getUnixName().'-/','',$o->getName()) ;
2553 $ndescription = $this->replaceTemplateStrings($o->getDescription()) ;
2554 $ml->create ($nname, $ndescription, $o->isPublic()) ;
2559 $this->setUseSCM ($template->usesSCM()) ;
2561 foreach ($template->getPlugins() as $plugin_id => $plugin_name) {
2562 $this->setPluginUse ($plugin_name) ;
2565 foreach ($template->getRoles() as $oldrole) {
2566 $newrole = RBACEngine::getInstance()->getRoleById ($id_mappings['role'][$oldrole->getID()]) ;
2567 if ($oldrole->getHomeProject() != NULL
2568 && $oldrole->getHomeProject()->getID() == $template->getID()) {
2569 $newrole->setPublic ($oldrole->isPublic()) ;
2571 $oldsettings = $oldrole->getSettingsForProject ($template) ;
2573 $sections = array ('project_read', 'project_admin', 'frs', 'scm', 'docman', 'tracker_admin', 'new_tracker', 'forum_admin', 'new_forum', 'pm_admin', 'new_pm') ;
2574 foreach ($sections as $section) {
2575 $newrole->setSetting ($section, $this->getID(), $oldsettings[$section][$template->getID()]) ;
2578 $sections = array ('tracker', 'pm', 'forum') ;
2579 foreach ($sections as $section) {
2580 if (isset ($oldsettings[$section])) {
2581 foreach ($oldsettings[$section] as $k => $v) {
2582 // Only copy perms for tools that have been copied
2583 if (isset ($id_mappings[$section][$k])) {
2584 $newrole->setSetting ($section,
2585 $id_mappings[$section][$k],
2593 $lm = new WidgetLayoutManager();
2594 $lm->createDefaultLayoutForProject ($this->getID(), $template->getID()) ;
2596 $params = array () ;
2597 $params['template'] = $template ;
2598 $params['project'] = $this ;
2599 $params['id_mappings'] = $id_mappings ;
2600 plugin_hook_by_reference ('clone_project_from_template', $params) ;
2602 // Disable everything
2603 $res = db_query_params ('UPDATE groups SET use_mail=0, use_survey=0, use_forum=0, use_pm=0, use_pm_depend_box=0, use_scm=0, use_news=0, use_docman=0, is_public=0, use_ftp=0, use_tracker=0, use_frs=0, use_stats=0 WHERE group_id=$1',
2605 array ($this->getID())) ;
2608 $this->normalizeAllRoles () ;
2610 // Switch back to user preference
2611 session_set_internal ($saved_session->getID()) ;
2612 setup_gettext_from_context();
2616 $this->sendApprovalEmail();
2617 $this->addHistory('Approved', 'x');
2620 // Plugin can make approve operation there
2623 $params[0] = $idadmin_group ;
2624 $params[1] = $this->getID();
2625 plugin_hook('group_approved',$params);
2633 * sendApprovalEmail - Send new project email.
2635 * @return boolean success.
2638 function sendApprovalEmail() {
2639 $admins = RBACEngine::getInstance()->getUsersByAllowedAction ('project_admin', $this->getID()) ;
2641 if (count($admins) < 1) {
2642 $this->setError(_("Group does not have any administrators."));
2646 // send one email per admin
2647 foreach ($admins as $admin) {
2648 setup_gettext_for_user ($admin) ;
2650 $message=sprintf(_('Your project registration for %4$s has been approved.
2652 Project Full Name: %1$s
2653 Project Unix Name: %2$s
2655 Your DNS will take up to a day to become active on our site.
2656 Your web site is accessible through your shell account. Please read
2657 site documentation (see link below) about intended usage, available
2658 services, and directory layout of the account.
2661 own project page in %4$s while logged in, you will find
2662 additional menu functions to your left labeled \'Project Admin\'.
2664 We highly suggest that you now visit %4$s and create a public
2665 description for your project. This can be done by visiting your project
2666 page while logged in, and selecting \'Project Admin\' from the menus
2667 on the left (or by visiting %3$s
2670 Your project will also not appear in the Trove Software Map (primary
2671 list of projects hosted on %4$s which offers great flexibility in
2672 browsing and search) until you categorize it in the project administration
2673 screens. So that people can find your project, you should do this now.
2674 Visit your project while logged in, and select \'Project Admin\' from the
2677 Enjoy the system, and please tell others about %4$s. Let us know
2678 if there is anything we can do to help you.
2681 htmlspecialchars_decode($this->getPublicName()),
2682 $this->getUnixName(),
2683 util_make_url ('/project/admin/?group_id='.$this->getID()),
2684 forge_get_config ('forge_name'));
2686 util_send_message($admin->getEmail(), sprintf(_('%1$s Project Approved'), forge_get_config ('forge_name')), $message);
2688 setup_gettext_from_context();
2696 * sendRejectionEmail - Send project rejection email.
2698 * This function sends out a rejection message to a user who
2699 * registered a project.
2701 * @param int The id of the response to use.
2702 * @param string The rejection message.
2703 * @return completion status.
2706 function sendRejectionEmail($response_id, $message="zxcv") {
2707 $submitters = array () ;
2709 foreach (get_group_join_requests ($this) as $gjr) {
2710 $submitters[] = user_get_object($gjr->getUserID()) ;
2713 $res = db_query_params("SELECT u.user_id FROM users u, user_group ug WHERE ug.group_id=$1 AND u.user_id=ug.user_id",
2715 while ($arr = db_fetch_array ($res)) {
2716 $submitter[] =& user_get_object($arr['user_id']);
2720 if (count ($submitters) < 1) {
2721 $this->setError(_("Group does not have any administrators."));
2725 foreach ($submitters as $admin) {
2726 setup_gettext_for_user ($admin) ;
2728 $response=sprintf(_('Your project registration for %3$s has been denied.
2730 Project Full Name: %1$s
2731 Project Unix Name: %2$s
2733 Reasons for negative decision:
2735 '), $this->getPublicName(), $this->getUnixName(), forge_get_config ('forge_name'));
2737 // Check to see if they want to send a custom rejection response
2738 if ($response_id == 0) {
2739 $response .= $message;
2741 $response .= db_result (
2742 db_query_params('SELECT response_text FROM canned_responses WHERE response_id=$1', array ($response_id)),
2747 util_send_message($admin->getEmail(), sprintf(_('%1$s Project Denied'), forge_get_config ('forge_name')), $response);
2748 setup_gettext_from_context();
2755 * sendNewProjectNotificationEmail - Send new project notification email.
2757 * This function sends out a notification email to the
2758 * SourceForge admin user when a new project is
2761 * @return boolean success.
2764 function sendNewProjectNotificationEmail() {
2765 // Get the user who wants to register the project
2766 $submitters = array () ;
2768 foreach (get_group_join_requests ($this) as $gjr) {
2769 $submitters[] = user_get_object($gjr->getUserID()) ;
2772 $res = db_query_params("SELECT u.user_id FROM users u, user_group ug WHERE ug.group_id=$1 AND u.user_id=ug.user_id",
2774 while ($arr = db_fetch_array ($res)) {
2775 $submitter[] =& user_get_object($arr['user_id']);
2778 if (count ($submitters) < 1) {
2779 $this->setError(_("Could not find user who has submitted the project."));
2783 $admins = RBACEngine::getInstance()->getUsersByAllowedAction ('approve_projects', -1) ;
2785 if (count($admins) < 1) {
2786 $this->setError(_("There is no administrator to send the mail to."));
2790 foreach ($admins as $admin) {
2791 $admin_email = $admin->getEmail () ;
2792 setup_gettext_for_user ($admin) ;
2794 foreach ($submitters as $u) {
2795 $submitter_names[] = $u->getRealName() ;
2798 $message = sprintf(_('New %1$s Project Submitted
2800 Project Full Name: %2$s
2801 Submitted Description: %3$s
2803 forge_get_config ('forge_name'),
2804 htmlspecialchars_decode($this->getPublicName()),
2805 htmlspecialchars_decode($this->getRegistrationPurpose()));
2807 foreach ($submitters as $submitter) {
2808 $message .= sprintf(_('Submitter: %1$s (%2$s)
2810 $submitter->getRealName(),
2811 $submitter->getUnixName());
2814 $message .= sprintf (_('
2815 Please visit the following URL to approve or reject this project:
2817 util_make_url ('/admin/approve-pending.php')) ;
2818 util_send_message($admin_email, sprintf(_('New %1$s Project Submitted'), forge_get_config ('forge_name')), $message);
2819 setup_gettext_from_context();
2823 $email = $submitter->getEmail() ;
2824 setup_gettext_for_user ($submitter) ;
2826 $message=sprintf(_('New %1$s Project Submitted
2828 Project Full Name: %2$s
2829 Submitted Description: %3$s
2831 The %1$s admin team will now examine your project submission. You will be notified of their decision.'), forge_get_config ('forge_name'), $this->getPublicName(), util_unconvert_htmlspecialchars($this->getRegistrationPurpose()), forge_get_config('web_host'));
2833 util_send_message($email, sprintf(_('New %1$s Project Submitted'), forge_get_config ('forge_name')), $message);
2834 setup_gettext_from_context();
2843 * validateGroupName - Validate the group name
2845 * @param string Group name.
2847 * @return an error false and set an error is the group name is invalide otherwise return true
2849 function validateGroupName($group_name) {
2850 if (strlen($group_name)<3) {
2851 $this->setError(_('Group name is too short'));
2853 } else if (strlen(htmlspecialchars($group_name))>50) {
2854 $this->setError(_('Group name is too long'));
2856 } else if ($group=group_get_object_by_publicname($group_name)) {
2857 $this->setError(_('Group name already taken'));
2865 * getRoles - Get the roles of the group.
2867 * @return array of Role id of this group.
2869 function getRolesId () {
2870 $role_ids = array () ;
2873 $res = db_query_params ('SELECT role_id FROM pfo_role WHERE home_group_id=$1',
2874 array ($this->getID()));
2875 while ($arr = db_fetch_array($res)) {
2876 $role_ids[] = $arr['role_id'] ;
2878 $res = db_query_params ('SELECT role_id FROM role_project_refs WHERE group_id=$1',
2879 array ($this->getID()));
2880 while ($arr = db_fetch_array($res)) {
2881 $role_ids[] = $arr['role_id'] ;
2884 $res = db_query_params ('SELECT role_id FROM role WHERE group_id=$1',
2885 array ($this->getID()));
2886 while ($arr = db_fetch_array($res)) {
2887 $role_ids[] = $arr['role_id'] ;
2891 return array_unique ($role_ids) ;
2894 function getRoles () {
2895 $result = array () ;
2897 $roles = $this->getRolesId () ;
2899 $engine = RBACEngine::getInstance() ;
2900 foreach ($roles as $role_id) {
2901 $result[] = $engine->getRoleById ($role_id) ;
2904 foreach ($roles as $role_id) {
2905 $result[] = new Role ($this, $role_id) ;
2912 function normalizeAllRoles () {
2913 $roles = $this->getRoles () ;
2915 foreach ($roles as $r) {
2916 $r->normalizeData () ;
2921 * getUnixStatus - Status of activation of unix account.
2923 * @return char (N)one, (A)ctive, (S)uspended or (D)eleted
2925 function getUnixStatus() {
2926 return $this->data_array['unix_status'];
2930 * setUnixStatus - Sets status of activation of unix account.
2932 * @param string The unix status.
2938 * @return boolean success.
2940 function setUnixStatus($status) {
2943 $res = db_query_params ('UPDATE groups SET unix_status=$1 WHERE group_id=$2',
2948 $this->setError(sprintf(_('ERROR - Could Not Update Group Unix Status: %s'),db_error()));
2952 if ($status == 'A') {
2953 if (!$SYS->sysCheckCreateGroup($this->getID())) {
2954 $this->setError($SYS->getErrorMessage());
2959 if ($SYS->sysCheckGroup($this->getID())) {
2960 if (!$SYS->sysRemoveGroup($this->getID())) {
2961 $this->setError($SYS->getErrorMessage());
2968 $this->data_array['unix_status']=$status;
2975 * getUsers - Get the users of a group
2977 * @return array of user's objects.
2979 function getUsers($onlylocal = true) {
2980 if (!isset($this->membersArr)) {
2981 $this->membersArr = array () ;
2985 foreach ($this->getRoles() as $role) {
2987 && ($role->getHomeProject() == NULL || $role->getHomeProject()->getID() != $this->getID())) {
2990 foreach ($role->getUsers() as $user) {
2991 $ids[] = $user->getID() ;
2994 $ids = array_unique ($ids) ;
2995 foreach ($ids as $id) {
2996 $u = user_get_object ($id) ;
2997 if ($u->isActive()) {
2998 $this->membersArr[] = $u ;
3003 $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',
3004 array ($this->getID(),
3006 if (!$users_group_res) {
3007 $this->setError(_('Error: Enable to get users from group'). ' ' . $this->getID() . ' ' .db_error());
3011 for ($i=0; $i<db_numrows($users_group_res); $i++) {
3012 $this->membersArr[$i] = new GFUser(db_result($users_group_res,$i,'user_id'),false);
3017 return $this->membersArr;
3020 function setDocmanCreateOnlineStatus($status) {
3022 /* if we activate search engine, we probably want to reindex */
3023 $res = db_query_params ('UPDATE groups SET use_docman_create_online=$1 WHERE group_id=$2',
3028 $this->setError(sprintf(_('ERROR - Could Not Update Group DocmanCreateOnline Status: %s'),db_error()));
3032 $this->data_array['use_docman_create_online']=$status;
3038 function setDocmanWebdav($status) {
3040 /* if we activate search engine, we probably want to reindex */
3041 $res = db_query_params ('UPDATE groups SET use_webdav=$1 WHERE group_id=$2',
3046 $this->setError(sprintf(_('ERROR - Could Not Update Group UseWebdab Status: %s'),db_error()));
3050 $this->data_array['use_webdav']=$status;
3056 function setDocmanSearchStatus($status) {
3058 /* if we activate search engine, we probably want to reindex */
3059 $res = db_query_params ('UPDATE groups SET use_docman_search=$1, force_docman_reindex=$1 WHERE group_id=$2',
3064 $this->setError(sprintf(_('ERROR - Could Not Update Group UseDocmanSearch Status: %s'),db_error()));
3068 $this->data_array['use_docman_search']=$status;
3074 function setDocmanForceReindexSearch($status) {
3076 /* if we activate search engine, we probably want to reindex */
3077 $res = db_query_params ('UPDATE groups SET force_docman_reindex=$1 WHERE group_id=$2',
3082 $this->setError(sprintf(_('ERROR - Could Not Update Group force_docman_reindex %s'),db_error()));
3086 $this->data_array['force_docman_reindex']=$status;
3092 function setStorageAPI($type) {
3096 function getStorageAPI() {
3102 * group_getname() - get the group name
3104 * @param int The group ID
3108 function group_getname ($group_id = 0) {
3109 $grp = group_get_object($group_id);
3111 return $grp->getPublicName();
3118 * group_getunixname() - get the unixname for a group
3120 * @param int The group ID
3124 function group_getunixname ($group_id) {
3125 $grp = group_get_object($group_id);
3127 return $grp->getUnixName();
3134 * group_get_result() - Get the group object result ID.
3136 * @param int The group ID
3140 function &group_get_result($group_id=0) {
3141 $grp = group_get_object($group_id);
3143 return $grp->getData();
3149 function getAllProjectTags($onlyvisible = true) {
3150 $res = db_query_params('SELECT project_tags.name, groups.group_id FROM groups, project_tags WHERE groups.group_id = project_tags.group_id AND groups.status = $1 ORDER BY project_tags.name, groups.group_id',
3153 if (!$res || db_numrows($res) == 0) {
3159 while ($arr = db_fetch_array($res)) {
3161 $group_id = $arr[1];
3162 if (!isset($result[$tag])) {
3163 $result[$tag] = array();
3166 if (!$onlyvisible || forge_check_perm('project_read', $group_id)) {
3167 $p = group_get_object($group_id);
3168 $result[$tag][] = array('unix_group_name' => $p->getUnixName(),
3169 'group_id' => $group_id);
3176 class ProjectComparator {
3177 var $criterion = 'name' ;
3179 function Compare ($a, $b) {
3180 switch ($this->criterion) {
3183 $namecmp = strcoll ($a->getPublicName(), $b->getPublicName()) ;
3184 if ($namecmp != 0) {
3187 /* If several projects share a same public name */
3188 return strcoll ($a->getUnixName(), $b->getUnixName()) ;
3191 return strcmp ($a->getUnixName(), $b->getUnixName()) ;
3194 $aid = $a->getID() ;
3195 $bid = $b->getID() ;
3199 return ($a < $b) ? -1 : 1;
3205 function sortProjectList (&$list, $criterion='name') {
3206 $cmp = new ProjectComparator () ;
3207 $cmp->criterion = $criterion ;
3209 return usort ($list, array ($cmp, 'Compare')) ;
3214 // c-file-style: "bsd"