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. FusionForge is free software;
11 * you can redistribute it and/or modify it under the terms of the
12 * GNU General Public License as published by the Free Software
13 * Foundation; either version 2 of the Licence, or (at your option)
16 * FusionForge is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
21 * You should have received a copy of the GNU General Public License along
22 * with FusionForge; if not, write to the Free Software Foundation, Inc.,
23 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
26 require_once $gfcommon.'tracker/ArtifactTypes.class.php';
27 require_once $gfcommon.'tracker/ArtifactTypeFactory.class.php';
28 require_once $gfcommon.'forum/Forum.class.php';
29 require_once $gfcommon.'forum/ForumFactory.class.php';
30 require_once $gfcommon.'pm/ProjectGroup.class.php';
31 require_once $gfcommon.'pm/ProjectGroupFactory.class.php';
32 require_once $gfcommon.'include/Role.class.php';
33 require_once $gfcommon.'frs/FRSPackage.class.php';
34 require_once $gfcommon.'docman/DocumentGroup.class.php';
35 require_once $gfcommon.'docman/DocumentGroupFactory.class.php';
36 require_once $gfcommon.'mail/MailingList.class.php';
37 require_once $gfcommon.'mail/MailingListFactory.class.php';
38 require_once $gfcommon.'survey/SurveyFactory.class.php';
39 require_once $gfcommon.'survey/SurveyQuestionFactory.class.php';
40 require_once $gfcommon.'include/gettext.php';
41 require_once $gfcommon.'include/GroupJoinRequest.class.php';
43 //the license_id of "Other/proprietary" license
44 define('GROUP_LICENSE_OTHER',126);
46 $LICENSE_NAMES=array();
49 * group_get_licences() - get the licenses list
51 * @return array list of licenses
53 function & group_get_licenses() {
54 global $LICENSE_NAMES;
55 if(empty($LICENSE_NAMES)) {
56 $result = db_query_params ('SELECT * FROM licenses', array());
57 while($data = db_fetch_array($result)) {
58 $LICENSE_NAMES[$data['license_id']] = $data['license_name'];
61 return $LICENSE_NAMES;
67 * group_get_object() - Get the group object.
69 * group_get_object() is useful so you can pool group objects/save database queries
70 * You should always use this instead of instantiating the object directly.
72 * You can now optionally pass in a db result handle. If you do, it re-uses that query
73 * to instantiate the objects.
75 * IMPORTANT! That db result must contain all fields
76 * from groups table or you will have problems
79 * @param int Result set handle ("SELECT * FROM groups WHERE group_id=xx")
80 * @return a group object or false on failure
82 function &group_get_object($group_id,$res=false) {
83 //create a common set of group objects
84 //saves a little wear on the database
86 //automatically checks group_type and
87 //returns appropriate object
90 if (!isset($GROUP_OBJ["_".$group_id."_"])) {
92 //the db result handle was passed in
94 $res = db_query_params ('SELECT * FROM groups WHERE group_id=$1', array ($group_id)) ;
96 if (!$res || db_numrows($res) < 1) {
97 $GROUP_OBJ["_".$group_id."_"]=false;
100 check group type and set up object
102 if (db_result($res,0,'type_id')==1) {
104 $GROUP_OBJ["_".$group_id."_"]= new Group($group_id,$res);
107 $GROUP_OBJ["_".$group_id."_"]=false;
111 return $GROUP_OBJ["_".$group_id."_"];
114 function &group_get_objects($id_arr) {
117 // Note: if we don't do this, the result may be corrupted
121 foreach ($id_arr as $id) {
123 // See if this ID already has been fetched in the cache
125 if (!isset($GROUP_OBJ["_".$id."_"])) {
129 if (count($fetch) > 0) {
130 $res=db_query_params ('SELECT * FROM groups WHERE group_id = ANY ($1)',
131 array (db_int_array_to_any_clause ($fetch))) ;
132 while ($arr = db_fetch_array($res)) {
133 $GROUP_OBJ["_".$arr['group_id']."_"] = new Group($arr['group_id'],$arr);
136 foreach ($id_arr as $id) {
137 $return[] =& $GROUP_OBJ["_".$id."_"];
142 function &group_get_active_projects() {
143 $res=db_query_params ('SELECT group_id FROM groups WHERE status=$1',
145 return group_get_objects (util_result_column_to_array($res,0)) ;
148 function &group_get_template_projects() {
149 $res=db_query_params ('SELECT group_id FROM groups WHERE is_template=1 AND status != $1',
151 return group_get_objects (util_result_column_to_array($res,0)) ;
154 function &group_get_object_by_name($groupname) {
155 $res=db_query_params('SELECT * FROM groups WHERE unix_group_name=$1', array ($groupname)) ;
156 return group_get_object(db_result($res,0,'group_id'),$res);
159 function &group_get_objects_by_name($groupname_arr) {
160 $res=db_query_params ('SELECT group_id FROM groups WHERE unix_group_name = ANY ($1)',
161 array (db_string_array_to_any_clause ($groupname_arr))
163 $arr =& util_result_column_to_array($res,0);
164 return group_get_objects($arr);
167 function &group_get_object_by_publicname($groupname) {
168 $res=db_query_params ('SELECT * FROM groups WHERE lower(group_name) LIKE $1',
169 array (htmlspecialchars (strtolower ($groupname)))) ;
171 return group_get_object(db_result($res,0,'group_id'),$res);
174 class Group extends Error {
176 * Associative array of data from db.
178 * @var array $data_array.
183 * array of User objects.
185 * @var array $membersArr.
190 * Whether the use is an admin/super user of this project.
192 * @var bool $is_admin.
197 * Artifact types result handle.
199 * @var int $types_res.
204 * Associative array of data for plugins.
206 * @var array $plugins_data.
212 * Associative array of data for the group menu.
214 * @var array $menu_data.
219 * Group - Group object constructor - use group_get_object() to instantiate.
221 * @param int Required - group_id of the group you want to instantiate.
222 * @param int Database result from select query OR associative array of all columns.
224 function Group($id=false, $res=false) {
227 //setting up an empty object
228 //probably going to call create()
232 if (!$this->fetchData($id)) {
237 // Assoc array was passed in
239 if (is_array($res)) {
240 $this->data_array =& $res;
242 if (db_numrows($res) < 1) {
243 //function in class we extended
244 $this->setError(_('Group Not Found'));
245 $this->data_array=array();
248 //set up an associative array for use by other functions
249 $this->data_array = db_fetch_array_by_row($res, 0);
258 * fetchData - May need to refresh database fields if an update occurred.
260 * @param int The group_id.
262 function fetchData($group_id) {
263 $res = db_query_params ('SELECT * FROM groups WHERE group_id=$1',
265 if (!$res || db_numrows($res) < 1) {
266 $this->setError(sprintf(_('fetchData():: %s'),db_error()));
269 $this->data_array = db_fetch_array($res);
274 * create - Create new group.
276 * This method should be called on empty Group object.
278 * @param object The User object.
279 * @param string The full name of the user.
280 * @param string The Unix name of the user.
281 * @param string The new group description.
282 * @param string The purpose of the group.
283 * @param bool Whether to send an email or not
284 * @param int The id of the project this new project is based on
286 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) {
287 // $user is ignored - anyone can create pending group
290 if ($this->getID()!=0) {
291 $this->setError(_('Group::create: Group object already exists'));
293 } else if (!$this->validateGroupName($group_name)) {
295 } else if (!account_groupnamevalid($unix_name)) {
296 $this->setError(_('Invalid Unix name'));
298 } else if (!$SYS->sysUseUnixName($unix_name)) {
299 $this->setError(_('Unix name already taken'));
301 } else if (db_numrows(db_query_params('SELECT group_id FROM groups WHERE unix_group_name=$1',
302 array ($unix_name))) > 0) {
303 $this->setError(_('Unix name already taken'));
305 } else if (strlen($purpose)<10) {
306 $this->setError(_('Please describe your Registration Purpose in a more comprehensive manner'));
308 } else if (strlen($purpose)>1500) {
309 $this->setError(_('The Registration Purpose text is too long. Please make it smaller than 1500 bytes.'));
311 } else if (strlen($description)<10) {
312 $this->setError(_('Describe in a more comprehensive manner your project.'));
314 } else if (strlen($description)>255) {
315 $this->setError(_('Your project description is too long. Please make it smaller than 256 bytes.'));
321 $res = db_query_params ('
337 VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13)',
338 array (htmlspecialchars ($group_name),
340 htmlspecialchars($description),
341 $unix_name.".".forge_get_config('web_host'),
342 $unix_name.".".forge_get_config('web_host'),
346 htmlspecialchars($purpose),
349 md5(util_randbytes()),
350 $built_from_template)) ;
351 if (!$res || db_affected_rows($res) < 1) {
352 $this->setError(sprintf(_('ERROR: Could not create group: %s'),db_error()));
357 $id = db_insertid($res, 'groups', 'group_id');
359 $this->setError(sprintf(_('ERROR: Could not get group id: %s'),db_error()));
364 if (!$this->fetchData($id)) {
370 $gjr = new GroupJoinRequest ($this) ;
371 $gjr->create ($user->getID(),
372 'Fake GroupJoinRequest to store the creator of a project',
376 // Now, make the user an admin
378 $res=db_query_params ('INSERT INTO user_group (user_id, group_id, admin_flags,
379 cvs_flags, artifact_flags, forum_flags, role_id)
380 VALUES ($1, $2, $3, $4, $5, $6, $7)',
381 array ($user->getID(),
388 if (!$res || db_affected_rows($res) < 1) {
389 $this->setError(sprintf(_('ERROR: Could not add admin to newly created group: %s'),db_error()));
395 $hook_params = array ();
396 $hook_params['group'] = $this;
397 $hook_params['group_id'] = $this->getID();
398 $hook_params['group_name'] = $group_name;
399 $hook_params['unix_group_name'] = $unix_name;
400 plugin_hook ("group_create", $hook_params);
404 $this->sendNewProjectNotificationEmail();
412 * updateAdmin - Update core properties of group object.
414 * This function require site admin privilege.
416 * @param object User requesting operation (for access control).
417 * @param bool Whether group is publicly accessible (0/1).
418 * @param int Group type (1-project, 2-foundry).
419 * @param string Machine on which group's home directory located.
420 * @param string Domain which serves group's WWW.
424 function updateAdmin(&$user, $is_public, $type_id, $unix_box, $http_domain) {
425 $perm =& $this->getPermission ();
427 if (!$perm || !is_object($perm)) {
428 $this->setError(_('Could not get permission.'));
432 if (!$perm->isSuperUser()) {
433 $this->setError(_('Permission denied.'));
439 $res = db_query_params ('
442 unix_box=$2, http_domain=$3
449 if (!$res || db_affected_rows($res) < 1) {
450 $this->setError(_('ERROR: DB: Could not change group properties: %s'),db_error());
455 // Log the audit trail
456 if ($type_id != $this->data_array['type_id']) {
457 $this->addHistory('type_id', $this->data_array['type_id']);
459 if ($unix_box != $this->data_array['unix_box']) {
460 $this->addHistory('unix_box', $this->data_array['unix_box']);
462 if ($http_domain != $this->data_array['http_domain']) {
463 $this->addHistory('http_domain', $this->data_array['http_domain']);
466 if (!$this->fetchData($this->getID())) {
475 * update - Update number of common properties.
477 * Unlike updateAdmin(), this function accessible to project admin.
479 * @param object User requesting operation (for access control).
480 * @param bool Whether group is publicly accessible (0/1).
481 * @param string Project's license (string ident).
482 * @param int Group type (1-project, 2-foundry).
483 * @param string Machine on which group's home directory located.
484 * @param string Domain which serves group's WWW.
485 * @return int status.
488 function update(&$user, $group_name,$homepage,$short_description,$use_mail,$use_survey,$use_forum,
489 $use_pm,$use_pm_depend_box,$use_scm,$use_news,$use_docman,
490 $new_doc_address,$send_all_docs,$logo_image_id,
491 $use_ftp,$use_tracker,$use_frs,$use_stats,$tags,$is_public) {
493 $perm =& $this->getPermission ();
495 if (!$perm || !is_object($perm)) {
496 $this->setError(_('Could not get permission.'));
500 if (!$perm->isAdmin()) {
501 $this->setError(_('Permission denied.'));
505 // Validate some values
506 if ($this->getPublicName() != $group_name) {
507 if (!$this->validateGroupName($group_name)) {
512 if ($new_doc_address) {
513 $invalid_mails = validate_emails($new_doc_address);
514 if (count($invalid_mails) > 0) {
515 $this->setError(sprintf (ngettext('New Doc Address Appeared Invalid: %s', 'New Doc Addresses Appeared Invalid: %s', count($invalid_mails)),implode(',',$invalid_mails)));
520 // in the database, these all default to '1',
521 // so we have to explicity set 0
534 if (!$use_pm_depend_box) {
535 $use_pm_depend_box=0;
558 if (!$send_all_docs) {
562 $homepage = ltrim($homepage);
564 $homepage=util_make_url('/projects/' . $this->getUnixName() . '/');
567 if (strlen(htmlspecialchars($short_description))>255) {
568 $this->setError(_('Error updating project information: Maximum length for Project Description is 255 chars.'));
574 //XXX not yet actived logo_image_id='$logo_image_id',
575 $res = db_query_params ('UPDATE groups
578 short_description=$3,
583 use_pm_depend_box=$8,
594 array (htmlspecialchars($group_name),
596 htmlspecialchars($short_description),
614 $this->setError(sprintf(_('Error updating project information: %s'), db_error()));
619 if ($this->setTags($tags) === false) {
624 $hook_params = array ();
625 $hook_params['group'] = $this;
626 $hook_params['group_id'] = $this->getID();
627 $hook_params['group_homepage'] = $homepage;
628 $hook_params['group_name'] = htmlspecialchars($group_name);
629 $hook_params['group_description'] = htmlspecialchars($short_description);
630 plugin_hook ("group_update", $hook_params);
632 // Log the audit trail
633 $this->addHistory('Changed Public Info', '');
635 if (!$this->fetchData($this->getID())) {
644 * getID - Simply return the group_id for this object.
646 * @return int group_id.
649 return $this->data_array['group_id'];
653 * getType() - Foundry, project, etc.
655 * @return int The type flag from the database.
658 return $this->data_array['type_id'];
663 * getStatus - the status code.
665 * Statuses char include I,H,A,D.
667 function getStatus() {
668 return $this->data_array['status'];
672 * setStatus - set the status code.
674 * Statuses include I,H,A,D.
676 * @param object User requesting operation (for access control).
677 * @param string Status value.
678 * @return boolean success.
681 function setStatus(&$user, $status) {
684 if (!forge_check_global_perm ('approve_projects')) {
685 $this->setPermissionDeniedError();
689 // Projects in 'A' status can only go to 'H' or 'D'
690 // Projects in 'D' status can only go to 'A'
691 // Projects in 'P' status can only go to 'A' OR 'D'
692 // Projects in 'I' status can only go to 'P'
693 // Projects in 'H' status can only go to 'A' OR 'D'
694 $allowed_status_changes = array(
695 'AH'=>1,'AD'=>1,'DA'=>1,'PA'=>1,'PD'=>1,
696 'IP'=>1,'HA'=>1,'HD'=>1
699 // Check that status transition is valid
700 if ($this->getStatus() != $status
701 && !$allowed_status_changes[$this->getStatus().$status]) {
702 $this->setError(_('Invalid Status Change'));
708 $res = db_query_params ('UPDATE groups
710 WHERE group_id=$2', array ($status, $this->getID())) ;
712 if (!$res || db_affected_rows($res) < 1) {
713 $this->setError(sprintf(_('ERROR: DB: Could not change group status: %s'),db_error()));
719 // Activate system group, if not yet
720 if (!$SYS->sysCheckGroup($this->getID())) {
721 if (!$SYS->sysCreateGroup($this->getID())) {
722 $this->setError($SYS->getErrorMessage());
727 if (!$this->activateUsers()) {
732 /* Otherwise, the group is not active, and make sure that
733 System group is not active either */
734 } else if ($SYS->sysCheckGroup($this->getID())) {
735 if (!$SYS->sysRemoveGroup($this->getID())) {
736 $this->setError($SYS->getErrorMessage());
742 $hook_params = array ();
743 $hook_params['group'] = $this;
744 $hook_params['group_id'] = $this->getID();
745 $hook_params['status'] = $status;
746 plugin_hook ("group_setstatus", $hook_params);
750 // Log the audit trail
751 if ($status != $this->getStatus()) {
752 $this->addHistory('Status', $this->getStatus());
755 $this->data_array['status'] = $status;
760 * isProject - Simple boolean test to see if it's a project or not.
762 * @return boolean is_project.
764 function isProject() {
765 if ($this->getType()==1) {
773 * isPublic - Wrapper around RBAC to check if a project is anonymously readable
775 * @return boolean is_public.
777 function isPublic() {
778 $ra = RoleAnonymous::getInstance() ;
779 return $ra->hasPermission('project_read', $this->getID());
783 * isActive - Database field status of 'A' returns true.
785 * @return boolean is_active.
787 function isActive() {
788 if ($this->getStatus()=='A') {
796 * isTemplate - Simply returns the is_template flag from the database.
798 * @return boolean is_template.
800 function isTemplate() {
801 return $this->data_array['is_template'];
805 * setAsTemplate - Set the template status of a project
807 * @param boolean is_template.
809 function setAsTemplate ($booleanparam) {
811 $booleanparam = $booleanparam ? 1 : 0 ;
812 $res = db_query_params ('UPDATE groups SET is_template=$1 WHERE group_id=$2',
813 array ($booleanparam, $this->getID()));
815 $this->data_array['is_template']=$booleanparam;
825 * getTemplateProject - Return the project template this project is built from
827 * @return object The template project
829 function getTemplateProject() {
830 return group_get_object($this->data_array['built_from_template']);
834 * getUnixName - the unix_name
836 * @return string unix_name.
838 function getUnixName() {
839 return strtolower($this->data_array['unix_group_name']);
843 * getPublicName - the full-length public name.
845 * @return string The group_name.
847 function getPublicName() {
848 return $this->data_array['group_name'];
852 * getRegisterPurpose - the text description of the purpose of this project.
854 * @return string The description.
856 function getRegisterPurpose() {
857 return $this->data_array['register_purpose'];
861 * getDescription - the text description of this project.
863 * @return string The description.
865 function getDescription() {
866 return $this->data_array['short_description'];
870 * getStartDate - the unix time this project was registered.
872 * @return int (unix time) of registration.
874 function getStartDate() {
875 return $this->data_array['register_time'];
879 * getLogoImageID - the id of the logo in the database for this project.
881 * @return int The ID of logo image in db_images table (or 100 if none).
883 function getLogoImageID() {
884 return $this->data_array['logo_image_id'];
888 * getUnixBox - the hostname of the unix box where this project is located.
890 * @return string The name of the unix machine for the group.
892 function getUnixBox() {
893 return $this->data_array['unix_box'];
897 * getSCMBox - the hostname of the scm box where this project is located.
899 * @return string The name of the unix machine for the group.
901 function getSCMBox() {
902 return $this->data_array['scm_box'];
905 * setSCMBox - the hostname of the scm box where this project is located.
907 * @param string The name of the new SCM_BOX
909 function setSCMBox($scm_box) {
911 if ($scm_box == $this->data_array['scm_box']) {
916 $res = db_query_params ('UPDATE groups SET scm_box=$1 WHERE group_id=$2', array ($scm_box, $this->getID ()));
918 $this->addHistory('scm_box', $this->data_array['scm_box']);
919 $this->data_array['scm_box']=$scm_box;
924 $this->setError(_("Couldn't insert SCM_BOX to database"));
928 $this->setError(_("SCM Box can't be empty"));
934 * getDomain - the hostname.domain where their web page is located.
936 * @return string The name of the group [web] domain.
938 function getDomain() {
939 return $this->data_array['http_domain'];
943 * getLicense - the license they chose.
945 * @return int ident of group license.
947 function getLicense() {
948 return $this->data_array['license'];
952 * getLicenseName - the name of the license
954 * @return string license name
956 function getLicenseName() {
957 $licenses =& group_get_licenses();
958 if(isset($licenses[$this->data_array['license']])) {
959 return $licenses[$this->data_array['license']];
966 * getLicenseOther - optional string describing license.
968 * @return string The custom license.
970 function getLicenseOther() {
971 if ($this->getLicense() == GROUP_LICENSE_OTHER) {
972 return $this->data_array['license_other'];
979 * getRegistrationPurpose - the text description of the purpose of this project.
981 * @return string The application for project hosting.
983 function getRegistrationPurpose() {
984 return $this->data_array['register_purpose'];
989 * getAdmins() - Get array of Admin user objects.
991 * @return array Array of User objects.
993 function &getAdmins() {
994 $roles = RBACEngine::getInstance()->getRolesByAllowedAction ('project_admin', $this->getID()) ;
996 $user_ids = array () ;
998 foreach ($roles as $role) {
999 if (! ($role instanceof RoleExplicit)) {
1002 if ($role->getHomeProject() == NULL
1003 || $role->getHomeProject()->getID() != $this->getID()) {
1007 foreach ($role->getUsers() as $u) {
1008 $user_ids[] = $u->getID() ;
1012 return user_get_objects(array_unique($user_ids));
1017 Common Group preferences for tools
1022 * enableAnonSCM - whether or not this group has opted to enable Anonymous SCM.
1024 * @return boolean enable_scm.
1026 function enableAnonSCM() {
1028 $r = RoleAnonymous::getInstance () ;
1029 return $r->hasPermission ('scm', $this->getID(), 'read') ;
1031 if ($this->isPublic() && $this->usesSCM()) {
1032 return $this->data_array['enable_anonscm'];
1039 function SetUsesAnonSCM ($booleanparam) {
1041 $booleanparam = $booleanparam ? 1 : 0 ;
1043 $r = RoleAnonymous::getInstance () ;
1044 $r->setSetting ('scm', $this->getID(), $booleanparam) ;
1047 $res = db_query_params ('UPDATE groups SET enable_anonscm=$1 WHERE group_id=$2',
1048 array ($booleanparam, $this->getID()));
1050 $this->data_array['enable_anonscm']=$booleanparam;
1059 function setUsesSCM ($booleanparam) {
1061 $booleanparam = $booleanparam ? 1 : 0 ;
1062 $res = db_query_params ('UPDATE groups SET use_scm=$1 WHERE group_id=$2',
1063 array ($booleanparam, $this->getID()));
1065 $this->data_array['use_scm']=$booleanparam;
1074 * enablePserver - whether or not this group has opted to enable Pserver.
1076 * @return boolean enable_pserver.
1078 function enablePserver() {
1079 if ($this->usesSCM()) {
1080 return $this->data_array['enable_pserver'];
1086 function SetUsesPserver ($booleanparam) {
1088 $booleanparam = $booleanparam ? 1 : 0 ;
1089 $res = db_query_params ('UPDATE groups SET enable_pserver=$1 WHERE group_id=$2',
1090 array ($booleanparam, $this->getID()));
1092 $this->data_array['enable_pserver']=$booleanparam;
1101 * usesSCM - whether or not this group has opted to use SCM.
1103 * @return boolean uses_scm.
1105 function usesSCM() {
1107 if (forge_get_config('use_scm')) {
1108 return $this->data_array['use_scm'];
1115 * setUseSCM - Set the SCM usage
1117 * @param boolean enabled/disabled
1119 function setUseSCM ($booleanparam) {
1121 $booleanparam = $booleanparam ? 1 : 0 ;
1122 $res = db_query_params ('UPDATE groups SET use_scm=$1 WHERE group_id=$2',
1123 array ($booleanparam, $this->getID()));
1125 $this->data_array['use_scm']=$booleanparam;
1135 * usesMail - whether or not this group has opted to use mailing lists.
1137 * @return boolean uses_mail.
1139 function usesMail() {
1141 if (forge_get_config('use_mail')) {
1142 return $this->data_array['use_mail'];
1149 * setUseMail - Set the mailing-list usage
1151 * @param boolean enabled/disabled
1153 function setUseMail ($booleanparam) {
1155 $booleanparam = $booleanparam ? 1 : 0 ;
1156 $res = db_query_params ('UPDATE groups SET use_mail=$1 WHERE group_id=$2',
1157 array ($booleanparam, $this->getID()));
1159 $this->data_array['use_mail']=$booleanparam;
1169 * usesNews - whether or not this group has opted to use news.
1171 * @return boolean uses_news.
1173 function usesNews() {
1175 if (forge_get_config('use_news')) {
1176 return $this->data_array['use_news'];
1183 * usesForum - whether or not this group has opted to use discussion forums.
1185 * @return boolean uses_forum.
1187 function usesForum() {
1189 if (forge_get_config('use_forum')) {
1190 return $this->data_array['use_forum'];
1197 * setUseForum - Set the forum usage
1199 * @param boolean enabled/disabled
1201 function setUseForum ($booleanparam) {
1203 $booleanparam = $booleanparam ? 1 : 0 ;
1204 $res = db_query_params ('UPDATE groups SET use_forum=$1 WHERE group_id=$2',
1205 array ($booleanparam, $this->getID()));
1207 $this->data_array['use_forum']=$booleanparam;
1217 * usesStats - whether or not this group has opted to use stats.
1219 * @return boolean uses_stats.
1221 function usesStats() {
1222 return $this->data_array['use_stats'];
1226 * usesFRS - whether or not this group has opted to use file release system.
1228 * @return boolean uses_frs.
1230 function usesFRS() {
1232 if (forge_get_config('use_frs')) {
1233 return $this->data_array['use_frs'];
1240 * setUseFRS - Set the FRS usage
1242 * @param boolean enabled/disabled
1244 function setUseFRS ($booleanparam) {
1246 $booleanparam = $booleanparam ? 1 : 0 ;
1247 $res = db_query_params ('UPDATE groups SET use_frs=$1 WHERE group_id=$2',
1248 array ($booleanparam, $this->getID()));
1250 $this->data_array['use_frs']=$booleanparam;
1260 * usesTracker - whether or not this group has opted to use tracker.
1262 * @return boolean uses_tracker.
1264 function usesTracker() {
1266 if (forge_get_config('use_tracker')) {
1267 return $this->data_array['use_tracker'];
1274 * setUseTracker - Set the tracker usage
1276 * @param boolean enabled/disabled
1278 function setUseTracker ($booleanparam) {
1280 $booleanparam = $booleanparam ? 1 : 0 ;
1281 $res = db_query_params ('UPDATE groups SET use_tracker=$1 WHERE group_id=$2',
1282 array ($booleanparam, $this->getID()));
1284 $this->data_array['use_tracker']=$booleanparam;
1294 * useCreateOnline - whether or not this group has opted to use create online documents option.
1296 * @return boolean use_docman_create_online.
1298 function useCreateOnline() {
1300 if (forge_get_config('use_docman')) {
1301 return $this->data_array['use_docman_create_online'];
1308 * usesDocman - whether or not this group has opted to use docman.
1310 * @return boolean use_docman.
1312 function usesDocman() {
1314 if (forge_get_config('use_docman')) {
1315 return $this->data_array['use_docman'];
1322 * setUseDocman - Set the docman usage
1324 * @param boolean enabled/disabled
1326 function setUseDocman ($booleanparam) {
1328 $booleanparam = $booleanparam ? 1 : 0 ;
1329 $res = db_query_params ('UPDATE groups SET use_docman=$1 WHERE group_id=$2',
1330 array ($booleanparam, $this->getID()));
1332 $this->data_array['use_docman']=$booleanparam;
1342 * useDocmanSearch - whether or not this group has opted to use docman search engine.
1344 * @return boolean use_docman_search.
1346 function useDocmanSearch() {
1348 if (forge_get_config('use_docman')) {
1349 return $this->data_array['use_docman_search'];
1356 * useWebdav - whether or not this group has opted to use webdav interface.
1358 * @return boolean use_docman_search.
1360 function useWebdav() {
1362 if (forge_get_config('use_webdav')) {
1363 return $this->data_array['use_webdav'];
1370 * usesFTP - whether or not this group has opted to use FTP.
1372 * @return boolean uses_ftp.
1374 function usesFTP() {
1376 if (forge_get_config('use_ftp')) {
1377 return $this->data_array['use_ftp'];
1384 * usesSurvey - whether or not this group has opted to use surveys.
1386 * @return boolean uses_survey.
1388 function usesSurvey() {
1390 if (forge_get_config('use_survey')) {
1391 return $this->data_array['use_survey'];
1398 * usesPM - whether or not this group has opted to Project Manager.
1400 * @return boolean uses_projman.
1404 if (forge_get_config('use_pm')) {
1405 return $this->data_array['use_pm'];
1412 * setUsePM - Set the PM usage
1414 * @param boolean enabled/disabled
1416 function setUsePM ($booleanparam) {
1418 $booleanparam = $booleanparam ? 1 : 0 ;
1419 $res = db_query_params ('UPDATE groups SET use_pm=$1 WHERE group_id=$2',
1420 array ($booleanparam, $this->getID()));
1422 $this->data_array['use_pm']=$booleanparam;
1432 * getPlugins - get a list of all available group plugins
1434 * @return array array containing plugin_id => plugin_name
1436 function getPlugins() {
1437 if (!isset($this->plugins_data)) {
1438 $this->plugins_data = array () ;
1439 $res = db_query_params ('SELECT group_plugin.plugin_id, plugins.plugin_name
1440 FROM group_plugin, plugins
1441 WHERE group_plugin.group_id=$1
1442 AND group_plugin.plugin_id=plugins.plugin_id', array ($this->getID()));
1443 $rows = db_numrows($res);
1445 for ($i=0; $i<$rows; $i++) {
1446 $plugin_id = db_result($res,$i,'plugin_id');
1447 $this->plugins_data[$plugin_id] = db_result($res,$i,'plugin_name');
1450 return $this->plugins_data ;
1454 * usesPlugin - returns true if the group uses a particular plugin
1456 * @param string name of the plugin
1457 * @return boolean whether plugin is being used or not
1459 function usesPlugin($pluginname) {
1460 $plugins_data = $this->getPlugins() ;
1461 foreach ($plugins_data as $p_id => $p_name) {
1462 if ($p_name == $pluginname) {
1469 * added for Codendi compatibility
1470 * usesServices - returns true if the group uses a particular plugin or feature
1472 * @param string name of the plugin
1473 * @return boolean whether plugin is being used or not
1475 function usesService($feature) {
1476 $plugins_data = $this->getPlugins() ;
1477 $pm = plugin_manager_get_object();
1478 foreach ($plugins_data as $p_id => $p_name) {
1479 if ($p_name == $feature) {
1482 if ($pm->getPluginByName($p_name)->provide($feature) ) {
1490 * setPluginUse - enables/disables plugins for the group
1492 * @param string name of the plugin
1493 * @param boolean the new state
1494 * @return string database result
1496 function setPluginUse($pluginname, $val=true) {
1497 if ($val == $this->usesPlugin($pluginname)) {
1498 // State is already good, returning
1501 $res = db_query_params ('SELECT plugin_id FROM plugins WHERE plugin_name=$1',
1502 array ($pluginname));
1503 $rows = db_numrows($res);
1505 // Error: no plugin by that name
1508 $plugin_id = db_result($res,0,'plugin_id');
1510 unset ($this->plugins_data) ;
1512 $res = db_query_params ('INSERT INTO group_plugin (group_id, plugin_id) VALUES ($1, $2)',
1513 array ($this->getID(),
1517 $res = db_query_params ('DELETE FROM group_plugin WHERE group_id=$1 AND plugin_id=$2',
1518 array ($this->getID(),
1525 * getDocEmailAddress - get email address(es) to send doc notifications to.
1527 * @return string email address.
1529 function getDocEmailAddress() {
1530 return $this->data_array['new_doc_address'];
1534 * DocEmailAll - whether or not this group has opted to use receive notices on all doc updates.
1536 * @return boolean email_on_all_doc_updates.
1538 function docEmailAll() {
1539 return $this->data_array['send_all_docs'];
1544 * getHomePage - The URL for this project's home page.
1546 * @return string homepage URL.
1548 function getHomePage() {
1549 return $this->data_array['homepage'];
1553 * getTags - Tags of this project.
1555 * @return string List of tags.
1557 function getTags() {
1558 $sql = 'SELECT name FROM project_tags WHERE group_id = $1';
1559 $res = db_query_params($sql, array($this->getID()));
1560 return join(', ', util_result_column_to_array($res));
1564 * setTags - Set tags of this project.
1566 * @return string database result.
1568 function setTags($tags) {
1570 $sql='DELETE FROM project_tags WHERE group_id=$1';
1571 $res=db_query_params($sql, array($this->getID()));
1573 $this->setError('Deleting old tags: '.db_error());
1577 $inserted = array();
1578 $tags_array = preg_split('/[;,]/', $tags);
1579 foreach ($tags_array as $tag) {
1580 $tag = preg_replace('/[\t\r\n]/', ' ', $tag);
1581 // Allowed caracteres: [A-Z][a-z][0-9] -_&'#+.
1582 if (preg_match('/[^[:alnum:]| |\-|_|\&|\'|#|\+|\.]/', $tag)) {
1583 $this->setError(_('Bad tag name, you only can use the following characters: [A-Z][a-z][0-9]-_&\'#+. and space'));
1588 if ($tag == '' || array_search($tag, $inserted) !== false) continue;
1589 $sql='INSERT INTO project_tags (group_id,name) VALUES ($1, $2)';
1590 $res=db_query_params($sql, array($this->getID(), $tag));
1592 $this->setError(_('Setting tags: ').db_error());
1603 * getPermission - Return a Permission for this Group
1605 * @return object The Permission.
1607 function &getPermission() {
1608 return permission_get_object($this);
1612 function delete($sure,$really_sure,$really_really_sure) {
1613 if (!$sure || !$really_sure || !$really_really_sure) {
1614 $this->setMissingParamsError(_('Please tick all checkboxes.'));
1617 if ($this->getID() == forge_get_config('news_group') ||
1618 $this->getID() == 1 ||
1619 $this->getID() == forge_get_config('stats_group') ||
1620 $this->getID() == forge_get_config('peer_rating_group')) {
1621 $this->setError(_('Cannot Delete System Group'));
1624 $perm =& $this->getPermission ();
1625 if (!$perm || !is_object($perm)) {
1626 $this->setPermissionDeniedError();
1628 } elseif ($perm->isError()) {
1629 $this->setPermissionDeniedError();
1631 } elseif (!$perm->isSuperUser()) {
1632 $this->setPermissionDeniedError();
1638 // Remove all the members
1640 $members =& $this->getMembers();
1641 foreach ($members as $i) {
1642 $this->removeUser($i->getID());
1644 // Failsafe until user_group table is gone
1645 $res = db_query_params ('DELETE FROM user_group WHERE group_id=$1',
1646 array ($this->getID())) ;
1648 // unlink roles from this project
1649 $ra = RoleAnonymous::getInstance();
1650 $rl = RoleLoggedIn::getInstance();
1651 $ra->unlinkProject($this);
1652 $rl->unlinkProject($this);
1653 // @todo : unlink all the other roles created in the project...
1658 $atf = new ArtifactTypeFactory($this);
1659 $at_arr =& $atf->getArtifactTypes();
1660 foreach ($at_arr as $i) {
1661 if (!is_object($i)) {
1669 $ff = new ForumFactory($this);
1670 $f_arr =& $ff->getForums();
1671 foreach ($f_arr as $i) {
1672 if (!is_object($i)) {
1678 // Delete Subprojects
1680 $pgf = new ProjectGroupFactory($this);
1681 $pg_arr =& $pgf->getProjectGroups();
1682 foreach ($pg_arr as $i) {
1683 if (!is_object($i)) {
1689 // Delete FRS Packages
1691 //$frspf = new FRSPackageFactory($this);
1692 $res = db_query_params ('SELECT * FROM frs_package WHERE group_id=$1',
1693 array ($this->getID())) ;
1694 //echo 'frs_package'.db_error();
1695 //$frsp_arr =& $frspf->getPackages();
1696 while ($arr = db_fetch_array($res)) {
1697 //if (!is_object($pg_arr[$i])) {
1698 // echo "Not Object: ProjectGroup: ".$i;
1701 $frsp=new FRSPackage($this,$arr['package_id'],$arr);
1707 $news_group=group_get_object(forge_get_config('news_group'));
1708 $res = db_query_params ('SELECT forum_id FROM news_bytes WHERE group_id=$1',
1709 array ($this->getID())) ;
1711 $this->setError(_('Error Deleting News: ').db_error());
1716 for ($i=0; $i<db_numrows($res); $i++) {
1717 $Forum = new Forum($news_group,db_result($res,$i,'forum_id'));
1718 if (!$Forum->delete(1,1)) {
1719 printf (_("Could Not Delete News Forum: %d"),$Forum->getID());
1722 $res = db_query_params ('DELETE FROM news_bytes WHERE group_id=$1',
1723 array ($this->getID())) ;
1725 $this->setError(_('Error Deleting News: ').db_error());
1733 $res = db_query_params ('DELETE FROM doc_data WHERE group_id=$1',
1734 array ($this->getID())) ;
1736 $this->setError(_('Error Deleting Documents: ').db_error());
1741 $res = db_query_params ('DELETE FROM doc_groups WHERE group_id=$1',
1742 array ($this->getID())) ;
1744 $this->setError(_('Error Deleting Documents: ').db_error());
1752 $res=db_query_params('DELETE FROM project_tags WHERE group_id=$1', array($this->getID()));
1754 $this->setError(_('Error Deleting Tags: ').db_error());
1760 // Delete group history
1762 $res = db_query_params ('DELETE FROM group_history WHERE group_id=$1',
1763 array ($this->getID())) ;
1765 $this->setError(_('Error Deleting Project History: ').db_error());
1771 // Delete group plugins
1773 $res = db_query_params ('DELETE FROM group_plugin WHERE group_id=$1',
1774 array ($this->getID())) ;
1776 $this->setError(_('Error Deleting Project Plugins: ').db_error());
1782 // Delete group cvs stats
1784 $res = db_query_params ('DELETE FROM stats_cvs_group WHERE group_id=$1',
1785 array ($this->getID())) ;
1787 $this->setError(_('Error Deleting SCM Statistics: ').db_error());
1795 $sf = new SurveyFactory($this);
1796 $s_arr =& $sf->getSurveys();
1797 foreach ($s_arr as $i) {
1798 if (!is_object($i)) {
1804 // Delete SurveyQuestions
1806 $sqf = new SurveyQuestionFactory($this);
1807 $sq_arr =& $sqf->getSurveyQuestions();
1808 foreach ($sq_arr as $i) {
1809 if (!is_object($i)) {
1815 // Delete Mailing List Factory
1817 $mlf = new MailingListFactory($this);
1818 $ml_arr = $mlf->getMailingLists();
1819 foreach ($ml_arr as $i) {
1820 if (!is_object($i)) {
1823 if (!$i->delete(1,1)) {
1824 $this->setError(_('Could not properly delete the mailing list'));
1830 $res = db_query_params ('DELETE FROM trove_group_link WHERE group_id=$1',
1831 array ($this->getID())) ;
1833 $this->setError(_('Error Deleting Trove: ').db_error());
1838 $res = db_query_params ('DELETE FROM trove_agg WHERE group_id=$1',
1839 array ($this->getID())) ;
1841 $this->setError(_('Error Deleting Trove: ').db_error());
1849 $res = db_query_params ('DELETE FROM project_sums_agg WHERE group_id=$1',
1850 array ($this->getID())) ;
1852 $this->setError(_('Error Deleting Counters: ').db_error());
1857 $res = db_query_params ('INSERT INTO deleted_groups (unix_group_name,delete_date,isdeleted) VALUES ($1, $2, $3)',
1858 array ($this->getUnixName(),
1862 $this->setError(_('Error Deleting Project: ').db_error());
1867 $res = db_query_params ('DELETE FROM groups WHERE group_id=$1',
1868 array ($this->getID())) ;
1870 $this->setError(_('Error Deleting Project: ').db_error());
1880 $hook_params = array ();
1881 $hook_params['group'] = $this;
1882 $hook_params['group_id'] = $this->getID();
1883 plugin_hook ("group_delete", $hook_params);
1885 if (forge_get_config('upload_dir') != '' && $this->getUnixName()) {
1886 exec('/bin/rm -rf '.forge_get_config('upload_dir').'/'.$this->getUnixName().'/');
1888 if (forge_get_config('ftp_upload_dir') != '' && $this->getUnixName()) {
1889 exec('/bin/rm -rf '.forge_get_config('ftp_upload_dir').'/'.$this->getUnixName().'/');
1894 $res = db_query_params ('DELETE FROM rep_group_act_monthly WHERE group_id=$1',
1895 array ($this->getID())) ;
1896 //echo 'rep_group_act_monthly'.db_error();
1897 $res = db_query_params ('DELETE FROM rep_group_act_weekly WHERE group_id=$1',
1898 array ($this->getID())) ;
1899 //echo 'rep_group_act_weekly'.db_error();
1900 $res = db_query_params ('DELETE FROM rep_group_act_daily WHERE group_id=$1',
1901 array ($this->getID())) ;
1902 //echo 'rep_group_act_daily'.db_error();
1903 unset($this->data_array);
1911 Basic functions to add/remove users to/from a group
1912 and update their permissions
1918 * addUser - controls adding a user to a group.
1920 * @param string Unix name of the user to add OR integer user_id.
1921 * @param int The role_id this user should have.
1922 * @return boolean success.
1925 function addUser($user_identifier,$role_id) {
1928 Admins can add users to groups
1931 if (!forge_check_perm ('project_admin', $this->getID())) {
1932 $this->setPermissionDeniedError();
1938 get user id for this user's unix_name
1940 if (is_int ($user_identifier)) { // user_id or user_name
1941 $res_newuser = db_query_params ('SELECT * FROM users WHERE user_id=$1', array ($user_identifier)) ;
1943 $res_newuser = db_query_params ('SELECT * FROM users WHERE user_name=$1', array ($user_identifier)) ;
1945 if (db_numrows($res_newuser) > 0) {
1947 // make sure user is active
1949 if (db_result($res_newuser,0,'status') != 'A') {
1950 $this->setError(_('User is not active. Only active users can be added.'));
1956 // user was found - set new user_id var
1958 $user_id = db_result($res_newuser,0,'user_id');
1960 $role = new Role($this,$role_id);
1961 if (!$role || !is_object($role)) {
1962 $this->setError(_('Error Getting Role Object'));
1965 } elseif ($role->isError()) {
1966 $this->setError('addUser::roleget::'.$role->getErrorMessage());
1972 $role->addUser (user_get_object ($user_id)) ;
1973 if (!$SYS->sysCheckCreateGroup($this->getID())){
1974 $this->setError($SYS->getErrorMessage());
1978 if (!$SYS->sysCheckCreateUser($user_id)) {
1979 $this->setError($SYS->getErrorMessage());
1983 if (!$SYS->sysGroupCheckUser($this->getID(),$user_id)) {
1984 $this->setError($SYS->getErrorMessage());
1991 // if not already a member, add them
1993 $res_member = db_query_params ('SELECT user_id
1995 WHERE user_id=$1 AND group_id=$2',
1996 array ($user_id, $this->getID())) ;
1998 if (db_numrows($res_member) < 1) {
2000 // Create this user's row in the user_group table
2002 $res = db_query_params ('INSERT INTO user_group
2003 (user_id,group_id,admin_flags,forum_flags,project_flags,
2004 doc_flags,cvs_flags,member_role,release_flags,artifact_flags)
2005 VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10)',
2017 //verify the insert worked
2018 if (!$res || db_affected_rows($res) < 1) {
2019 $this->setError(sprintf(_('ERROR: Could Not Add User To Group: %s'),db_error()));
2024 // check and create if group doesn't exists
2026 //echo "<h2>Group::addUser SYS->sysCheckCreateGroup(".$this->getID().")</h2>";
2027 if (!$SYS->sysCheckCreateGroup($this->getID())){
2028 $this->setError($SYS->getErrorMessage());
2033 // check and create if user doesn't exists
2035 //echo "<h2>Group::addUser SYS->sysCheckCreateUser($user_id)</h2>";
2036 if (!$SYS->sysCheckCreateUser($user_id)) {
2037 $this->setError($SYS->getErrorMessage());
2044 //echo "<h2>Group::addUser role->setUser($user_id)</h2>";
2045 if (!$role->setUser($user_id)) {
2046 $this->setError('addUser::role::setUser'.$role->getErrorMessage());
2052 // user was already a member
2053 // make sure they are set up
2055 $user=&user_get_object($user_id,$res_newuser);
2056 $user->fetchData($user->getID());
2057 $role = new Role($this,$role_id);
2058 if (!$role || !is_object($role)) {
2059 $this->setError(_('Error Getting Role Object'));
2062 } elseif ($role->isError()) {
2063 $this->setError('addUser::roleget::'.$role->getErrorMessage());
2067 //echo "<h2>Already Member Group::addUser role->setUser($user_id)</h2>";
2068 if (!$role->setUser($user_id)) {
2069 $this->setError('addUser::role::setUser'.$role->getErrorMessage());
2074 // set up their system info
2076 //echo "<h2>Already Member Group::addUser SYS->sysCheckCreateUser($user_id)</h2>";
2077 if (!$SYS->sysCheckCreateUser($user_id)) {
2078 $this->setError($SYS->getErrorMessage());
2086 // user doesn't exist
2088 $this->setError(_('ERROR: User does not exist'));
2093 $hook_params['group'] = $this;
2094 $hook_params['group_id'] = $this->getID();
2095 $hook_params['user'] = &user_get_object($user_id);
2096 $hook_params['user_id'] = $user_id;
2097 plugin_hook ("group_adduser", $hook_params);
2102 $this->addHistory('Added User',$user_identifier);
2108 * removeUser - controls removing a user from a group.
2110 * Users can remove themselves.
2112 * @param int The ID of the user to remove.
2113 * @return boolean success.
2115 function removeUser($user_id) {
2118 if ($user_id != user_getid()
2119 || !forge_check_perm ('project_admin', $this->getID())) {
2120 $this->setPermissionDeniedError();
2127 $user = user_get_object ($user_id) ;
2128 $roles = RBACEngine::getInstance()->getAvailableRolesForUser ($user) ;
2129 $found_role = NULL ;
2130 foreach ($roles as $role) {
2131 if ($role->getHomeProject() && $role->getHomeProject()->getID() == $this->getID()) {
2132 $found_role = $role ;
2136 if ($found_role == NULL) {
2137 $this->setError(sprintf(_('ERROR: User not removed: %s')));
2141 $found_role->removeUser ($user) ;
2142 if (!$SYS->sysGroupCheckUser($this->getID(),$user_id)) {
2143 $this->setError($SYS->getErrorMessage());
2149 $res = db_query_params ('DELETE FROM user_group WHERE group_id=$1 AND user_id=$2',
2150 array ($this->getID(),
2152 if (!$res || db_affected_rows($res) < 1) {
2153 $this->setError(sprintf(_('ERROR: User not removed: %s'),db_error()));
2160 // reassign open artifacts to id=100
2162 $res = db_query_params ('UPDATE artifact SET assigned_to=100
2163 WHERE group_artifact_id
2164 IN (SELECT group_artifact_id
2165 FROM artifact_group_list
2166 WHERE group_id=$1 AND status_id=1 AND assigned_to=$2)',
2167 array ($this->getID(),
2170 $this->setError(sprintf(_('ERROR: DB: artifact: %s'),db_error()));
2176 // reassign open tasks to id=100
2177 // first have to purge any assignments that would cause
2178 // conflict with existing assignment to 100
2180 $res = db_query_params ('DELETE FROM project_assigned_to
2181 WHERE project_task_id IN (SELECT pt.project_task_id
2182 FROM project_task pt, project_group_list pgl, project_assigned_to pat
2183 WHERE pt.group_project_id = pgl.group_project_id
2184 AND pat.project_task_id=pt.project_task_id
2185 AND pt.status_id=1 AND pgl.group_id=$1
2186 AND pat.assigned_to_id=$2)
2187 AND assigned_to_id=100',
2188 array ($this->getID(),
2191 $this->setError(sprintf(_('ERROR: DB: project_assigned_to %d: %s'),1,db_error()));
2195 $res = db_query_params ('UPDATE project_assigned_to SET assigned_to_id=100
2196 WHERE project_task_id IN (SELECT pt.project_task_id
2197 FROM project_task pt, project_group_list pgl
2198 WHERE pt.group_project_id = pgl.group_project_id
2199 AND pt.status_id=1 AND pgl.group_id=$1)
2200 AND assigned_to_id=$2',
2201 array ($this->getID(),
2204 $this->setError(sprintf(_('ERROR: DB: project_assigned_to %d: %s'),2,db_error()));
2210 // Remove user from system
2212 if (!$SYS->sysGroupRemoveUser($this->getID(),$user_id)) {
2213 $this->setError($SYS->getErrorMessage());
2218 $hook_params['group'] = $this;
2219 $hook_params['group_id'] = $this->getID();
2220 $hook_params['user'] = &user_get_object($user_id);
2221 $hook_params['user_id'] = $user_id;
2222 plugin_hook ("group_removeuser", $hook_params);
2225 $this->addHistory('Removed User',$user_id);
2232 * updateUser - controls updating a user's role in this group.
2234 * @param int The ID of the user.
2235 * @param int The role_id to set this user to.
2236 * @return boolean success.
2238 function updateUser($user_id,$role_id) {
2241 if (!forge_check_perm ('project_admin', $this->getID())) {
2242 $this->setPermissionDeniedError();
2247 $newrole = RBACEngine::getInstance()->getRoleById ($role_id) ;
2248 if (!$newrole || !is_object($newrole)) {
2249 $this->setError(_('Could Not Get Role'));
2251 } elseif ($newrole->isError()) {
2252 $this->setError(sprintf(_('Role: %s'),$role->getErrorMessage()));
2254 } elseif ($newrole->getHomeProject() == NULL
2255 || $newrole->getHomeProject()->getID() != $this->getID()) {
2256 $this->setError(_('Wrong destination role'));
2259 $user = user_get_object ($user_id) ;
2260 $roles = RBACEngine::getInstance()->getAvailableRolesForUser ($user) ;
2261 $found_role = NULL ;
2262 foreach ($roles as $role) {
2263 if ($role->getHomeProject() && $role->getHomeProject()->getID() == $this->getID()) {
2264 $found_role = $role ;
2268 if ($found_role == NULL) {
2269 $this->setError(sprintf(_('ERROR: User not removed: %s')));
2273 $found_role->removeUser ($user) ;
2274 $newrole->addUser ($user) ;
2276 $role = new Role($this,$role_id);
2277 if (!$role || !is_object($role)) {
2278 $this->setError(_('Could Not Get Role'));
2280 } elseif ($role->isError()) {
2281 $this->setError(sprintf(_('Role: %s'),$role->getErrorMessage()));
2284 //echo "<h3>Group::updateUser role->setUser($user_id)</h3>";
2285 if (!$role->setUser($user_id)) {
2286 $this->setError(sprintf(_('Role: %s'),$role->getErrorMessage()));
2291 $this->addHistory('Updated User',$user_id);
2296 * addHistory - Makes an audit trail entry for this project.
2298 * @param string The name of the field.
2299 * @param string The Old Value for this $field_name.
2300 * @return database result handle.
2303 function addHistory($field_name, $old_value) {
2304 return db_query_params ('INSERT INTO group_history(group_id,field_name,old_value,mod_by,adddate)
2305 VALUES ($1,$2,$3,$4,$5)',
2306 array ($this->getID(),
2314 * activateUsers - Make sure that group members have unix accounts.
2316 * Setup unix accounts for group members. Can be called even
2317 * if members are already active.
2321 function activateUsers() {
2323 Activate member(s) of the project
2327 $members = $this->getUsers (true) ;
2329 foreach ($members as $member) {
2331 foreach (RBACEngine::getInstance()->getAvailableRolesForUser ($member) as $role) {
2332 if ($role->getHomeProject() && $role->getHomeProject()->getID() == $this->getID()) {
2335 if (!$this->addUser($member->getUnixName(),$role->getID())) {
2342 $res_member = db_query_params ('SELECT user_id,role_id FROM user_group WHERE group_id=$1',
2343 array ($this->getID())) ;
2344 while ($row_member = db_fetch_array($res_member)) {
2345 $u = user_get_object($row_member['user_id']) ;
2346 if (!$this->addUser($u->getUnixName(),$row_member['role_id'])) {
2356 * getMembers - returns array of User objects for this project
2358 * @return array of User objects for this group.
2360 function getMembers() {
2361 return $this->getUsers (true) ;
2365 * replaceTemplateStrings - fill-in some blanks with project name
2367 * @param string Template string
2368 * @return string String after replacements
2370 function replaceTemplateStrings($string) {
2371 $string = str_replace ('UNIXNAME', $this->getUnixName(), $string) ;
2372 $string = str_replace ('PUBLICNAME', $this->getPublicName(), $string) ;
2373 $string = str_replace ('DESCRIPTION', $this->getDescription(), $string) ;
2378 * approve - Approve pending project.
2380 * @param object The User object who is doing the updating.
2383 function approve(&$user) {
2385 require_once $gfcommon.'widget/WidgetLayoutManager.class.php';
2387 if ($this->getStatus()=='A') {
2388 $this->setError(_("Group already active"));
2394 // Step 1: Activate group and create LDAP entries
2395 if (!$this->setStatus($user, 'A')) {
2400 // Switch to system language for item creation
2401 setup_gettext_from_sys_lang ();
2403 // Create default roles
2405 $idadmin_group = NULL ;
2406 foreach (get_group_join_requests ($this) as $gjr) {
2407 $idadmin_group = $gjr->getUserID() ;
2410 if ($idadmin_group == NULL) {
2411 $idadmin_group = $user->getID();
2414 $admin_group = db_query_params ('SELECT user_id FROM user_group WHERE group_id=$1 AND admin_flags=$2',
2415 array ($this->getID(),
2417 if (db_numrows($admin_group) > 0) {
2418 $idadmin_group = db_result($admin_group,0,'user_id');
2420 $idadmin_group = $user->getID();
2421 db_query_params ('INSERT INTO user_group (user_id, group_id, admin_flags) VALUES ($1, $2, $3)',
2422 array ($idadmin_group,
2428 $template = $this->getTemplateProject() ;
2429 $id_mappings = array ();
2430 $seen_local_roles = false ;
2432 // Copy roles from template project
2433 foreach ($template->getRoles() as $oldrole) {
2434 if ($oldrole->getHomeProject() != NULL) {
2435 $role = new Role ($this) ;
2437 // Need to use a different role name so that the permissions aren't set from the hardcoded defaults
2438 $role->create ('TEMPORARY ROLE NAME', $data, true) ;
2439 $role->setName ($oldrole->getName()) ;
2440 $seen_local_roles = true ;
2443 $role->linkProject ($this) ;
2445 $id_mappings['role'][$oldrole->getID()] = $role->getID() ;
2446 // Reuse the project_admin permission
2447 $role->setSetting ('project_admin', $this->getID(), $oldrole->getSetting ('project_admin', $template->getID())) ;
2451 if (!$seen_local_roles) {
2452 $role = new Role($this);
2453 $adminperms = array ('project_admin' => array ($this->getID() => 1)) ;
2454 $role_id = $role->create ('Admin', $adminperms, true) ;
2458 $roles = $this->getRoles() ;
2459 foreach ($roles as $r) {
2460 if ($r->getSetting ('project_admin', $this->getID())) {
2461 $r->addUser (user_get_object ($idadmin_group)) ;
2466 // Temporarily switch to the submitter's identity
2467 $saved_session = session_get_user () ;
2468 session_set_internal ($idadmin_group) ;
2471 if (forge_get_config ('use_tracker')) {
2472 $this->setUseTracker ($template->usesTracker()) ;
2473 if ($template->usesTracker()) {
2474 $oldatf = new ArtifactTypeFactory ($template) ;
2475 foreach ($oldatf->getArtifactTypes() as $o) {
2476 $t = new ArtifactType ($this) ;
2477 $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()) ;
2478 $id_mappings['tracker'][$o->getID()] = $t->getID() ;
2479 $t->cloneFieldsFrom ($o->getID()) ;
2484 if (forge_get_config ('use_pm')) {
2485 $this->setUsePM ($template->usesPM()) ;
2486 if ($template->usesPM()) {
2487 $oldpgf = new ProjectGroupFactory ($template) ;
2488 foreach ($oldpgf->getProjectGroups() as $o) {
2489 $pg = new ProjectGroup ($this) ;
2490 $pg->create ($this->replaceTemplateStrings($o->getName()),$this->replaceTemplateStrings($o->getDescription()),$o->isPublic(),$o->getSendAllPostsTo()) ;
2491 $id_mappings['pm'][$o->getID()] = $pg->getID() ;
2496 if (forge_get_config ('use_forum')) {
2497 $this->setUseForum ($template->usesForum()) ;
2498 if ($template->usesForum()) {
2499 $oldff = new ForumFactory ($template) ;
2500 foreach ($oldff->getForums() as $o) {
2501 $f = new Forum ($this) ;
2502 $f->create ($this->replaceTemplateStrings($o->getName()),$this->replaceTemplateStrings($o->getDescription()),$o->isPublic(),$o->getSendAllPostsTo(),1,$o->allowAnonymous(),$o->getModerationLevel()) ;
2503 $id_mappings['forum'][$o->getID()] = $f->getID() ;
2508 if (forge_get_config ('use_docman')) {
2509 $this->setUseDocman ($template->usesDocman()) ;
2510 if ($template->usesDocman()) {
2511 $olddgf = new DocumentGroupFactory ($template) ;
2512 // First pass: create all docgroups
2513 $id_mappings['docman_docgroup'][0] = 0 ;
2514 foreach ($olddgf->getDocumentGroups() as $o) {
2515 $ndgf = new DocumentGroup ($this) ;
2516 $ndgf->create($this->replaceTemplateStrings($o->getName())) ;
2517 $id_mappings['docman_docgroup'][$o->getID()] = $ndgf->getID() ;
2519 // Second pass: restore hierarchy links
2520 foreach ($olddgf->getDocumentGroups() as $o) {
2521 $ndgf = new DocumentGroup ($this) ;
2522 $ndgf->fetchData ($id_mappings['docman_docgroup'][$o->getID()]) ;
2523 $ndgf->update ($ndgf->getName(),$id_mappings['docman_docgroup'][$o->getParentID()]) ;
2528 if (forge_get_config ('use_frs')) {
2529 $this->setUseFRS ($template->usesFRS()) ;
2530 if ($template->usesFRS()) {
2531 foreach (get_frs_packages ($template) as $o) {
2532 $newp = new FRSPackage ($this) ;
2533 $nname = $this->replaceTemplateStrings($o->getName()) ;
2534 $newp->create ($nname, $o->isPublic()) ;
2539 if (forge_get_config ('use_mail')) {
2540 $this->setUseMail ($template->usesMail()) ;
2541 if ($template->usesMail()) {
2542 $oldmlf = new MailingListFactory ($template) ;
2543 foreach ($oldmlf->getMailingLists() as $o) {
2544 $ml = new MailingList ($this) ;
2545 $nname = preg_replace ('/^'.$template->getUnixName().'-/','',$o->getName()) ;
2547 $ndescription = $this->replaceTemplateStrings($o->getDescription()) ;
2548 $ml->create ($nname, $ndescription, $o->isPublic()) ;
2553 $this->setUseSCM ($template->usesSCM()) ;
2555 foreach ($template->getPlugins() as $plugin_id => $plugin_name) {
2556 $this->setPluginUse ($plugin_name) ;
2559 foreach ($template->getRoles() as $oldrole) {
2560 $newrole = RBACEngine::getInstance()->getRoleById ($id_mappings['role'][$oldrole->getID()]) ;
2561 if ($oldrole->getHomeProject() != NULL
2562 && $oldrole->getHomeProject()->getID() == $template->getID()) {
2563 $newrole->setPublic ($oldrole->isPublic()) ;
2565 $oldsettings = $oldrole->getSettingsForProject ($template) ;
2567 $sections = array ('project_read', 'project_admin', 'frs', 'scm', 'docman', 'tracker_admin', 'new_tracker', 'forum_admin', 'new_forum', 'pm_admin', 'new_pm') ;
2568 foreach ($sections as $section) {
2569 $newrole->setSetting ($section, $this->getID(), $oldsettings[$section][$template->getID()]) ;
2572 $sections = array ('tracker', 'pm', 'forum') ;
2573 foreach ($sections as $section) {
2574 if (isset ($oldsettings[$section])) {
2575 foreach ($oldsettings[$section] as $k => $v) {
2576 // Only copy perms for tools that have been copied
2577 if (isset ($id_mappings[$section][$k])) {
2578 $newrole->setSetting ($section,
2579 $id_mappings[$section][$k],
2587 $lm = new WidgetLayoutManager();
2588 $lm->createDefaultLayoutForProject ($this->getID(), $template->getID()) ;
2590 $params = array () ;
2591 $params['template'] = $template ;
2592 $params['project'] = $this ;
2593 $params['id_mappings'] = $id_mappings ;
2594 plugin_hook_by_reference ('clone_project_from_template', $params) ;
2596 // Disable everything
2597 $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, use_ftp=0, use_tracker=0, use_frs=0, use_stats=0 WHERE group_id=$1',
2599 array ($this->getID())) ;
2602 $this->normalizeAllRoles () ;
2603 $this->activateUsers();
2605 // Switch back to user preference
2606 session_set_internal ($saved_session->getID()) ;
2607 setup_gettext_from_context();
2611 $this->sendApprovalEmail();
2612 $this->addHistory('Approved', 'x');
2615 // Plugin can make approve operation there
2618 $params[0] = $idadmin_group ;
2619 $params[1] = $this->getID();
2620 plugin_hook('group_approved',$params);
2628 * sendApprovalEmail - Send new project email.
2630 * @return boolean success.
2633 function sendApprovalEmail() {
2634 $admins = RBACEngine::getInstance()->getUsersByAllowedAction ('project_admin', $this->getID()) ;
2636 if (count($admins) < 1) {
2637 $this->setError(_("Group does not have any administrators."));
2641 // send one email per admin
2642 foreach ($admins as $admin) {
2643 setup_gettext_for_user ($admin) ;
2645 $message=sprintf(_('Your project registration for %4$s has been approved.
2647 Project Full Name: %1$s
2648 Project Unix Name: %2$s
2650 Your DNS will take up to a day to become active on our site.
2651 Your web site is accessible through your shell account. Please read
2652 site documentation (see link below) about intended usage, available
2653 services, and directory layout of the account.
2656 own project page in %4$s while logged in, you will find
2657 additional menu functions to your left labeled \'Project Admin\'.
2659 We highly suggest that you now visit %4$s and create a public
2660 description for your project. This can be done by visiting your project
2661 page while logged in, and selecting \'Project Admin\' from the menus
2662 on the left (or by visiting %3$s
2665 Your project will also not appear in the Trove Software Map (primary
2666 list of projects hosted on %4$s which offers great flexibility in
2667 browsing and search) until you categorize it in the project administration
2668 screens. So that people can find your project, you should do this now.
2669 Visit your project while logged in, and select \'Project Admin\' from the
2672 Enjoy the system, and please tell others about %4$s. Let us know
2673 if there is anything we can do to help you.
2676 htmlspecialchars_decode($this->getPublicName()),
2677 $this->getUnixName(),
2678 util_make_url ('/project/admin/?group_id='.$this->getID()),
2679 forge_get_config ('forge_name'));
2681 util_send_message($admin->getEmail(), sprintf(_('%1$s Project Approved'), forge_get_config ('forge_name')), $message);
2683 setup_gettext_from_context();
2691 * sendRejectionEmail - Send project rejection email.
2693 * This function sends out a rejection message to a user who
2694 * registered a project.
2696 * @param int The id of the response to use.
2697 * @param string The rejection message.
2698 * @return completion status.
2701 function sendRejectionEmail($response_id, $message="zxcv") {
2702 $submitters = array () ;
2704 foreach (get_group_join_requests ($this) as $gjr) {
2705 $submitters[] = user_get_object($gjr->getUserID()) ;
2708 $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",
2710 while ($arr = db_fetch_array ($res)) {
2711 $submitter[] =& user_get_object($arr['user_id']);
2715 if (count ($submitters) < 1) {
2716 $this->setError(_("Group does not have any administrators."));
2720 foreach ($submitters as $admin) {
2721 setup_gettext_for_user ($admin) ;
2723 $response=sprintf(_('Your project registration for %3$s has been denied.
2725 Project Full Name: %1$s
2726 Project Unix Name: %2$s
2728 Reasons for negative decision:
2730 '), $this->getPublicName(), $this->getUnixName(), forge_get_config ('forge_name'));
2732 // Check to see if they want to send a custom rejection response
2733 if ($response_id == 0) {
2734 $response .= $message;
2736 $response .= db_result (
2737 db_query_params('SELECT response_text FROM canned_responses WHERE response_id=$1', array ($response_id)),
2742 util_send_message($admin->getEmail(), sprintf(_('%1$s Project Denied'), forge_get_config ('forge_name')), $response);
2743 setup_gettext_from_context();
2750 * sendNewProjectNotificationEmail - Send new project notification email.
2752 * This function sends out a notification email to the
2753 * SourceForge admin user when a new project is
2756 * @return boolean success.
2759 function sendNewProjectNotificationEmail() {
2760 // Get the user who wants to register the project
2761 $submitters = array () ;
2763 foreach (get_group_join_requests ($this) as $gjr) {
2764 $submitters[] = user_get_object($gjr->getUserID()) ;
2767 $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",
2769 while ($arr = db_fetch_array ($res)) {
2770 $submitter[] =& user_get_object($arr['user_id']);
2773 if (count ($submitters) < 1) {
2774 $this->setError(_("Could not find user who has submitted the project."));
2778 $admins = RBACEngine::getInstance()->getUsersByAllowedAction ('approve_projects', -1) ;
2780 if (count($admins) < 1) {
2781 $this->setError(_("There is no administrator to send the mail to."));
2785 foreach ($admins as $admin) {
2786 $admin_email = $admin->getEmail () ;
2787 setup_gettext_for_user ($admin) ;
2789 foreach ($submitters as $u) {
2790 $submitter_names[] = $u->getRealName() ;
2793 $message = sprintf(_('New %1$s Project Submitted
2795 Project Full Name: %2$s
2796 Submitted Description: %3$s
2798 forge_get_config ('forge_name'),
2799 htmlspecialchars_decode($this->getPublicName()),
2800 htmlspecialchars_decode($this->getRegistrationPurpose()));
2802 foreach ($submitters as $submitter) {
2803 $message .= sprintf(_('Submitter: %1$s (%2$s)
2805 $submitter->getRealName(),
2806 $submitter->getUnixName());
2809 $message .= sprintf (_('
2810 Please visit the following URL to approve or reject this project:
2812 util_make_url ('/admin/approve-pending.php')) ;
2813 util_send_message($admin_email, sprintf(_('New %1$s Project Submitted'), forge_get_config ('forge_name')), $message);
2814 setup_gettext_from_context();
2818 $email = $submitter->getEmail() ;
2819 setup_gettext_for_user ($submitter) ;
2821 $message=sprintf(_('New %1$s Project Submitted
2823 Project Full Name: %2$s
2824 Submitted Description: %3$s
2826 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'));
2828 util_send_message($email, sprintf(_('New %1$s Project Submitted'), forge_get_config ('forge_name')), $message);
2829 setup_gettext_from_context();
2838 * validateGroupName - Validate the group name
2840 * @param string Group name.
2842 * @return an error false and set an error is the group name is invalide otherwise return true
2844 function validateGroupName($group_name) {
2845 if (strlen($group_name)<3) {
2846 $this->setError(_('Group name is too short'));
2848 } else if (strlen(htmlspecialchars($group_name))>50) {
2849 $this->setError(_('Group name is too long'));
2851 } else if ($group=group_get_object_by_publicname($group_name)) {
2852 $this->setError(_('Group name already taken'));
2860 * getRoles - Get the roles of the group.
2862 * @return array of Role id of this group.
2864 function getRolesId () {
2865 $role_ids = array () ;
2868 $res = db_query_params ('SELECT role_id FROM pfo_role WHERE home_group_id=$1',
2869 array ($this->getID()));
2870 while ($arr = db_fetch_array($res)) {
2871 $role_ids[] = $arr['role_id'] ;
2873 $res = db_query_params ('SELECT role_id FROM role_project_refs WHERE group_id=$1',
2874 array ($this->getID()));
2875 while ($arr = db_fetch_array($res)) {
2876 $role_ids[] = $arr['role_id'] ;
2879 $res = db_query_params ('SELECT role_id FROM role WHERE group_id=$1',
2880 array ($this->getID()));
2881 while ($arr = db_fetch_array($res)) {
2882 $role_ids[] = $arr['role_id'] ;
2886 return array_unique ($role_ids) ;
2889 function getRoles () {
2890 $result = array () ;
2892 $roles = $this->getRolesId () ;
2894 $engine = RBACEngine::getInstance() ;
2895 foreach ($roles as $role_id) {
2896 $result[] = $engine->getRoleById ($role_id) ;
2899 foreach ($roles as $role_id) {
2900 $result[] = new Role ($this, $role_id) ;
2907 function normalizeAllRoles () {
2908 $roles = $this->getRoles () ;
2910 foreach ($roles as $r) {
2911 $r->normalizeData () ;
2916 * getUnixStatus - Status of activation of unix account.
2918 * @return char (N)one, (A)ctive, (S)uspended or (D)eleted
2920 function getUnixStatus() {
2921 return $this->data_array['unix_status'];
2925 * setUnixStatus - Sets status of activation of unix account.
2927 * @param string The unix status.
2933 * @return boolean success.
2935 function setUnixStatus($status) {
2938 $res = db_query_params ('UPDATE groups SET unix_status=$1 WHERE group_id=$2',
2943 $this->setError(sprintf(_('ERROR - Could Not Update Group Unix Status: %s'),db_error()));
2947 if ($status == 'A') {
2948 if (!$SYS->sysCheckCreateGroup($this->getID())) {
2949 $this->setError($SYS->getErrorMessage());
2954 if ($SYS->sysCheckGroup($this->getID())) {
2955 if (!$SYS->sysRemoveGroup($this->getID())) {
2956 $this->setError($SYS->getErrorMessage());
2963 $this->data_array['unix_status']=$status;
2970 * getUsers - Get the users of a group
2972 * @return array of user's objects.
2974 function getUsers($onlylocal = true) {
2975 if (!isset($this->membersArr)) {
2976 $this->membersArr = array () ;
2980 foreach ($this->getRoles() as $role) {
2982 && ($role->getHomeProject() == NULL || $role->getHomeProject()->getID() != $this->getID())) {
2985 foreach ($role->getUsers() as $user) {
2986 $ids[] = $user->getID() ;
2989 $ids = array_unique ($ids) ;
2990 foreach ($ids as $id) {
2991 $u = user_get_object ($id) ;
2992 if ($u->isActive()) {
2993 $this->membersArr[] = $u ;
2998 $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',
2999 array ($this->getID(),
3001 if (!$users_group_res) {
3002 $this->setError(_('Error: Enable to get users from group'). ' ' . $this->getID() . ' ' .db_error());
3006 for ($i=0; $i<db_numrows($users_group_res); $i++) {
3007 $this->membersArr[$i] = new GFUser(db_result($users_group_res,$i,'user_id'),false);
3012 return $this->membersArr;
3015 function setDocmanCreateOnlineStatus($status) {
3017 /* if we activate search engine, we probably want to reindex */
3018 $res = db_query_params ('UPDATE groups SET use_docman_create_online=$1 WHERE group_id=$2',
3023 $this->setError(sprintf(_('ERROR - Could Not Update Group DocmanCreateOnline Status: %s'),db_error()));
3027 $this->data_array['use_docman_create_online']=$status;
3033 function setDocmanWebdav($status) {
3035 /* if we activate search engine, we probably want to reindex */
3036 $res = db_query_params ('UPDATE groups SET use_webdav=$1 WHERE group_id=$2',
3041 $this->setError(sprintf(_('ERROR - Could Not Update Group UseWebdab Status: %s'),db_error()));
3045 $this->data_array['use_webdav']=$status;
3051 function setDocmanSearchStatus($status) {
3053 /* if we activate search engine, we probably want to reindex */
3054 $res = db_query_params ('UPDATE groups SET use_docman_search=$1, force_docman_reindex=$1 WHERE group_id=$2',
3059 $this->setError(sprintf(_('ERROR - Could Not Update Group UseDocmanSearch Status: %s'),db_error()));
3063 $this->data_array['use_docman_search']=$status;
3069 function setDocmanForceReindexSearch($status) {
3071 /* if we activate search engine, we probably want to reindex */
3072 $res = db_query_params ('UPDATE groups SET force_docman_reindex=$1 WHERE group_id=$2',
3077 $this->setError(sprintf(_('ERROR - Could Not Update Group force_docman_reindex %s'),db_error()));
3081 $this->data_array['force_docman_reindex']=$status;
3087 function setStorageAPI($type) {
3091 function getStorageAPI() {
3097 * group_getname() - get the group name
3099 * @param int The group ID
3103 function group_getname ($group_id = 0) {
3104 $grp = group_get_object($group_id);
3106 return $grp->getPublicName();
3113 * group_getunixname() - get the unixname for a group
3115 * @param int The group ID
3119 function group_getunixname ($group_id) {
3120 $grp = group_get_object($group_id);
3122 return $grp->getUnixName();
3129 * group_get_result() - Get the group object result ID.
3131 * @param int The group ID
3135 function &group_get_result($group_id=0) {
3136 $grp = group_get_object($group_id);
3138 return $grp->getData();
3144 function getAllProjectTags($onlyvisible = true) {
3145 $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',
3148 if (!$res || db_numrows($res) == 0) {
3154 while ($arr = db_fetch_array($res)) {
3156 $group_id = $arr[1];
3157 if (!isset($result[$tag])) {
3158 $result[$tag] = array();
3161 if (!$onlyvisible || forge_check_perm('project_read', $group_id)) {
3162 $p = group_get_object($group_id);
3163 $result[$tag][] = array('unix_group_name' => $p->getUnixName(),
3164 'group_id' => $group_id);
3171 class ProjectComparator {
3172 var $criterion = 'name' ;
3174 function Compare ($a, $b) {
3175 switch ($this->criterion) {
3178 $namecmp = strcoll ($a->getPublicName(), $b->getPublicName()) ;
3179 if ($namecmp != 0) {
3182 /* If several projects share a same public name */
3183 return strcoll ($a->getUnixName(), $b->getUnixName()) ;
3186 return strcmp ($a->getUnixName(), $b->getUnixName()) ;
3189 $aid = $a->getID() ;
3190 $bid = $b->getID() ;
3194 return ($a < $b) ? -1 : 1;
3200 function sortProjectList (&$list, $criterion='name') {
3201 $cmp = new ProjectComparator () ;
3202 $cmp->criterion = $criterion ;
3204 return usort ($list, array ($cmp, 'Compare')) ;
3209 // c-file-style: "bsd"