5 * Copyright 1999-2001, VA Linux Systems, Inc.
6 * Copyright 2009-2010, Roland Mas
7 * Copyright 2010, Franck Villaume - Capgemini
9 * This file is part of FusionForge.
11 * FusionForge is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published
13 * by the Free Software Foundation; either version 2 of the License,
14 * or (at your option) any later version.
16 * FusionForge is distributed in the hope that it will be useful, but
17 * WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 * General Public License for more details.
21 * You should have received a copy of the GNU General Public License
22 * along with FusionForge; if not, write to the Free Software
23 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
27 require_once $gfcommon.'tracker/ArtifactTypes.class.php';
28 require_once $gfcommon.'tracker/ArtifactTypeFactory.class.php';
29 require_once $gfcommon.'forum/Forum.class.php';
30 require_once $gfcommon.'forum/ForumFactory.class.php';
31 require_once $gfcommon.'pm/ProjectGroup.class.php';
32 require_once $gfcommon.'pm/ProjectGroupFactory.class.php';
33 require_once $gfcommon.'include/Role.class.php';
34 require_once $gfcommon.'frs/FRSPackage.class.php';
35 require_once $gfcommon.'docman/DocumentGroup.class.php';
36 require_once $gfcommon.'docman/DocumentGroupFactory.class.php';
37 require_once $gfcommon.'mail/MailingList.class.php';
38 require_once $gfcommon.'mail/MailingListFactory.class.php';
39 require_once $gfcommon.'survey/SurveyFactory.class.php';
40 require_once $gfcommon.'survey/SurveyQuestionFactory.class.php';
41 require_once $gfcommon.'include/gettext.php';
42 require_once $gfcommon.'include/GroupJoinRequest.class.php';
44 //the license_id of "Other/proprietary" license
45 define('GROUP_LICENSE_OTHER',126);
47 $LICENSE_NAMES=array();
50 * group_get_licences() - get the licenses list
52 * @return array list of licenses
54 function & group_get_licenses() {
55 global $LICENSE_NAMES;
56 if(empty($LICENSE_NAMES)) {
57 $result = db_query_params ('select * from licenses', array());
58 while($data = db_fetch_array($result)) {
59 $LICENSE_NAMES[$data['license_id']] = $data['license_name'];
62 return $LICENSE_NAMES;
68 * group_get_object() - Get the group object.
70 * group_get_object() is useful so you can pool group objects/save database queries
71 * You should always use this instead of instantiating the object directly.
73 * You can now optionally pass in a db result handle. If you do, it re-uses that query
74 * to instantiate the objects.
76 * IMPORTANT! That db result must contain all fields
77 * from groups table or you will have problems
80 * @param int Result set handle ("SELECT * FROM groups WHERE group_id=xx")
81 * @return a group object or false on failure
83 function &group_get_object($group_id,$res=false) {
84 //create a common set of group objects
85 //saves a little wear on the database
87 //automatically checks group_type and
88 //returns appropriate object
91 if (!isset($GROUP_OBJ["_".$group_id."_"])) {
93 //the db result handle was passed in
95 $res = db_query_params ('SELECT * FROM groups WHERE group_id=$1', array ($group_id)) ;
97 if (!$res || db_numrows($res) < 1) {
98 $GROUP_OBJ["_".$group_id."_"]=false;
101 check group type and set up object
103 if (db_result($res,0,'type_id')==1) {
105 $GROUP_OBJ["_".$group_id."_"]= new Group($group_id,$res);
108 $GROUP_OBJ["_".$group_id."_"]=false;
112 return $GROUP_OBJ["_".$group_id."_"];
115 function &group_get_objects($id_arr) {
118 // Note: if we don't do this, the result may be corrupted
122 foreach ($id_arr as $id) {
124 // See if this ID already has been fetched in the cache
126 if (!isset($GROUP_OBJ["_".$id."_"])) {
130 if (count($fetch) > 0) {
131 $res=db_query_params ('SELECT * FROM groups WHERE group_id = ANY ($1)',
132 array (db_int_array_to_any_clause ($fetch))) ;
133 while ($arr = db_fetch_array($res)) {
134 $GROUP_OBJ["_".$arr['group_id']."_"] = new Group($arr['group_id'],$arr);
137 foreach ($id_arr as $id) {
138 $return[] =& $GROUP_OBJ["_".$id."_"];
143 function &group_get_active_projects() {
144 $res=db_query_params ('SELECT group_id FROM groups WHERE status=$1',
146 return group_get_objects (util_result_column_to_array($res,0)) ;
149 function &group_get_template_projects() {
150 $res=db_query_params ('SELECT group_id FROM groups WHERE is_template=1 AND status != $1',
152 return group_get_objects (util_result_column_to_array($res,0)) ;
155 function &group_get_object_by_name($groupname) {
156 $res=db_query_params('SELECT * FROM groups WHERE unix_group_name=$1', array ($groupname)) ;
157 return group_get_object(db_result($res,0,'group_id'),$res);
160 function &group_get_objects_by_name($groupname_arr) {
161 $res=db_query_params ('SELECT group_id FROM groups WHERE unix_group_name = ANY ($1)',
162 array (db_string_array_to_any_clause ($groupname_arr))
164 $arr =& util_result_column_to_array($res,0);
165 return group_get_objects($arr);
168 function &group_get_object_by_publicname($groupname) {
169 $res=db_query_params ('SELECT * FROM groups WHERE lower(group_name) LIKE $1',
170 array (htmlspecialchars (strtolower ($groupname)))) ;
172 return group_get_object(db_result($res,0,'group_id'),$res);
175 class Group extends Error {
177 * Associative array of data from db.
179 * @var array $data_array.
184 * array of User objects.
186 * @var array $membersArr.
191 * Whether the use is an admin/super user of this project.
193 * @var bool $is_admin.
198 * Artifact types result handle.
200 * @var int $types_res.
205 * Associative array of data for plugins.
207 * @var array $plugins_data.
213 * Associative array of data for the group menu.
215 * @var array $menu_data.
220 * Group - Group object constructor - use group_get_object() to instantiate.
222 * @param int Required - group_id of the group you want to instantiate.
223 * @param int Database result from select query OR associative array of all columns.
225 function Group($id=false, $res=false) {
228 //setting up an empty object
229 //probably going to call create()
233 if (!$this->fetchData($id)) {
238 // Assoc array was passed in
240 if (is_array($res)) {
241 $this->data_array =& $res;
243 if (db_numrows($res) < 1) {
244 //function in class we extended
245 $this->setError(_('Group Not Found'));
246 $this->data_array=array();
249 //set up an associative array for use by other functions
250 $this->data_array = db_fetch_array_by_row($res, 0);
259 * fetchData - May need to refresh database fields if an update occurred.
261 * @param int The group_id.
263 function fetchData($group_id) {
264 $res = db_query_params ('SELECT * FROM groups WHERE group_id=$1',
266 if (!$res || db_numrows($res) < 1) {
267 $this->setError(sprintf(_('fetchData():: %s'),db_error()));
270 $this->data_array = db_fetch_array($res);
275 * create - Create new group.
277 * This method should be called on empty Group object.
279 * @param object The User object.
280 * @param string The full name of the user.
281 * @param string The Unix name of the user.
282 * @param string The new group description.
283 * @param string The purpose of the group.
284 * @param bool Whether to send an email or not
285 * @param int The id of the project this new project is based on
287 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) {
288 // $user is ignored - anyone can create pending group
291 if ($this->getID()!=0) {
292 $this->setError(_('Group::create: Group object already exists'));
294 } else if (!$this->validateGroupName($group_name)) {
296 } else if (!account_groupnamevalid($unix_name)) {
297 $this->setError(_('Invalid Unix name'));
299 } else if (!$SYS->sysUseUnixName($unix_name)) {
300 $this->setError(_('Unix name already taken'));
302 } else if (db_numrows(db_query_params('SELECT group_id FROM groups WHERE unix_group_name=$1',
303 array ($unix_name))) > 0) {
304 $this->setError(_('Unix name already taken'));
306 } else if (strlen($purpose)<10) {
307 $this->setError(_('Please describe your Registration Purpose in a more comprehensive manner'));
309 } else if (strlen($purpose)>1500) {
310 $this->setError(_('The Registration Purpose text is too long. Please make it smaller than 1500 bytes.'));
312 } else if (strlen($description)<10) {
313 $this->setError(_('Describe in a more comprehensive manner your project.'));
315 } else if (strlen($description)>255) {
316 $this->setError(_('Your project description is too long. Please make it smaller than 256 bytes.'));
320 srand((double)microtime()*1000000);
321 $random_num = rand(0,1000000);
325 $res = db_query_params ('
342 VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14)',
343 array (htmlspecialchars ($group_name),
346 htmlspecialchars($description),
347 $unix_name.".".forge_get_config('web_host'),
348 $unix_name.".".forge_get_config('web_host'),
352 htmlspecialchars($purpose),
356 $built_from_template)) ;
357 if (!$res || db_affected_rows($res) < 1) {
358 $this->setError(sprintf(_('ERROR: Could not create group: %s'),db_error()));
363 $id = db_insertid($res, 'groups', 'group_id');
365 $this->setError(sprintf(_('ERROR: Could not get group id: %s'),db_error()));
370 if (!$this->fetchData($id)) {
376 $gjr = new GroupJoinRequest ($this) ;
377 $gjr->create ($user->getID(),
378 'Fake GroupJoinRequest to store the creator of a project',
382 // Now, make the user an admin
384 $res=db_query_params ('INSERT INTO user_group (user_id, group_id, admin_flags,
385 cvs_flags, artifact_flags, forum_flags, role_id)
386 VALUES ($1, $2, $3, $4, $5, $6, $7)',
387 array ($user->getID(),
394 if (!$res || db_affected_rows($res) < 1) {
395 $this->setError(sprintf(_('ERROR: Could not add admin to newly created group: %s'),db_error()));
401 $hook_params = array ();
402 $hook_params['group'] = $this;
403 $hook_params['group_id'] = $this->getID();
404 $hook_params['group_name'] = $group_name;
405 $hook_params['unix_group_name'] = $unix_name;
406 plugin_hook ("group_create", $hook_params);
410 $this->sendNewProjectNotificationEmail();
418 * updateAdmin - Update core properties of group object.
420 * This function require site admin privilege.
422 * @param object User requesting operation (for access control).
423 * @param bool Whether group is publicly accessible (0/1).
424 * @param int Group type (1-project, 2-foundry).
425 * @param string Machine on which group's home directory located.
426 * @param string Domain which serves group's WWW.
430 function updateAdmin(&$user, $is_public, $type_id, $unix_box, $http_domain) {
431 $perm =& $this->getPermission ();
433 if (!$perm || !is_object($perm)) {
434 $this->setError(_('Could not get permission.'));
438 if (!$perm->isSuperUser()) {
439 $this->setError(_('Permission denied.'));
445 $res = db_query_params ('
447 SET is_public=$1, type_id=$2,
448 unix_box=$3, http_domain=$4
456 if (!$res || db_affected_rows($res) < 1) {
457 $this->setError(_('ERROR: DB: Could not change group properties: %s'),db_error());
462 // Log the audit trail
463 if ($is_public != $this->isPublic()) {
464 $this->addHistory('is_public', $this->isPublic());
466 if ($type_id != $this->data_array['type_id']) {
467 $this->addHistory('type_id', $this->data_array['type_id']);
469 if ($unix_box != $this->data_array['unix_box']) {
470 $this->addHistory('unix_box', $this->data_array['unix_box']);
472 if ($http_domain != $this->data_array['http_domain']) {
473 $this->addHistory('http_domain', $this->data_array['http_domain']);
476 if (!$this->fetchData($this->getID())) {
485 * update - Update number of common properties.
487 * Unlike updateAdmin(), this function accessible to project admin.
489 * @param object User requesting operation (for access control).
490 * @param bool Whether group is publicly accessible (0/1).
491 * @param string Project's license (string ident).
492 * @param int Group type (1-project, 2-foundry).
493 * @param string Machine on which group's home directory located.
494 * @param string Domain which serves group's WWW.
495 * @return int status.
498 function update(&$user, $group_name,$homepage,$short_description,$use_mail,$use_survey,$use_forum,
499 $use_pm,$use_pm_depend_box,$use_scm,$use_news,$use_docman,
500 $new_doc_address,$send_all_docs,$logo_image_id,
501 $use_ftp,$use_tracker,$use_frs,$use_stats,$tags,$is_public) {
503 $perm =& $this->getPermission ();
505 if (!$perm || !is_object($perm)) {
506 $this->setError(_('Could not get permission.'));
510 if (!$perm->isAdmin()) {
511 $this->setError(_('Permission denied.'));
515 // Validate some values
516 if ($this->getPublicName() != $group_name) {
517 if (!$this->validateGroupName($group_name)) {
522 if ($new_doc_address) {
523 $invalid_mails = validate_emails($new_doc_address);
524 if (count($invalid_mails) > 0) {
525 $this->setError(sprintf (ngettext('New Doc Address Appeared Invalid: %s', 'New Doc Addresses Appeared Invalid: %s', count($invalid_mails)),implode(',',$invalid_mails)));
530 // in the database, these all default to '1',
531 // so we have to explicity set 0
544 if (!$use_pm_depend_box) {
545 $use_pm_depend_box=0;
568 if (!$send_all_docs) {
572 $homepage = ltrim($homepage);
574 $homepage=forge_get_config('web_host').'/projects/'.$this->getUnixName().'/';
577 if (strlen(htmlspecialchars($short_description))>255) {
578 $this->setError(_('Error updating project information: Maximum length for Project Description is 255 chars.'));
584 //XXX not yet actived logo_image_id='$logo_image_id',
585 $res = db_query_params ('UPDATE groups
588 short_description=$3,
593 use_pm_depend_box=$8,
605 array (htmlspecialchars($group_name),
607 htmlspecialchars($short_description),
626 $this->setError(sprintf(_('Error updating project information: %s'), db_error()));
631 if ($this->setTags($tags) === false) {
636 $hook_params = array ();
637 $hook_params['group'] = $this;
638 $hook_params['group_id'] = $this->getID();
639 $hook_params['group_homepage'] = $homepage;
640 $hook_params['group_name'] = htmlspecialchars($group_name);
641 $hook_params['group_description'] = htmlspecialchars($short_description);
642 plugin_hook ("group_update", $hook_params);
644 // Log the audit trail
645 $this->addHistory('Changed Public Info', '');
647 if (!$this->fetchData($this->getID())) {
656 * getID - Simply return the group_id for this object.
658 * @return int group_id.
661 return $this->data_array['group_id'];
665 * getType() - Foundry, project, etc.
667 * @return int The type flag from the database.
670 return $this->data_array['type_id'];
675 * getStatus - the status code.
677 * Statuses char include I,H,A,D.
679 function getStatus() {
680 return $this->data_array['status'];
684 * setStatus - set the status code.
686 * Statuses include I,H,A,D.
688 * @param object User requesting operation (for access control).
689 * @param string Status value.
690 * @return boolean success.
693 function setStatus(&$user, $status) {
696 if (!forge_check_global_perm ('approve_projects')) {
697 $this->setPermissionDeniedError();
701 // Projects in 'A' status can only go to 'H' or 'D'
702 // Projects in 'D' status can only go to 'A'
703 // Projects in 'P' status can only go to 'A' OR 'D'
704 // Projects in 'I' status can only go to 'P'
705 // Projects in 'H' status can only go to 'A' OR 'D'
706 $allowed_status_changes = array(
707 'AH'=>1,'AD'=>1,'DA'=>1,'PA'=>1,'PD'=>1,
708 'IP'=>1,'HA'=>1,'HD'=>1
711 // Check that status transition is valid
712 if ($this->getStatus() != $status
713 && !$allowed_status_changes[$this->getStatus().$status]) {
714 $this->setError(_('Invalid Status Change'));
720 $res = db_query_params ('UPDATE groups
722 WHERE group_id=$2', array ($status, $this->getID())) ;
724 if (!$res || db_affected_rows($res) < 1) {
725 $this->setError(sprintf(_('ERROR: DB: Could not change group status: %s'),db_error()));
731 // Activate system group, if not yet
732 if (!$SYS->sysCheckGroup($this->getID())) {
733 if (!$SYS->sysCreateGroup($this->getID())) {
734 $this->setError($SYS->getErrorMessage());
739 if (!$this->activateUsers()) {
744 /* Otherwise, the group is not active, and make sure that
745 System group is not active either */
746 } else if ($SYS->sysCheckGroup($this->getID())) {
747 if (!$SYS->sysRemoveGroup($this->getID())) {
748 $this->setError($SYS->getErrorMessage());
754 $hook_params = array ();
755 $hook_params['group'] = $this;
756 $hook_params['group_id'] = $this->getID();
757 $hook_params['status'] = $status;
758 plugin_hook ("group_setstatus", $hook_params);
762 // Log the audit trail
763 if ($status != $this->getStatus()) {
764 $this->addHistory('Status', $this->getStatus());
767 $this->data_array['status'] = $status;
772 * isProject - Simple boolean test to see if it's a project or not.
774 * @return boolean is_project.
776 function isProject() {
777 if ($this->getType()==1) {
785 * isPublic - Simply returns the is_public flag from the database.
787 * @return boolean is_public.
789 function isPublic() {
790 return $this->data_array['is_public'];
794 * isActive - Database field status of 'A' returns true.
796 * @return boolean is_active.
798 function isActive() {
799 if ($this->getStatus()=='A') {
807 * isTemplate - Simply returns the is_template flag from the database.
809 * @return boolean is_template.
811 function isTemplate() {
812 return $this->data_array['is_template'];
816 * setAsTemplate - Set the template status of a project
818 * @param boolean is_template.
820 function setAsTemplate ($booleanparam) {
822 $booleanparam = $booleanparam ? 1 : 0 ;
823 $res = db_query_params ('UPDATE groups SET is_template=$1 WHERE group_id=$2',
824 array ($booleanparam, $this->getID()));
826 $this->data_array['is_template']=$booleanparam;
836 * getTemplateProject - Return the project template this project is built from
838 * @return object The template project
840 function getTemplateProject() {
841 return group_get_object($this->data_array['built_from_template']);
845 * getUnixName - the unix_name
847 * @return string unix_name.
849 function getUnixName() {
850 return strtolower($this->data_array['unix_group_name']);
854 * getPublicName - the full-length public name.
856 * @return string The group_name.
858 function getPublicName() {
859 return $this->data_array['group_name'];
863 * getRegisterPurpose - the text description of the purpose of this project.
865 * @return string The description.
867 function getRegisterPurpose() {
868 return $this->data_array['register_purpose'];
872 * getDescription - the text description of this project.
874 * @return string The description.
876 function getDescription() {
877 return $this->data_array['short_description'];
881 * getStartDate - the unix time this project was registered.
883 * @return int (unix time) of registration.
885 function getStartDate() {
886 return $this->data_array['register_time'];
890 * getLogoImageID - the id of the logo in the database for this project.
892 * @return int The ID of logo image in db_images table (or 100 if none).
894 function getLogoImageID() {
895 return $this->data_array['logo_image_id'];
899 * getUnixBox - the hostname of the unix box where this project is located.
901 * @return string The name of the unix machine for the group.
903 function getUnixBox() {
904 return $this->data_array['unix_box'];
908 * getSCMBox - the hostname of the scm box where this project is located.
910 * @return string The name of the unix machine for the group.
912 function getSCMBox() {
913 return $this->data_array['scm_box'];
916 * setSCMBox - the hostname of the scm box where this project is located.
918 * @param string The name of the new SCM_BOX
920 function setSCMBox($scm_box) {
922 if ($scm_box == $this->data_array['scm_box']) {
927 $res = db_query_params ('UPDATE groups SET scm_box=$1 WHERE group_id=$2', array ($scm_box, $this->getID ()));
929 $this->addHistory('scm_box', $this->data_array['scm_box']);
930 $this->data_array['scm_box']=$scm_box;
935 $this->setError(_("Couldn't insert SCM_BOX to database"));
939 $this->setError(_("SCM Box can't be empty"));
945 * getDomain - the hostname.domain where their web page is located.
947 * @return string The name of the group [web] domain.
949 function getDomain() {
950 return $this->data_array['http_domain'];
954 * getLicense - the license they chose.
956 * @return int ident of group license.
958 function getLicense() {
959 return $this->data_array['license'];
963 * getLicenseName - the name of the license
965 * @return string license name
967 function getLicenseName() {
968 $licenses =& group_get_licenses();
969 if(isset($licenses[$this->data_array['license']])) {
970 return $licenses[$this->data_array['license']];
977 * getLicenseOther - optional string describing license.
979 * @return string The custom license.
981 function getLicenseOther() {
982 if ($this->getLicense() == GROUP_LICENSE_OTHER) {
983 return $this->data_array['license_other'];
990 * getRegistrationPurpose - the text description of the purpose of this project.
992 * @return string The application for project hosting.
994 function getRegistrationPurpose() {
995 return $this->data_array['register_purpose'];
1000 * getAdmins() - Get array of Admin user objects.
1002 * @return array Array of User objects.
1004 function &getAdmins() {
1005 $roles = RBACEngine::getInstance()->getRolesByAllowedAction ('project_admin', $this->getID()) ;
1007 $user_ids = array () ;
1009 foreach ($roles as $role) {
1010 if (! ($role instanceof RoleExplicit)) {
1013 if ($role->getHomeProject() == NULL
1014 || $role->getHomeProject()->getID() != $this->getID()) {
1018 foreach ($role->getUsers() as $u) {
1019 $user_ids[] = $u->getID() ;
1023 return user_get_objects(array_unique($user_ids));
1028 Common Group preferences for tools
1033 * enableAnonSCM - whether or not this group has opted to enable Anonymous SCM.
1035 * @return boolean enable_scm.
1037 function enableAnonSCM() {
1039 $r = RoleAnonymous::getInstance () ;
1040 return $r->hasPermission ('scm', $this->getID(), 'read') ;
1042 if ($this->isPublic() && $this->usesSCM()) {
1043 return $this->data_array['enable_anonscm'];
1050 function SetUsesAnonSCM ($booleanparam) {
1052 $booleanparam = $booleanparam ? 1 : 0 ;
1054 $r = RoleAnonymous::getInstance () ;
1055 $r->setSetting ('scm', $this->getID(), $booleanparam) ;
1058 $res = db_query_params ('UPDATE groups SET enable_anonscm=$1 WHERE group_id=$2',
1059 array ($booleanparam, $this->getID()));
1061 $this->data_array['enable_anonscm']=$booleanparam;
1070 function setUsesSCM ($booleanparam) {
1072 $booleanparam = $booleanparam ? 1 : 0 ;
1073 $res = db_query_params ('UPDATE groups SET use_scm=$1 WHERE group_id=$2',
1074 array ($booleanparam, $this->getID()));
1076 $this->data_array['use_scm']=$booleanparam;
1085 * enablePserver - whether or not this group has opted to enable Pserver.
1087 * @return boolean enable_pserver.
1089 function enablePserver() {
1090 if ($this->usesSCM()) {
1091 return $this->data_array['enable_pserver'];
1097 function SetUsesPserver ($booleanparam) {
1099 $booleanparam = $booleanparam ? 1 : 0 ;
1100 $res = db_query_params ('UPDATE groups SET enable_pserver=$1 WHERE group_id=$2',
1101 array ($booleanparam, $this->getID()));
1103 $this->data_array['enable_pserver']=$booleanparam;
1112 * usesSCM - whether or not this group has opted to use SCM.
1114 * @return boolean uses_scm.
1116 function usesSCM() {
1118 if (forge_get_config('use_scm')) {
1119 return $this->data_array['use_scm'];
1126 * setUseSCM - Set the SCM usage
1128 * @param boolean enabled/disabled
1130 function setUseSCM ($booleanparam) {
1132 $booleanparam = $booleanparam ? 1 : 0 ;
1133 $res = db_query_params ('UPDATE groups SET use_scm=$1 WHERE group_id=$2',
1134 array ($booleanparam, $this->getID()));
1136 $this->data_array['use_scm']=$booleanparam;
1146 * usesMail - whether or not this group has opted to use mailing lists.
1148 * @return boolean uses_mail.
1150 function usesMail() {
1152 if (forge_get_config('use_mail')) {
1153 return $this->data_array['use_mail'];
1160 * setUseMail - Set the mailing-list usage
1162 * @param boolean enabled/disabled
1164 function setUseMail ($booleanparam) {
1166 $booleanparam = $booleanparam ? 1 : 0 ;
1167 $res = db_query_params ('UPDATE groups SET use_mail=$1 WHERE group_id=$2',
1168 array ($booleanparam, $this->getID()));
1170 $this->data_array['use_mail']=$booleanparam;
1180 * usesNews - whether or not this group has opted to use news.
1182 * @return boolean uses_news.
1184 function usesNews() {
1186 if (forge_get_config('use_news')) {
1187 return $this->data_array['use_news'];
1194 * usesForum - whether or not this group has opted to use discussion forums.
1196 * @return boolean uses_forum.
1198 function usesForum() {
1200 if (forge_get_config('use_forum')) {
1201 return $this->data_array['use_forum'];
1208 * setUseForum - Set the forum usage
1210 * @param boolean enabled/disabled
1212 function setUseForum ($booleanparam) {
1214 $booleanparam = $booleanparam ? 1 : 0 ;
1215 $res = db_query_params ('UPDATE groups SET use_forum=$1 WHERE group_id=$2',
1216 array ($booleanparam, $this->getID()));
1218 $this->data_array['use_forum']=$booleanparam;
1228 * usesStats - whether or not this group has opted to use stats.
1230 * @return boolean uses_stats.
1232 function usesStats() {
1233 return $this->data_array['use_stats'];
1237 * usesFRS - whether or not this group has opted to use file release system.
1239 * @return boolean uses_frs.
1241 function usesFRS() {
1243 if (forge_get_config('use_frs')) {
1244 return $this->data_array['use_frs'];
1251 * setUseFRS - Set the FRS usage
1253 * @param boolean enabled/disabled
1255 function setUseFRS ($booleanparam) {
1257 $booleanparam = $booleanparam ? 1 : 0 ;
1258 $res = db_query_params ('UPDATE groups SET use_frs=$1 WHERE group_id=$2',
1259 array ($booleanparam, $this->getID()));
1261 $this->data_array['use_frs']=$booleanparam;
1271 * usesTracker - whether or not this group has opted to use tracker.
1273 * @return boolean uses_tracker.
1275 function usesTracker() {
1277 if (forge_get_config('use_tracker')) {
1278 return $this->data_array['use_tracker'];
1285 * setUseTracker - Set the tracker usage
1287 * @param boolean enabled/disabled
1289 function setUseTracker ($booleanparam) {
1291 $booleanparam = $booleanparam ? 1 : 0 ;
1292 $res = db_query_params ('UPDATE groups SET use_tracker=$1 WHERE group_id=$2',
1293 array ($booleanparam, $this->getID()));
1295 $this->data_array['use_tracker']=$booleanparam;
1305 * useCreateOnline - whether or not this group has opted to use create online documents option.
1307 * @return boolean use_docman_create_online.
1309 function useCreateOnline() {
1311 if (forge_get_config('use_docman')) {
1312 return $this->data_array['use_docman_create_online'];
1319 * usesDocman - whether or not this group has opted to use docman.
1321 * @return boolean use_docman.
1323 function usesDocman() {
1325 if (forge_get_config('use_docman')) {
1326 return $this->data_array['use_docman'];
1333 * setUseDocman - Set the docman usage
1335 * @param boolean enabled/disabled
1337 function setUseDocman ($booleanparam) {
1339 $booleanparam = $booleanparam ? 1 : 0 ;
1340 $res = db_query_params ('UPDATE groups SET use_docman=$1 WHERE group_id=$2',
1341 array ($booleanparam, $this->getID()));
1343 $this->data_array['use_docman']=$booleanparam;
1353 * useDocmanSearch - whether or not this group has opted to use docman search engine.
1355 * @return boolean use_docman_search.
1357 function useDocmanSearch() {
1359 if (forge_get_config('use_docman')) {
1360 return $this->data_array['use_docman_search'];
1367 * useWebdav - whether or not this group has opted to use webdav interface.
1369 * @return boolean use_docman_search.
1371 function useWebdav() {
1373 if (forge_get_config('use_webdav')) {
1374 return $this->data_array['use_webdav'];
1381 * usesFTP - whether or not this group has opted to use FTP.
1383 * @return boolean uses_ftp.
1385 function usesFTP() {
1387 if (forge_get_config('use_ftp')) {
1388 return $this->data_array['use_ftp'];
1395 * usesSurvey - whether or not this group has opted to use surveys.
1397 * @return boolean uses_survey.
1399 function usesSurvey() {
1401 if (forge_get_config('use_survey')) {
1402 return $this->data_array['use_survey'];
1409 * usesPM - whether or not this group has opted to Project Manager.
1411 * @return boolean uses_projman.
1415 if (forge_get_config('use_pm')) {
1416 return $this->data_array['use_pm'];
1423 * setUsePM - Set the PM usage
1425 * @param boolean enabled/disabled
1427 function setUsePM ($booleanparam) {
1429 $booleanparam = $booleanparam ? 1 : 0 ;
1430 $res = db_query_params ('UPDATE groups SET use_pm=$1 WHERE group_id=$2',
1431 array ($booleanparam, $this->getID()));
1433 $this->data_array['use_pm']=$booleanparam;
1443 * getPlugins - get a list of all available group plugins
1445 * @return array array containing plugin_id => plugin_name
1447 function getPlugins() {
1448 if (!isset($this->plugins_data)) {
1449 $this->plugins_data = array () ;
1450 $res = db_query_params ('SELECT group_plugin.plugin_id, plugins.plugin_name
1451 FROM group_plugin, plugins
1452 WHERE group_plugin.group_id=$1
1453 AND group_plugin.plugin_id=plugins.plugin_id', array ($this->getID()));
1454 $rows = db_numrows($res);
1456 for ($i=0; $i<$rows; $i++) {
1457 $plugin_id = db_result($res,$i,'plugin_id');
1458 $this->plugins_data[$plugin_id] = db_result($res,$i,'plugin_name');
1461 return $this->plugins_data ;
1465 * usesPlugin - returns true if the group uses a particular plugin
1467 * @param string name of the plugin
1468 * @return boolean whether plugin is being used or not
1470 function usesPlugin($pluginname) {
1471 $plugins_data = $this->getPlugins() ;
1472 foreach ($plugins_data as $p_id => $p_name) {
1473 if ($p_name == $pluginname) {
1480 * added for Codendi compatibility
1481 * usesServices - returns true if the group uses a particular plugin or feature
1483 * @param string name of the plugin
1484 * @return boolean whether plugin is being used or not
1486 function usesService($feature) {
1487 $plugins_data = $this->getPlugins() ;
1488 $pm = plugin_manager_get_object();
1489 foreach ($plugins_data as $p_id => $p_name) {
1490 if ($p_name == $feature) {
1493 if ($pm->getPluginByName($p_name)->provide($feature) ) {
1501 * setPluginUse - enables/disables plugins for the group
1503 * @param string name of the plugin
1504 * @param boolean the new state
1505 * @return string database result
1507 function setPluginUse($pluginname, $val=true) {
1508 if ($val == $this->usesPlugin($pluginname)) {
1509 // State is already good, returning
1512 $res = db_query_params ('SELECT plugin_id FROM plugins WHERE plugin_name=$1',
1513 array ($pluginname));
1514 $rows = db_numrows($res);
1516 // Error: no plugin by that name
1519 $plugin_id = db_result($res,0,'plugin_id');
1521 unset ($this->plugins_data) ;
1523 $res = db_query_params ('INSERT INTO group_plugin (group_id, plugin_id) VALUES ($1, $2)',
1524 array ($this->getID(),
1528 $res = db_query_params ('DELETE FROM group_plugin WHERE group_id=$1 AND plugin_id=$2',
1529 array ($this->getID(),
1536 * getDocEmailAddress - get email address(es) to send doc notifications to.
1538 * @return string email address.
1540 function getDocEmailAddress() {
1541 return $this->data_array['new_doc_address'];
1545 * DocEmailAll - whether or not this group has opted to use receive notices on all doc updates.
1547 * @return boolean email_on_all_doc_updates.
1549 function docEmailAll() {
1550 return $this->data_array['send_all_docs'];
1555 * getHomePage - The URL for this project's home page.
1557 * @return string homepage URL.
1559 function getHomePage() {
1560 return $this->data_array['homepage'];
1564 * getTags - Tags of this project.
1566 * @return string List of tags.
1568 function getTags() {
1569 $sql = 'SELECT name FROM project_tags WHERE group_id = $1';
1570 $res = db_query_params($sql, array($this->getID()));
1571 return join(', ', util_result_column_to_array($res));
1575 * setTags - Set tags of this project.
1577 * @return string database result.
1579 function setTags($tags) {
1581 $sql='DELETE FROM project_tags WHERE group_id=$1';
1582 $res=db_query_params($sql, array($this->getID()));
1584 $this->setError('Deleting old tags: '.db_error());
1588 $inserted = array();
1589 $tags_array = preg_split('/[;,]/', $tags);
1590 foreach ($tags_array as $tag) {
1591 $tag = preg_replace('/[\t\r\n]/', ' ', $tag);
1592 // Allowed caracteres: [A-Z][a-z][0-9] -_&'#+.
1593 if (preg_match('/[^[:alnum:]| |\-|_|\&|\'|#|\+|\.]/', $tag)) {
1594 $this->setError(_('Bad tag name, you only can use the following characters: [A-Z][a-z][0-9]-_&\'#+. and space'));
1599 if ($tag == '' || array_search($tag, $inserted) !== false) continue;
1600 $sql='INSERT INTO project_tags (group_id,name) VALUES ($1, $2)';
1601 $res=db_query_params($sql, array($this->getID(), $tag));
1603 $this->setError(_('Setting tags: ').db_error());
1614 * getPermission - Return a Permission for this Group
1616 * @return object The Permission.
1618 function &getPermission() {
1619 return permission_get_object($this);
1623 function delete($sure,$really_sure,$really_really_sure) {
1624 if (!$sure || !$really_sure || !$really_really_sure) {
1625 $this->setMissingParamsError();
1628 if ($this->getID() == forge_get_config('news_group') ||
1629 $this->getID() == 1 ||
1630 $this->getID() == forge_get_config('stats_group') ||
1631 $this->getID() == forge_get_config('peer_rating_group')) {
1632 $this->setError(_('Cannot Delete System Group'));
1635 $perm =& $this->getPermission ();
1636 if (!$perm || !is_object($perm)) {
1637 $this->setPermissionDeniedError();
1639 } elseif ($perm->isError()) {
1640 $this->setPermissionDeniedError();
1642 } elseif (!$perm->isSuperUser()) {
1643 $this->setPermissionDeniedError();
1649 // Remove all the members
1651 $members =& $this->getMembers();
1652 foreach ($members as $i) {
1653 $this->removeUser($i->getID());
1655 // Failsafe until user_group table is gone
1656 $res = db_query_params ('DELETE FROM user_group WHERE group_id=$1',
1657 array ($this->getID())) ;
1659 // unlink roles to this project
1660 if ($this->isPublic()) {
1661 $ra = RoleAnonymous::getInstance();
1662 $rl = RoleLoggedIn::getInstance();
1663 $ra->unlinkProject($this);
1664 $rl->unlinkProject($this);
1666 // @todo : unlink all the other roles created in the project...
1671 $atf = new ArtifactTypeFactory($this);
1672 $at_arr =& $atf->getArtifactTypes();
1673 foreach ($at_arr as $i) {
1674 if (!is_object($i)) {
1682 $ff = new ForumFactory($this);
1683 $f_arr =& $ff->getForums();
1684 foreach ($f_arr as $i) {
1685 if (!is_object($i)) {
1691 // Delete Subprojects
1693 $pgf = new ProjectGroupFactory($this);
1694 $pg_arr =& $pgf->getProjectGroups();
1695 foreach ($pg_arr as $i) {
1696 if (!is_object($i)) {
1702 // Delete FRS Packages
1704 //$frspf = new FRSPackageFactory($this);
1705 $res = db_query_params ('SELECT * FROM frs_package WHERE group_id=$1',
1706 array ($this->getID())) ;
1707 //echo 'frs_package'.db_error();
1708 //$frsp_arr =& $frspf->getPackages();
1709 while ($arr = db_fetch_array($res)) {
1710 //if (!is_object($pg_arr[$i])) {
1711 // echo "Not Object: ProjectGroup: ".$i;
1714 $frsp=new FRSPackage($this,$arr['package_id'],$arr);
1720 $news_group=group_get_object(forge_get_config('news_group'));
1721 $res = db_query_params ('SELECT forum_id FROM news_bytes WHERE group_id=$1',
1722 array ($this->getID())) ;
1724 $this->setError(_('Error Deleting News: ').db_error());
1729 for ($i=0; $i<db_numrows($res); $i++) {
1730 $Forum = new Forum($news_group,db_result($res,$i,'forum_id'));
1731 if (!$Forum->delete(1,1)) {
1732 printf (_("Could Not Delete News Forum: %d"),$Forum->getID());
1735 $res = db_query_params ('DELETE FROM news_bytes WHERE group_id=$1',
1736 array ($this->getID())) ;
1738 $this->setError(_('Error Deleting News: ').db_error());
1746 $res = db_query_params ('DELETE FROM doc_data WHERE group_id=$1',
1747 array ($this->getID())) ;
1749 $this->setError(_('Error Deleting Documents: ').db_error());
1754 $res = db_query_params ('DELETE FROM doc_groups WHERE group_id=$1',
1755 array ($this->getID())) ;
1757 $this->setError(_('Error Deleting Documents: ').db_error());
1765 $res=db_query_params('DELETE FROM project_tags WHERE group_id=$1', array($this->getID()));
1767 $this->setError(_('Error Deleting Tags: ').db_error());
1773 // Delete group history
1775 $res = db_query_params ('DELETE FROM group_history WHERE group_id=$1',
1776 array ($this->getID())) ;
1778 $this->setError(_('Error Deleting Project History: ').db_error());
1784 // Delete group plugins
1786 $res = db_query_params ('DELETE FROM group_plugin WHERE group_id=$1',
1787 array ($this->getID())) ;
1789 $this->setError(_('Error Deleting Project Plugins: ').db_error());
1795 // Delete group cvs stats
1797 $res = db_query_params ('DELETE FROM stats_cvs_group WHERE group_id=$1',
1798 array ($this->getID())) ;
1800 $this->setError(_('Error Deleting SCM Statistics: ').db_error());
1808 $sf = new SurveyFactory($this);
1809 $s_arr =& $sf->getSurveys();
1810 foreach ($s_arr as $i) {
1811 if (!is_object($i)) {
1817 // Delete SurveyQuestions
1819 $sqf = new SurveyQuestionFactory($this);
1820 $sq_arr =& $sqf->getSurveyQuestions();
1821 foreach ($sq_arr as $i) {
1822 if (!is_object($i)) {
1828 // Delete Mailing List Factory
1830 $mlf = new MailingListFactory($this);
1831 $ml_arr =& $mlf->getMailingLists();
1832 foreach ($ml_arr as $i) {
1833 if (!is_object($i)) {
1836 if (!$i->delete(1,1)) {
1837 $this->setError(_('Could not properly delete the mailing list'));
1843 $res = db_query_params ('DELETE FROM trove_group_link WHERE group_id=$1',
1844 array ($this->getID())) ;
1846 $this->setError(_('Error Deleting Trove: ').db_error());
1851 $res = db_query_params ('DELETE FROM trove_agg WHERE group_id=$1',
1852 array ($this->getID())) ;
1854 $this->setError(_('Error Deleting Trove: ').db_error());
1862 $res = db_query_params ('DELETE FROM project_sums_agg WHERE group_id=$1',
1863 array ($this->getID())) ;
1865 $this->setError(_('Error Deleting Counters: ').db_error());
1870 $res = db_query_params ('INSERT INTO deleted_groups (unix_group_name,delete_date,isdeleted) VALUES ($1, $2, $3)',
1871 array ($this->getUnixName(),
1875 $this->setError(_('Error Deleting Project: ').db_error());
1880 $res = db_query_params ('DELETE FROM groups WHERE group_id=$1',
1881 array ($this->getID())) ;
1883 $this->setError(_('Error Deleting Project: ').db_error());
1893 $hook_params = array ();
1894 $hook_params['group'] = $this;
1895 $hook_params['group_id'] = $this->getID();
1896 plugin_hook ("group_delete", $hook_params);
1898 if (forge_get_config('upload_dir') != '' && $this->getUnixName()) {
1899 exec('/bin/rm -rf '.forge_get_config('upload_dir').'/'.$this->getUnixName().'/');
1901 if (forge_get_config('ftp_upload_dir') != '' && $this->getUnixName()) {
1902 exec('/bin/rm -rf '.forge_get_config('ftp_upload_dir').'/'.$this->getUnixName().'/');
1907 $res = db_query_params ('DELETE FROM rep_group_act_monthly WHERE group_id=$1',
1908 array ($this->getID())) ;
1909 //echo 'rep_group_act_monthly'.db_error();
1910 $res = db_query_params ('DELETE FROM rep_group_act_weekly WHERE group_id=$1',
1911 array ($this->getID())) ;
1912 //echo 'rep_group_act_weekly'.db_error();
1913 $res = db_query_params ('DELETE FROM rep_group_act_daily WHERE group_id=$1',
1914 array ($this->getID())) ;
1915 //echo 'rep_group_act_daily'.db_error();
1916 unset($this->data_array);
1924 Basic functions to add/remove users to/from a group
1925 and update their permissions
1931 * addUser - controls adding a user to a group.
1933 * @param string Unix name of the user to add OR integer user_id.
1934 * @param int The role_id this user should have.
1935 * @return boolean success.
1938 function addUser($user_identifier,$role_id) {
1941 Admins can add users to groups
1944 if (!forge_check_perm ('project_admin', $this->getID())) {
1945 $this->setPermissionDeniedError();
1951 get user id for this user's unix_name
1953 if (is_int ($user_identifier)) { // user_id or user_name
1954 $res_newuser = db_query_params ('SELECT * FROM users WHERE user_id=$1', array ($user_identifier)) ;
1956 $res_newuser = db_query_params ('SELECT * FROM users WHERE user_name=$1', array ($user_identifier)) ;
1958 if (db_numrows($res_newuser) > 0) {
1960 // make sure user is active
1962 if (db_result($res_newuser,0,'status') != 'A') {
1963 $this->setError(_('User is not active. Only active users can be added.'));
1969 // user was found - set new user_id var
1971 $user_id = db_result($res_newuser,0,'user_id');
1973 $role = new Role($this,$role_id);
1974 if (!$role || !is_object($role)) {
1975 $this->setError(_('Error Getting Role Object'));
1978 } elseif ($role->isError()) {
1979 $this->setError('addUser::roleget::'.$role->getErrorMessage());
1985 $role->addUser (user_get_object ($user_id)) ;
1986 if (!$SYS->sysCheckCreateGroup($this->getID())){
1987 $this->setError($SYS->getErrorMessage());
1991 if (!$SYS->sysCheckCreateUser($user_id)) {
1992 $this->setError($SYS->getErrorMessage());
1999 // if not already a member, add them
2001 $res_member = db_query_params ('SELECT user_id
2003 WHERE user_id=$1 AND group_id=$2',
2004 array ($user_id, $this->getID())) ;
2006 if (db_numrows($res_member) < 1) {
2008 // Create this user's row in the user_group table
2010 $res = db_query_params ('INSERT INTO user_group
2011 (user_id,group_id,admin_flags,forum_flags,project_flags,
2012 doc_flags,cvs_flags,member_role,release_flags,artifact_flags)
2013 VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10)',
2025 //verify the insert worked
2026 if (!$res || db_affected_rows($res) < 1) {
2027 $this->setError(sprintf(_('ERROR: Could Not Add User To Group: %s'),db_error()));
2032 // check and create if group doesn't exists
2034 //echo "<h2>Group::addUser SYS->sysCheckCreateGroup(".$this->getID().")</h2>";
2035 if (!$SYS->sysCheckCreateGroup($this->getID())){
2036 $this->setError($SYS->getErrorMessage());
2041 // check and create if user doesn't exists
2043 //echo "<h2>Group::addUser SYS->sysCheckCreateUser($user_id)</h2>";
2044 if (!$SYS->sysCheckCreateUser($user_id)) {
2045 $this->setError($SYS->getErrorMessage());
2052 //echo "<h2>Group::addUser role->setUser($user_id)</h2>";
2053 if (!$role->setUser($user_id)) {
2054 $this->setError('addUser::role::setUser'.$role->getErrorMessage());
2060 // user was already a member
2061 // make sure they are set up
2063 $user=&user_get_object($user_id,$res_newuser);
2064 $user->fetchData($user->getID());
2065 $role = new Role($this,$role_id);
2066 if (!$role || !is_object($role)) {
2067 $this->setError(_('Error Getting Role Object'));
2070 } elseif ($role->isError()) {
2071 $this->setError('addUser::roleget::'.$role->getErrorMessage());
2075 //echo "<h2>Already Member Group::addUser role->setUser($user_id)</h2>";
2076 if (!$role->setUser($user_id)) {
2077 $this->setError('addUser::role::setUser'.$role->getErrorMessage());
2082 // set up their system info
2084 //echo "<h2>Already Member Group::addUser SYS->sysCheckCreateUser($user_id)</h2>";
2085 if (!$SYS->sysCheckCreateUser($user_id)) {
2086 $this->setError($SYS->getErrorMessage());
2094 // user doesn't exist
2096 $this->setError(_('ERROR: User does not exist'));
2101 $hook_params['group'] = $this;
2102 $hook_params['group_id'] = $this->getID();
2103 $hook_params['user'] = &user_get_object($user_id);
2104 $hook_params['user_id'] = $user_id;
2105 plugin_hook ("group_adduser", $hook_params);
2110 $this->addHistory('Added User',$user_identifier);
2116 * removeUser - controls removing a user from a group.
2118 * Users can remove themselves.
2120 * @param int The ID of the user to remove.
2121 * @return boolean success.
2123 function removeUser($user_id) {
2126 if ($user_id != user_getid()
2127 || !forge_check_perm ('project_admin', $this->getID())) {
2128 $this->setPermissionDeniedError();
2135 $user = user_get_object ($user_id) ;
2136 $roles = RBACEngine::getInstance()->getAvailableRolesForUser ($user) ;
2137 $found_role = NULL ;
2138 foreach ($roles as $role) {
2139 if ($role->getHomeProject() && $role->getHomeProject()->getID() == $this->getID()) {
2140 $found_role = $role ;
2144 if ($found_role == NULL) {
2145 $this->setError(sprintf(_('ERROR: User not removed: %s')));
2149 $found_role->removeUser ($user) ;
2150 if (!$SYS->sysGroupCheckUser($this->getID(),$user_id)) {
2151 $this->setError($SYS->getErrorMessage());
2157 $res = db_query_params ('DELETE FROM user_group WHERE group_id=$1 AND user_id=$2',
2158 array ($this->getID(),
2160 if (!$res || db_affected_rows($res) < 1) {
2161 $this->setError(sprintf(_('ERROR: User not removed: %s'),db_error()));
2168 // reassign open artifacts to id=100
2170 $res = db_query_params ('UPDATE artifact SET assigned_to=100
2171 WHERE group_artifact_id
2172 IN (SELECT group_artifact_id
2173 FROM artifact_group_list
2174 WHERE group_id=$1 AND status_id=1 AND assigned_to=$2)',
2175 array ($this->getID(),
2178 $this->setError(sprintf(_('ERROR: DB: artifact: %s'),db_error()));
2184 // reassign open tasks to id=100
2185 // first have to purge any assignments that would cause
2186 // conflict with existing assignment to 100
2188 $res = db_query_params ('DELETE FROM project_assigned_to
2189 WHERE project_task_id IN (SELECT pt.project_task_id
2190 FROM project_task pt, project_group_list pgl, project_assigned_to pat
2191 WHERE pt.group_project_id = pgl.group_project_id
2192 AND pat.project_task_id=pt.project_task_id
2193 AND pt.status_id=1 AND pgl.group_id=$1
2194 AND pat.assigned_to_id=$2)
2195 AND assigned_to_id=100',
2196 array ($this->getID(),
2199 $this->setError(sprintf(_('ERROR: DB: project_assigned_to %d: %s'),1,db_error()));
2203 $res = db_query_params ('UPDATE project_assigned_to SET assigned_to_id=100
2204 WHERE project_task_id IN (SELECT pt.project_task_id
2205 FROM project_task pt, project_group_list pgl
2206 WHERE pt.group_project_id = pgl.group_project_id
2207 AND pt.status_id=1 AND pgl.group_id=$1)
2208 AND assigned_to_id=$2',
2209 array ($this->getID(),
2212 $this->setError(sprintf(_('ERROR: DB: project_assigned_to %d: %s'),2,db_error()));
2218 // Remove user from system
2220 if (!$SYS->sysGroupRemoveUser($this->getID(),$user_id)) {
2221 $this->setError($SYS->getErrorMessage());
2226 $hook_params['group'] = $this;
2227 $hook_params['group_id'] = $this->getID();
2228 $hook_params['user'] = &user_get_object($user_id);
2229 $hook_params['user_id'] = $user_id;
2230 plugin_hook ("group_removeuser", $hook_params);
2233 $this->addHistory('Removed User',$user_id);
2240 * updateUser - controls updating a user's role in this group.
2242 * @param int The ID of the user.
2243 * @param int The role_id to set this user to.
2244 * @return boolean success.
2246 function updateUser($user_id,$role_id) {
2249 if (!forge_check_perm ('project_admin', $this->getID())) {
2250 $this->setPermissionDeniedError();
2255 $newrole = RBACEngine::getInstance()->getRoleById ($role_id) ;
2256 if (!$newrole || !is_object($newrole)) {
2257 $this->setError(_('Could Not Get Role'));
2259 } elseif ($newrole->isError()) {
2260 $this->setError(sprintf(_('Role: %s'),$role->getErrorMessage()));
2262 } elseif ($newrole->getHomeProject() == NULL
2263 || $newrole->getHomeProject()->getID() != $this->getID()) {
2264 $this->setError(_('Wrong destination role'));
2267 $user = user_get_object ($user_id) ;
2268 $roles = RBACEngine::getInstance()->getAvailableRolesForUser ($user) ;
2269 $found_role = NULL ;
2270 foreach ($roles as $role) {
2271 if ($role->getHomeProject() && $role->getHomeProject()->getID() == $this->getID()) {
2272 $found_role = $role ;
2276 if ($found_role == NULL) {
2277 $this->setError(sprintf(_('ERROR: User not removed: %s')));
2281 $found_role->removeUser ($user) ;
2282 $newrole->addUser ($user) ;
2284 $role = new Role($this,$role_id);
2285 if (!$role || !is_object($role)) {
2286 $this->setError(_('Could Not Get Role'));
2288 } elseif ($role->isError()) {
2289 $this->setError(sprintf(_('Role: %s'),$role->getErrorMessage()));
2292 //echo "<h3>Group::updateUser role->setUser($user_id)</h3>";
2293 if (!$role->setUser($user_id)) {
2294 $this->setError(sprintf(_('Role: %s'),$role->getErrorMessage()));
2299 $this->addHistory('Updated User',$user_id);
2304 * addHistory - Makes an audit trail entry for this project.
2306 * @param string The name of the field.
2307 * @param string The Old Value for this $field_name.
2308 * @return database result handle.
2311 function addHistory($field_name, $old_value) {
2312 return db_query_params ('INSERT INTO group_history(group_id,field_name,old_value,mod_by,adddate)
2313 VALUES ($1,$2,$3,$4,$5)',
2314 array ($this->getID(),
2322 * activateUsers - Make sure that group members have unix accounts.
2324 * Setup unix accounts for group members. Can be called even
2325 * if members are already active.
2329 function activateUsers() {
2331 Activate member(s) of the project
2335 $members = $this->getUsers (true) ;
2337 foreach ($members as $member) {
2339 foreach (RBACEngine::getInstance()->getAvailableRolesForUser ($member) as $role) {
2340 if ($role->getHomeProject() && $role->getHomeProject()->getID() == $this->getID()) {
2343 if (!$this->addUser($member->getUnixName(),$role->getID())) {
2350 $res_member = db_query_params ('SELECT user_id,role_id FROM user_group WHERE group_id=$1',
2351 array ($this->getID())) ;
2352 while ($row_member = db_fetch_array($res_member)) {
2353 $u = user_get_object($row_member['user_id']) ;
2354 if (!$this->addUser($u->getUnixName(),$row_member['role_id'])) {
2364 * getMembers - returns array of User objects for this project
2366 * @return array of User objects for this group.
2368 function getMembers() {
2369 return $this->getUsers (true) ;
2373 * replaceTemplateStrings - fill-in some blanks with project name
2375 * @param string Template string
2376 * @return string String after replacements
2378 function replaceTemplateStrings($string) {
2379 $string = str_replace ('UNIXNAME', $this->getUnixName(), $string) ;
2380 $string = str_replace ('PUBLICNAME', $this->getPublicName(), $string) ;
2381 $string = str_replace ('DESCRIPTION', $this->getDescription(), $string) ;
2386 * approve - Approve pending project.
2388 * @param object The User object who is doing the updating.
2391 function approve(&$user) {
2393 require_once $gfcommon.'widget/WidgetLayoutManager.class.php';
2395 if ($this->getStatus()=='A') {
2396 $this->setError(_("Group already active"));
2402 // Step 1: Activate group and create LDAP entries
2403 if (!$this->setStatus($user, 'A')) {
2408 // Switch to system language for item creation
2409 setup_gettext_from_sys_lang ();
2411 // Create default roles
2413 $idadmin_group = NULL ;
2414 foreach (get_group_join_requests ($this) as $gjr) {
2415 $idadmin_group = $gjr->getUserID() ;
2418 if ($idadmin_group == NULL) {
2419 $idadmin_group = $user->getID();
2422 $admin_group = db_query_params ('SELECT user_id FROM user_group WHERE group_id=$1 AND admin_flags=$2',
2423 array ($this->getID(),
2425 if (db_numrows($admin_group) > 0) {
2426 $idadmin_group = db_result($admin_group,0,'user_id');
2428 $idadmin_group = $user->getID();
2429 db_query_params ('INSERT INTO user_group (user_id, group_id, admin_flags) VALUES ($1, $2, $3)',
2430 array ($idadmin_group,
2436 $template = $this->getTemplateProject() ;
2437 $id_mappings = array ();
2438 $seen_local_roles = false ;
2440 // Copy roles from template project
2441 foreach ($template->getRoles() as $oldrole) {
2442 if ($oldrole->getHomeProject() != NULL) {
2443 $role = new Role ($this) ;
2445 // Need to use a different role name so that the permissions aren't set from the hardcoded defaults
2446 $role->create ('TEMPORARY ROLE NAME', $data, true) ;
2447 $role->setName ($oldrole->getName()) ;
2448 $seen_local_roles = true ;
2451 $role->linkProject ($this) ;
2453 $id_mappings['role'][$oldrole->getID()] = $role->getID() ;
2454 // Reuse the project_admin permission
2455 $role->setSetting ('project_admin', $this->getID(), $oldrole->getSetting ('project_admin', $template->getID())) ;
2459 if (!$seen_local_roles) {
2460 $role = new Role($this);
2461 $adminperms = array ('project_admin' => array ($this->getID() => 1)) ;
2462 $role_id = $role->create ('Admin', $adminperms, true) ;
2466 $roles = $this->getRoles() ;
2467 foreach ($roles as $r) {
2468 if ($r->getSetting ('project_admin', $this->getID())) {
2469 $r->addUser (user_get_object ($idadmin_group)) ;
2474 // Temporarily switch to the submitter's identity
2475 $saved_session = session_get_user () ;
2476 session_set_internal ($idadmin_group) ;
2479 if (forge_get_config ('use_tracker')) {
2480 $this->setUseTracker ($template->usesTracker()) ;
2481 if ($template->usesTracker()) {
2482 $oldatf = new ArtifactTypeFactory ($template) ;
2483 foreach ($oldatf->getArtifactTypes() as $o) {
2484 $t = new ArtifactType ($this) ;
2485 $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()) ;
2486 $id_mappings['tracker'][$o->getID()] = $t->getID() ;
2487 $t->cloneFieldsFrom ($o->getID()) ;
2492 if (forge_get_config ('use_pm')) {
2493 $this->setUsePM ($template->usesPM()) ;
2494 if ($template->usesPM()) {
2495 $oldpgf = new ProjectGroupFactory ($template) ;
2496 foreach ($oldpgf->getProjectGroups() as $o) {
2497 $pg = new ProjectGroup ($this) ;
2498 $pg->create ($this->replaceTemplateStrings($o->getName()),$this->replaceTemplateStrings($o->getDescription()),$o->isPublic(),$o->getSendAllPostsTo()) ;
2499 $id_mappings['pm'][$o->getID()] = $pg->getID() ;
2504 if (forge_get_config ('use_forum')) {
2505 $this->setUseForum ($template->usesForum()) ;
2506 if ($template->usesForum()) {
2507 $oldff = new ForumFactory ($template) ;
2508 foreach ($oldff->getForums() as $o) {
2509 $f = new Forum ($this) ;
2510 $f->create ($this->replaceTemplateStrings($o->getName()),$this->replaceTemplateStrings($o->getDescription()),$o->isPublic(),$o->getSendAllPostsTo(),1,$o->allowAnonymous(),$o->getModerationLevel()) ;
2511 $id_mappings['forum'][$o->getID()] = $f->getID() ;
2516 if (forge_get_config ('use_docman')) {
2517 $this->setUseDocman ($template->usesDocman()) ;
2518 if ($template->usesDocman()) {
2519 $olddgf = new DocumentGroupFactory ($template) ;
2520 // First pass: create all docgroups
2521 $id_mappings['docman_docgroup'][0] = 0 ;
2522 foreach ($olddgf->getDocumentGroups() as $o) {
2523 $ndgf = new DocumentGroup ($this) ;
2524 $ndgf->create($this->replaceTemplateStrings($o->getName())) ;
2525 $id_mappings['docman_docgroup'][$o->getID()] = $ndgf->getID() ;
2527 // Second pass: restore hierarchy links
2528 foreach ($olddgf->getDocumentGroups() as $o) {
2529 $ndgf = new DocumentGroup ($this) ;
2530 $ndgf->fetchData ($id_mappings['docman_docgroup'][$o->getID()]) ;
2531 $ndgf->update ($ndgf->getName(),$id_mappings['docman_docgroup'][$o->getParentID()]) ;
2536 if (forge_get_config ('use_frs')) {
2537 $this->setUseFRS ($template->usesFRS()) ;
2538 if ($template->usesFRS()) {
2539 foreach (get_frs_packages ($template) as $o) {
2540 $newp = new FRSPackage ($this) ;
2541 $nname = $this->replaceTemplateStrings($o->getName()) ;
2542 $newp->create ($nname, $o->isPublic()) ;
2547 if (forge_get_config ('use_mail')) {
2548 $this->setUseMail ($template->usesMail()) ;
2549 if ($template->usesMail()) {
2550 $oldmlf = new MailingListFactory ($template) ;
2551 foreach ($oldmlf->getMailingLists() as $o) {
2552 $ml = new MailingList ($this) ;
2553 $nname = preg_replace ('/^'.$template->getUnixName().'-/','',$o->getName()) ;
2555 $ndescription = $this->replaceTemplateStrings($o->getDescription()) ;
2556 $ml->create ($nname, $ndescription, $o->isPublic()) ;
2561 $this->setUseSCM ($template->usesSCM()) ;
2563 foreach ($template->getPlugins() as $plugin_id => $plugin_name) {
2564 $this->setPluginUse ($plugin_name) ;
2567 foreach ($template->getRoles() as $oldrole) {
2568 $newrole = RBACEngine::getInstance()->getRoleById ($id_mappings['role'][$oldrole->getID()]) ;
2569 if ($oldrole->getHomeProject() != NULL
2570 && $oldrole->getHomeProject()->getID() == $template->getID()) {
2571 $newrole->setPublic ($oldrole->isPublic()) ;
2573 $oldsettings = $oldrole->getSettingsForProject ($template) ;
2575 $sections = array ('project_read', 'project_admin', 'frs', 'scm', 'docman', 'tracker_admin', 'new_tracker', 'forum_admin', 'new_forum', 'pm_admin', 'new_pm') ;
2576 foreach ($sections as $section) {
2577 $newrole->setSetting ($section, $this->getID(), $oldsettings[$section][$template->getID()]) ;
2580 $sections = array ('tracker', 'pm', 'forum') ;
2581 foreach ($sections as $section) {
2582 if (isset ($oldsettings[$section])) {
2583 foreach ($oldsettings[$section] as $k => $v) {
2584 // Only copy perms for tools that have been copied
2585 if (isset ($id_mappings[$section][$k])) {
2586 $newrole->setSetting ($section,
2587 $id_mappings[$section][$k],
2595 $lm = new WidgetLayoutManager();
2596 $lm->createDefaultLayoutForProject ($this->getID(), $template->getID()) ;
2598 $params = array () ;
2599 $params['template'] = $template ;
2600 $params['project'] = $this ;
2601 $params['id_mappings'] = $id_mappings ;
2602 plugin_hook_by_reference ('clone_project_from_template', $params) ;
2604 // Disable everything
2605 $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',
2607 array ($this->getID())) ;
2610 $this->normalizeAllRoles () ;
2612 // Switch back to user preference
2613 session_set_internal ($saved_session->getID()) ;
2614 setup_gettext_from_context();
2618 $this->sendApprovalEmail();
2619 $this->addHistory('Approved', 'x');
2622 // Plugin can make approve operation there
2625 $params[0] = $idadmin_group ;
2626 $params[1] = $this->getID();
2627 plugin_hook('group_approved',$params);
2635 * sendApprovalEmail - Send new project email.
2637 * @return boolean success.
2640 function sendApprovalEmail() {
2641 $admins = RBACEngine::getInstance()->getUsersByAllowedAction ('project_admin', $this->getID()) ;
2643 if (count($admins) < 1) {
2644 $this->setError(_("Group does not have any administrators."));
2648 // send one email per admin
2649 foreach ($admins as $admin) {
2650 setup_gettext_for_user ($admin) ;
2652 $message=sprintf(_('Your project registration for %4$s has been approved.
2654 Project Full Name: %1$s
2655 Project Unix Name: %2$s
2657 Your DNS will take up to a day to become active on our site.
2658 Your web site is accessible through your shell account. Please read
2659 site documentation (see link below) about intended usage, available
2660 services, and directory layout of the account.
2663 own project page in %4$s while logged in, you will find
2664 additional menu functions to your left labeled \'Project Admin\'.
2666 We highly suggest that you now visit %4$s and create a public
2667 description for your project. This can be done by visiting your project
2668 page while logged in, and selecting \'Project Admin\' from the menus
2669 on the left (or by visiting %3$s
2672 Your project will also not appear in the Trove Software Map (primary
2673 list of projects hosted on %4$s which offers great flexibility in
2674 browsing and search) until you categorize it in the project administration
2675 screens. So that people can find your project, you should do this now.
2676 Visit your project while logged in, and select \'Project Admin\' from the
2679 Enjoy the system, and please tell others about %4$s. Let us know
2680 if there is anything we can do to help you.
2683 htmlspecialchars_decode($this->getPublicName()),
2684 $this->getUnixName(),
2685 util_make_url ('/project/admin/?group_id='.$this->getID()),
2686 forge_get_config ('forge_name'));
2688 util_send_message($admin->getEmail(), sprintf(_('%1$s Project Approved'), forge_get_config ('forge_name')), $message);
2690 setup_gettext_from_context();
2698 * sendRejectionEmail - Send project rejection email.
2700 * This function sends out a rejection message to a user who
2701 * registered a project.
2703 * @param int The id of the response to use.
2704 * @param string The rejection message.
2705 * @return completion status.
2708 function sendRejectionEmail($response_id, $message="zxcv") {
2709 $submitters = array () ;
2711 foreach (get_group_join_requests ($this) as $gjr) {
2712 $submitters[] = user_get_object($gjr->getUserID()) ;
2715 $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",
2717 while ($arr = db_fetch_array ($res)) {
2718 $submitter[] =& user_get_object($arr['user_id']);
2722 if (count ($submitters) < 1) {
2723 $this->setError(_("Group does not have any administrators."));
2727 foreach ($submitters as $admin) {
2728 setup_gettext_for_user ($admin) ;
2730 $response=sprintf(_('Your project registration for %3$s has been denied.
2732 Project Full Name: %1$s
2733 Project Unix Name: %2$s
2735 Reasons for negative decision:
2737 '), $this->getPublicName(), $this->getUnixName(), forge_get_config ('forge_name'));
2739 // Check to see if they want to send a custom rejection response
2740 if ($response_id == 0) {
2741 $response .= $message;
2743 $response .= db_result (
2744 db_query_params('SELECT response_text FROM canned_responses WHERE response_id=$1', array ($response_id)),
2749 util_send_message($admin->getEmail(), sprintf(_('%1$s Project Denied'), forge_get_config ('forge_name')), $response);
2750 setup_gettext_from_context();
2757 * sendNewProjectNotificationEmail - Send new project notification email.
2759 * This function sends out a notification email to the
2760 * SourceForge admin user when a new project is
2763 * @return boolean success.
2766 function sendNewProjectNotificationEmail() {
2767 // Get the user who wants to register the project
2768 $submitters = array () ;
2770 foreach (get_group_join_requests ($this) as $gjr) {
2771 $submitters[] = user_get_object($gjr->getUserID()) ;
2774 $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",
2776 while ($arr = db_fetch_array ($res)) {
2777 $submitter[] =& user_get_object($arr['user_id']);
2780 if (count ($submitters) < 1) {
2781 $this->setError(_("Could not find user who has submitted the project."));
2785 $admins = RBACEngine::getInstance()->getUsersByAllowedAction ('approve_projects', -1) ;
2787 if (count($admins) < 1) {
2788 $this->setError(_("There is no administrator to send the mail to."));
2792 foreach ($admins as $admin) {
2793 $admin_email = $admin->getEmail () ;
2794 setup_gettext_for_user ($admin) ;
2796 foreach ($submitters as $u) {
2797 $submitter_names[] = $u->getRealName() ;
2800 $message = sprintf(_('New %1$s Project Submitted
2802 Project Full Name: %2$s
2803 Submitted Description: %3$s
2805 forge_get_config ('forge_name'),
2806 htmlspecialchars_decode($this->getPublicName()),
2807 htmlspecialchars_decode($this->getRegistrationPurpose()));
2809 foreach ($submitters as $submitter) {
2810 $message .= sprintf(_('Submitter: %1$s (%2$s)
2812 $submitter->getRealName(),
2813 $submitter->getUnixName());
2816 $message .= sprintf (_('
2817 Please visit the following URL to approve or reject this project:
2819 util_make_url ('/admin/approve-pending.php')) ;
2820 util_send_message($admin_email, sprintf(_('New %1$s Project Submitted'), forge_get_config ('forge_name')), $message);
2821 setup_gettext_from_context();
2825 $email = $submitter->getEmail() ;
2826 setup_gettext_for_user ($submitter) ;
2828 $message=sprintf(_('New %1$s Project Submitted
2830 Project Full Name: %2$s
2831 Submitted Description: %3$s
2833 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'));
2835 util_send_message($email, sprintf(_('New %1$s Project Submitted'), forge_get_config ('forge_name')), $message);
2836 setup_gettext_from_context();
2845 * validateGroupName - Validate the group name
2847 * @param string Group name.
2849 * @return an error false and set an error is the group name is invalide otherwise return true
2851 function validateGroupName($group_name) {
2852 if (strlen($group_name)<3) {
2853 $this->setError(_('Group name is too short'));
2855 } else if (strlen(htmlspecialchars($group_name))>50) {
2856 $this->setError(_('Group name is too long'));
2858 } else if ($group=group_get_object_by_publicname($group_name)) {
2859 $this->setError(_('Group name already taken'));
2867 * getRoles - Get the roles of the group.
2869 * @return array of Role id of this group.
2871 function getRolesId () {
2872 $role_ids = array () ;
2875 $res = db_query_params ('SELECT role_id FROM pfo_role WHERE home_group_id=$1',
2876 array ($this->getID()));
2877 while ($arr = db_fetch_array($res)) {
2878 $role_ids[] = $arr['role_id'] ;
2880 $res = db_query_params ('SELECT role_id FROM role_project_refs WHERE group_id=$1',
2881 array ($this->getID()));
2882 while ($arr = db_fetch_array($res)) {
2883 $role_ids[] = $arr['role_id'] ;
2886 $res = db_query_params ('SELECT role_id FROM role WHERE group_id=$1',
2887 array ($this->getID()));
2888 while ($arr = db_fetch_array($res)) {
2889 $role_ids[] = $arr['role_id'] ;
2893 return array_unique ($role_ids) ;
2896 function getRoles () {
2897 $result = array () ;
2899 $roles = $this->getRolesId () ;
2901 $engine = RBACEngine::getInstance() ;
2902 foreach ($roles as $role_id) {
2903 $result[] = $engine->getRoleById ($role_id) ;
2906 foreach ($roles as $role_id) {
2907 $result[] = new Role ($this, $role_id) ;
2914 function normalizeAllRoles () {
2915 $roles = $this->getRoles () ;
2917 foreach ($roles as $r) {
2918 $r->normalizeData () ;
2923 * getUnixStatus - Status of activation of unix account.
2925 * @return char (N)one, (A)ctive, (S)uspended or (D)eleted
2927 function getUnixStatus() {
2928 return $this->data_array['unix_status'];
2932 * setUnixStatus - Sets status of activation of unix account.
2934 * @param string The unix status.
2940 * @return boolean success.
2942 function setUnixStatus($status) {
2945 $res = db_query_params ('UPDATE groups SET unix_status=$1 WHERE group_id=$2',
2950 $this->setError(sprintf(_('ERROR - Could Not Update Group Unix Status: %s'),db_error()));
2954 if ($status == 'A') {
2955 if (!$SYS->sysCheckCreateGroup($this->getID())) {
2956 $this->setError($SYS->getErrorMessage());
2961 if ($SYS->sysCheckGroup($this->getID())) {
2962 if (!$SYS->sysRemoveGroup($this->getID())) {
2963 $this->setError($SYS->getErrorMessage());
2970 $this->data_array['unix_status']=$status;
2977 * getUsers - Get the users of a group
2979 * @return array of user's objects.
2981 function getUsers($onlylocal = true) {
2982 if (!isset($this->membersArr)) {
2983 $this->membersArr = array () ;
2987 foreach ($this->getRoles() as $role) {
2989 && ($role->getHomeProject() == NULL || $role->getHomeProject()->getID() != $this->getID())) {
2992 foreach ($role->getUsers() as $user) {
2993 $ids[] = $user->getID() ;
2996 $ids = array_unique ($ids) ;
2997 foreach ($ids as $id) {
2998 $u = user_get_object ($id) ;
2999 if ($u->isActive()) {
3000 $this->membersArr[] = $u ;
3005 $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',
3006 array ($this->getID(),
3008 if (!$users_group_res) {
3009 $this->setError(_('Error: Enable to get users from group'). ' ' . $this->getID() . ' ' .db_error());
3013 for ($i=0; $i<db_numrows($users_group_res); $i++) {
3014 $this->membersArr[$i] = new GFUser(db_result($users_group_res,$i,'user_id'),false);
3019 return $this->membersArr;
3022 function setDocmanCreateOnlineStatus($status) {
3024 /* if we activate search engine, we probably want to reindex */
3025 $res = db_query_params ('UPDATE groups SET use_docman_create_online=$1 WHERE group_id=$2',
3030 $this->setError(sprintf(_('ERROR - Could Not Update Group DocmanCreateOnline Status: %s'),db_error()));
3034 $this->data_array['use_docman_create_online']=$status;
3040 function setDocmanWebdav($status) {
3042 /* if we activate search engine, we probably want to reindex */
3043 $res = db_query_params ('UPDATE groups SET use_webdav=$1 WHERE group_id=$2',
3048 $this->setError(sprintf(_('ERROR - Could Not Update Group UseWebdab Status: %s'),db_error()));
3052 $this->data_array['use_webdav']=$status;
3058 function setDocmanSearchStatus($status) {
3060 /* if we activate search engine, we probably want to reindex */
3061 $res = db_query_params ('UPDATE groups SET use_docman_search=$1, force_docman_reindex=$1 WHERE group_id=$2',
3066 $this->setError(sprintf(_('ERROR - Could Not Update Group UseDocmanSearch Status: %s'),db_error()));
3070 $this->data_array['use_docman_search']=$status;
3076 function setDocmanForceReindexSearch($status) {
3078 /* if we activate search engine, we probably want to reindex */
3079 $res = db_query_params ('UPDATE groups SET force_docman_reindex=$1 WHERE group_id=$2',
3084 $this->setError(sprintf(_('ERROR - Could Not Update Group force_docman_reindex %s'),db_error()));
3088 $this->data_array['force_docman_reindex']=$status;
3094 function setStorageAPI($type) {
3098 function getStorageAPI() {
3104 * group_getname() - get the group name
3106 * @param int The group ID
3110 function group_getname ($group_id = 0) {
3111 $grp = group_get_object($group_id);
3113 return $grp->getPublicName();
3120 * group_getunixname() - get the unixname for a group
3122 * @param int The group ID
3126 function group_getunixname ($group_id) {
3127 $grp = group_get_object($group_id);
3129 return $grp->getUnixName();
3136 * group_get_result() - Get the group object result ID.
3138 * @param int The group ID
3142 function &group_get_result($group_id=0) {
3143 $grp = group_get_object($group_id);
3145 return $grp->getData();
3151 class ProjectComparator {
3152 var $criterion = 'name' ;
3154 function Compare ($a, $b) {
3155 switch ($this->criterion) {
3158 $namecmp = strcoll ($a->getPublicName(), $b->getPublicName()) ;
3159 if ($namecmp != 0) {
3162 /* If several projects share a same public name */
3163 return strcoll ($a->getUnixName(), $b->getUnixName()) ;
3166 return strcmp ($a->getUnixName(), $b->getUnixName()) ;
3169 $aid = $a->getID() ;
3170 $bid = $b->getID() ;
3174 return ($a < $b) ? -1 : 1;
3180 function sortProjectList (&$list, $criterion='name') {
3181 $cmp = new ProjectComparator () ;
3182 $cmp->criterion = $criterion ;
3184 return usort ($list, array ($cmp, 'Compare')) ;
3189 // c-file-style: "bsd"