5 * Copyright 1999-2001, VA Linux Systems, Inc.
6 * Copyright 2009-2010, Roland Mas
7 * Copyright 2010, Franck Villaume - Capgemini
8 * Copyright (C) 2010-2011 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.'));
319 // Check if sys_use_project_vhost for homepage
320 if (forge_get_config('use_project_vhost')) {
321 $homepage = $unix_name.".".forge_get_config('web_host');
323 $homepage = forge_get_config('web_host')."/www/".$unix_name."/";
329 $res = db_query_params ('
345 VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13)',
346 array (htmlspecialchars ($group_name),
348 htmlspecialchars($description),
349 $unix_name.".".forge_get_config('web_host'),
354 htmlspecialchars($purpose),
357 md5(util_randbytes()),
358 $built_from_template)) ;
359 if (!$res || db_affected_rows($res) < 1) {
360 $this->setError(sprintf(_('ERROR: Could not create group: %s'),db_error()));
365 $id = db_insertid($res, 'groups', 'group_id');
367 $this->setError(sprintf(_('ERROR: Could not get group id: %s'),db_error()));
372 if (!$this->fetchData($id)) {
378 $gjr = new GroupJoinRequest ($this) ;
379 $gjr->create ($user->getID(),
380 'Fake GroupJoinRequest to store the creator of a project',
384 // Now, make the user an admin
386 $res=db_query_params ('INSERT INTO user_group (user_id, group_id, admin_flags,
387 cvs_flags, artifact_flags, forum_flags, role_id)
388 VALUES ($1, $2, $3, $4, $5, $6, $7)',
389 array ($user->getID(),
396 if (!$res || db_affected_rows($res) < 1) {
397 $this->setError(sprintf(_('ERROR: Could not add admin to newly created group: %s'),db_error()));
403 $hook_params = array ();
404 $hook_params['group'] = $this;
405 $hook_params['group_id'] = $this->getID();
406 $hook_params['group_name'] = $group_name;
407 $hook_params['unix_group_name'] = $unix_name;
408 plugin_hook ("group_create", $hook_params);
412 $this->sendNewProjectNotificationEmail();
420 * updateAdmin - Update core properties of group object.
422 * This function require site admin privilege.
424 * @param object User requesting operation (for access control).
425 * @param bool Whether group is publicly accessible (0/1).
426 * @param int Group type (1-project, 2-foundry).
427 * @param string Machine on which group's home directory located.
428 * @param string Domain which serves group's WWW.
432 function updateAdmin(&$user, $is_public, $type_id, $unix_box, $http_domain) {
433 $perm =& $this->getPermission ();
435 if (!$perm || !is_object($perm)) {
436 $this->setError(_('Could not get permission.'));
440 if (!$perm->isSuperUser()) {
441 $this->setError(_('Permission denied.'));
447 $res = db_query_params ('
450 unix_box=$2, http_domain=$3
457 if (!$res || db_affected_rows($res) < 1) {
458 $this->setError(_('ERROR: DB: Could not change group properties: %s'),db_error());
463 // Log the audit trail
464 if ($type_id != $this->data_array['type_id']) {
465 $this->addHistory('type_id', $this->data_array['type_id']);
467 if ($unix_box != $this->data_array['unix_box']) {
468 $this->addHistory('unix_box', $this->data_array['unix_box']);
470 if ($http_domain != $this->data_array['http_domain']) {
471 $this->addHistory('http_domain', $this->data_array['http_domain']);
474 if (!$this->fetchData($this->getID())) {
483 * update - Update number of common properties.
485 * Unlike updateAdmin(), this function accessible to project admin.
487 * @param object User requesting operation (for access control).
488 * @param bool Whether group is publicly accessible (0/1).
489 * @param string Project's license (string ident).
490 * @param int Group type (1-project, 2-foundry).
491 * @param string Machine on which group's home directory located.
492 * @param string Domain which serves group's WWW.
493 * @return int status.
496 function update(&$user, $group_name,$homepage,$short_description,$use_mail,$use_survey,$use_forum,
497 $use_pm,$use_pm_depend_box,$use_scm,$use_news,$use_docman,
498 $new_doc_address,$send_all_docs,$logo_image_id,
499 $use_ftp,$use_tracker,$use_frs,$use_stats,$tags,$is_public) {
501 $perm =& $this->getPermission ();
503 if (!$perm || !is_object($perm)) {
504 $this->setError(_('Could not get permission.'));
508 if (!$perm->isAdmin()) {
509 $this->setError(_('Permission denied.'));
513 // Validate some values
514 if ($this->getPublicName() != $group_name) {
515 if (!$this->validateGroupName($group_name)) {
520 if ($new_doc_address) {
521 $invalid_mails = validate_emails($new_doc_address);
522 if (count($invalid_mails) > 0) {
523 $this->setError(sprintf (ngettext('New Doc Address Appeared Invalid: %s', 'New Doc Addresses Appeared Invalid: %s', count($invalid_mails)),implode(',',$invalid_mails)));
528 // in the database, these all default to '1',
529 // so we have to explicity set 0
542 if (!$use_pm_depend_box) {
543 $use_pm_depend_box=0;
566 if (!$send_all_docs) {
570 $homepage = ltrim($homepage);
572 $homepage=util_make_url('/projects/' . $this->getUnixName() . '/');
575 if (strlen(htmlspecialchars($short_description))>255) {
576 $this->setError(_('Error updating project information: Maximum length for Project Description is 255 chars.'));
582 //XXX not yet actived logo_image_id='$logo_image_id',
583 $res = db_query_params ('UPDATE groups
586 short_description=$3,
591 use_pm_depend_box=$8,
602 array (htmlspecialchars($group_name),
604 htmlspecialchars($short_description),
622 $this->setError(sprintf(_('Error updating project information: %s'), db_error()));
627 if ($this->setTags($tags) === false) {
632 $hook_params = array ();
633 $hook_params['group'] = $this;
634 $hook_params['group_id'] = $this->getID();
635 $hook_params['group_homepage'] = $homepage;
636 $hook_params['group_name'] = htmlspecialchars($group_name);
637 $hook_params['group_description'] = htmlspecialchars($short_description);
638 plugin_hook ("group_update", $hook_params);
640 // Log the audit trail
641 $this->addHistory('Changed Public Info', '');
643 if (!$this->fetchData($this->getID())) {
652 * getID - Simply return the group_id for this object.
654 * @return int group_id.
657 return $this->data_array['group_id'];
661 * getType() - Foundry, project, etc.
663 * @return int The type flag from the database.
666 return $this->data_array['type_id'];
671 * getStatus - the status code.
673 * Statuses char include I,H,A,D.
675 function getStatus() {
676 return $this->data_array['status'];
680 * setStatus - set the status code.
682 * Statuses include I,H,A,D.
684 * @param object User requesting operation (for access control).
685 * @param string Status value.
686 * @return boolean success.
689 function setStatus(&$user, $status) {
692 if (!forge_check_global_perm ('approve_projects')) {
693 $this->setPermissionDeniedError();
697 // Projects in 'A' status can only go to 'H' or 'D'
698 // Projects in 'D' status can only go to 'A'
699 // Projects in 'P' status can only go to 'A' OR 'D'
700 // Projects in 'I' status can only go to 'P'
701 // Projects in 'H' status can only go to 'A' OR 'D'
702 $allowed_status_changes = array(
703 'AH'=>1,'AD'=>1,'DA'=>1,'PA'=>1,'PD'=>1,
704 'IP'=>1,'HA'=>1,'HD'=>1
707 // Check that status transition is valid
708 if ($this->getStatus() != $status
709 && !$allowed_status_changes[$this->getStatus().$status]) {
710 $this->setError(_('Invalid Status Change'));
716 $res = db_query_params ('UPDATE groups
718 WHERE group_id=$2', array ($status, $this->getID())) ;
720 if (!$res || db_affected_rows($res) < 1) {
721 $this->setError(sprintf(_('ERROR: DB: Could not change group status: %s'),db_error()));
727 // Activate system group, if not yet
728 if (!$SYS->sysCheckGroup($this->getID())) {
729 if (!$SYS->sysCreateGroup($this->getID())) {
730 $this->setError($SYS->getErrorMessage());
735 if (!$this->activateUsers()) {
740 /* Otherwise, the group is not active, and make sure that
741 System group is not active either */
742 } else if ($SYS->sysCheckGroup($this->getID())) {
743 if (!$SYS->sysRemoveGroup($this->getID())) {
744 $this->setError($SYS->getErrorMessage());
750 $hook_params = array ();
751 $hook_params['group'] = $this;
752 $hook_params['group_id'] = $this->getID();
753 $hook_params['status'] = $status;
754 plugin_hook ("group_setstatus", $hook_params);
758 // Log the audit trail
759 if ($status != $this->getStatus()) {
760 $this->addHistory('Status', $this->getStatus());
763 $this->data_array['status'] = $status;
768 * isProject - Simple boolean test to see if it's a project or not.
770 * @return boolean is_project.
772 function isProject() {
773 if ($this->getType()==1) {
781 * isPublic - Wrapper around RBAC to check if a project is anonymously readable
783 * @return boolean is_public.
785 function isPublic() {
786 $ra = RoleAnonymous::getInstance() ;
787 return $ra->hasPermission('project_read', $this->getID());
791 * isActive - Database field status of 'A' returns true.
793 * @return boolean is_active.
795 function isActive() {
796 if ($this->getStatus()=='A') {
804 * isTemplate - Simply returns the is_template flag from the database.
806 * @return boolean is_template.
808 function isTemplate() {
809 return $this->data_array['is_template'];
813 * setAsTemplate - Set the template status of a project
815 * @param boolean is_template.
817 function setAsTemplate ($booleanparam) {
819 $booleanparam = $booleanparam ? 1 : 0 ;
820 $res = db_query_params ('UPDATE groups SET is_template=$1 WHERE group_id=$2',
821 array ($booleanparam, $this->getID()));
823 $this->data_array['is_template']=$booleanparam;
833 * getTemplateProject - Return the project template this project is built from
835 * @return object The template project
837 function getTemplateProject() {
838 return group_get_object($this->data_array['built_from_template']);
842 * getUnixName - the unix_name
844 * @return string unix_name.
846 function getUnixName() {
847 return strtolower($this->data_array['unix_group_name']);
851 * getPublicName - the full-length public name.
853 * @return string The group_name.
855 function getPublicName() {
856 return $this->data_array['group_name'];
860 * getRegisterPurpose - the text description of the purpose of this project.
862 * @return string The description.
864 function getRegisterPurpose() {
865 return $this->data_array['register_purpose'];
869 * getDescription - the text description of this project.
871 * @return string The description.
873 function getDescription() {
874 return $this->data_array['short_description'];
878 * getStartDate - the unix time this project was registered.
880 * @return int (unix time) of registration.
882 function getStartDate() {
883 return $this->data_array['register_time'];
887 * getLogoImageID - the id of the logo in the database for this project.
889 * @return int The ID of logo image in db_images table (or 100 if none).
891 function getLogoImageID() {
892 return $this->data_array['logo_image_id'];
896 * getUnixBox - the hostname of the unix box where this project is located.
898 * @return string The name of the unix machine for the group.
900 function getUnixBox() {
901 return $this->data_array['unix_box'];
905 * getSCMBox - the hostname of the scm box where this project is located.
907 * @return string The name of the unix machine for the group.
909 function getSCMBox() {
910 return $this->data_array['scm_box'];
913 * setSCMBox - the hostname of the scm box where this project is located.
915 * @param string The name of the new SCM_BOX
917 function setSCMBox($scm_box) {
919 if ($scm_box == $this->data_array['scm_box']) {
924 $res = db_query_params ('UPDATE groups SET scm_box=$1 WHERE group_id=$2', array ($scm_box, $this->getID ()));
926 $this->addHistory('scm_box', $this->data_array['scm_box']);
927 $this->data_array['scm_box']=$scm_box;
932 $this->setError(_("Couldn't insert SCM_BOX to database"));
936 $this->setError(_("SCM Box can't be empty"));
942 * getDomain - the hostname.domain where their web page is located.
944 * @return string The name of the group [web] domain.
946 function getDomain() {
947 return $this->data_array['http_domain'];
951 * getLicense - the license they chose.
953 * @return int ident of group license.
955 function getLicense() {
956 return $this->data_array['license'];
960 * getLicenseName - the name of the license
962 * @return string license name
964 function getLicenseName() {
965 $licenses =& group_get_licenses();
966 if(isset($licenses[$this->data_array['license']])) {
967 return $licenses[$this->data_array['license']];
974 * getLicenseOther - optional string describing license.
976 * @return string The custom license.
978 function getLicenseOther() {
979 if ($this->getLicense() == GROUP_LICENSE_OTHER) {
980 return $this->data_array['license_other'];
987 * getRegistrationPurpose - the text description of the purpose of this project.
989 * @return string The application for project hosting.
991 function getRegistrationPurpose() {
992 return $this->data_array['register_purpose'];
997 * getAdmins() - Get array of Admin user objects.
999 * @return array Array of User objects.
1001 function &getAdmins() {
1002 $roles = RBACEngine::getInstance()->getRolesByAllowedAction ('project_admin', $this->getID()) ;
1004 $user_ids = array () ;
1006 foreach ($roles as $role) {
1007 if (! ($role instanceof RoleExplicit)) {
1010 if ($role->getHomeProject() == NULL
1011 || $role->getHomeProject()->getID() != $this->getID()) {
1015 foreach ($role->getUsers() as $u) {
1016 $user_ids[] = $u->getID() ;
1020 return user_get_objects(array_unique($user_ids));
1025 Common Group preferences for tools
1030 * enableAnonSCM - whether or not this group has opted to enable Anonymous SCM.
1032 * @return boolean enable_scm.
1034 function enableAnonSCM() {
1036 $r = RoleAnonymous::getInstance () ;
1037 return $r->hasPermission ('scm', $this->getID(), 'read') ;
1039 if ($this->isPublic() && $this->usesSCM()) {
1040 return $this->data_array['enable_anonscm'];
1047 function SetUsesAnonSCM ($booleanparam) {
1049 $booleanparam = $booleanparam ? 1 : 0 ;
1051 $r = RoleAnonymous::getInstance () ;
1052 $r->setSetting ('scm', $this->getID(), $booleanparam) ;
1055 $res = db_query_params ('UPDATE groups SET enable_anonscm=$1 WHERE group_id=$2',
1056 array ($booleanparam, $this->getID()));
1058 $this->data_array['enable_anonscm']=$booleanparam;
1067 function setUsesSCM ($booleanparam) {
1069 $booleanparam = $booleanparam ? 1 : 0 ;
1070 $res = db_query_params ('UPDATE groups SET use_scm=$1 WHERE group_id=$2',
1071 array ($booleanparam, $this->getID()));
1073 $this->data_array['use_scm']=$booleanparam;
1082 * enablePserver - whether or not this group has opted to enable Pserver.
1084 * @return boolean enable_pserver.
1086 function enablePserver() {
1087 if ($this->usesSCM()) {
1088 return $this->data_array['enable_pserver'];
1094 function SetUsesPserver ($booleanparam) {
1096 $booleanparam = $booleanparam ? 1 : 0 ;
1097 $res = db_query_params ('UPDATE groups SET enable_pserver=$1 WHERE group_id=$2',
1098 array ($booleanparam, $this->getID()));
1100 $this->data_array['enable_pserver']=$booleanparam;
1109 * usesSCM - whether or not this group has opted to use SCM.
1111 * @return boolean uses_scm.
1113 function usesSCM() {
1115 if (forge_get_config('use_scm')) {
1116 return $this->data_array['use_scm'];
1123 * setUseSCM - Set the SCM usage
1125 * @param boolean enabled/disabled
1127 function setUseSCM ($booleanparam) {
1129 $booleanparam = $booleanparam ? 1 : 0 ;
1130 $res = db_query_params ('UPDATE groups SET use_scm=$1 WHERE group_id=$2',
1131 array ($booleanparam, $this->getID()));
1133 $this->data_array['use_scm']=$booleanparam;
1143 * usesMail - whether or not this group has opted to use mailing lists.
1145 * @return boolean uses_mail.
1147 function usesMail() {
1149 if (forge_get_config('use_mail')) {
1150 return $this->data_array['use_mail'];
1157 * setUseMail - Set the mailing-list usage
1159 * @param boolean enabled/disabled
1161 function setUseMail ($booleanparam) {
1163 $booleanparam = $booleanparam ? 1 : 0 ;
1164 $res = db_query_params ('UPDATE groups SET use_mail=$1 WHERE group_id=$2',
1165 array ($booleanparam, $this->getID()));
1167 $this->data_array['use_mail']=$booleanparam;
1177 * usesNews - whether or not this group has opted to use news.
1179 * @return boolean uses_news.
1181 function usesNews() {
1183 if (forge_get_config('use_news')) {
1184 return $this->data_array['use_news'];
1191 * usesForum - whether or not this group has opted to use discussion forums.
1193 * @return boolean uses_forum.
1195 function usesForum() {
1197 if (forge_get_config('use_forum')) {
1198 return $this->data_array['use_forum'];
1205 * setUseForum - Set the forum usage
1207 * @param boolean enabled/disabled
1209 function setUseForum ($booleanparam) {
1211 $booleanparam = $booleanparam ? 1 : 0 ;
1212 $res = db_query_params ('UPDATE groups SET use_forum=$1 WHERE group_id=$2',
1213 array ($booleanparam, $this->getID()));
1215 $this->data_array['use_forum']=$booleanparam;
1225 * usesStats - whether or not this group has opted to use stats.
1227 * @return boolean uses_stats.
1229 function usesStats() {
1230 return $this->data_array['use_stats'];
1234 * usesFRS - whether or not this group has opted to use file release system.
1236 * @return boolean uses_frs.
1238 function usesFRS() {
1240 if (forge_get_config('use_frs')) {
1241 return $this->data_array['use_frs'];
1248 * setUseFRS - Set the FRS usage
1250 * @param boolean enabled/disabled
1252 function setUseFRS ($booleanparam) {
1254 $booleanparam = $booleanparam ? 1 : 0 ;
1255 $res = db_query_params ('UPDATE groups SET use_frs=$1 WHERE group_id=$2',
1256 array ($booleanparam, $this->getID()));
1258 $this->data_array['use_frs']=$booleanparam;
1268 * usesTracker - whether or not this group has opted to use tracker.
1270 * @return boolean uses_tracker.
1272 function usesTracker() {
1274 if (forge_get_config('use_tracker')) {
1275 return $this->data_array['use_tracker'];
1282 * setUseTracker - Set the tracker usage
1284 * @param boolean enabled/disabled
1286 function setUseTracker ($booleanparam) {
1288 $booleanparam = $booleanparam ? 1 : 0 ;
1289 $res = db_query_params ('UPDATE groups SET use_tracker=$1 WHERE group_id=$2',
1290 array ($booleanparam, $this->getID()));
1292 $this->data_array['use_tracker']=$booleanparam;
1302 * useCreateOnline - whether or not this group has opted to use create online documents option.
1304 * @return boolean use_docman_create_online.
1306 function useCreateOnline() {
1308 if (forge_get_config('use_docman')) {
1309 return $this->data_array['use_docman_create_online'];
1316 * usesDocman - whether or not this group has opted to use docman.
1318 * @return boolean use_docman.
1320 function usesDocman() {
1322 if (forge_get_config('use_docman')) {
1323 return $this->data_array['use_docman'];
1330 * setUseDocman - Set the docman usage
1332 * @param boolean enabled/disabled
1334 function setUseDocman ($booleanparam) {
1336 $booleanparam = $booleanparam ? 1 : 0 ;
1337 $res = db_query_params ('UPDATE groups SET use_docman=$1 WHERE group_id=$2',
1338 array ($booleanparam, $this->getID()));
1340 $this->data_array['use_docman']=$booleanparam;
1350 * useDocmanSearch - whether or not this group has opted to use docman search engine.
1352 * @return boolean use_docman_search.
1354 function useDocmanSearch() {
1356 if (forge_get_config('use_docman')) {
1357 return $this->data_array['use_docman_search'];
1364 * useWebdav - whether or not this group has opted to use webdav interface.
1366 * @return boolean use_docman_search.
1368 function useWebdav() {
1370 if (forge_get_config('use_webdav')) {
1371 return $this->data_array['use_webdav'];
1378 * usesFTP - whether or not this group has opted to use FTP.
1380 * @return boolean uses_ftp.
1382 function usesFTP() {
1384 if (forge_get_config('use_ftp')) {
1385 return $this->data_array['use_ftp'];
1392 * usesSurvey - whether or not this group has opted to use surveys.
1394 * @return boolean uses_survey.
1396 function usesSurvey() {
1398 if (forge_get_config('use_survey')) {
1399 return $this->data_array['use_survey'];
1406 * usesPM - whether or not this group has opted to Project Manager.
1408 * @return boolean uses_projman.
1412 if (forge_get_config('use_pm')) {
1413 return $this->data_array['use_pm'];
1420 * setUsePM - Set the PM usage
1422 * @param boolean enabled/disabled
1424 function setUsePM ($booleanparam) {
1426 $booleanparam = $booleanparam ? 1 : 0 ;
1427 $res = db_query_params ('UPDATE groups SET use_pm=$1 WHERE group_id=$2',
1428 array ($booleanparam, $this->getID()));
1430 $this->data_array['use_pm']=$booleanparam;
1440 * getPlugins - get a list of all available group plugins
1442 * @return array array containing plugin_id => plugin_name
1444 function getPlugins() {
1445 if (!isset($this->plugins_data)) {
1446 $this->plugins_data = array () ;
1447 $res = db_query_params ('SELECT group_plugin.plugin_id, plugins.plugin_name
1448 FROM group_plugin, plugins
1449 WHERE group_plugin.group_id=$1
1450 AND group_plugin.plugin_id=plugins.plugin_id', array ($this->getID()));
1451 $rows = db_numrows($res);
1453 for ($i=0; $i<$rows; $i++) {
1454 $plugin_id = db_result($res,$i,'plugin_id');
1455 $this->plugins_data[$plugin_id] = db_result($res,$i,'plugin_name');
1458 return $this->plugins_data ;
1462 * usesPlugin - returns true if the group uses a particular plugin
1464 * @param string name of the plugin
1465 * @return boolean whether plugin is being used or not
1467 function usesPlugin($pluginname) {
1468 $plugins_data = $this->getPlugins() ;
1469 foreach ($plugins_data as $p_id => $p_name) {
1470 if ($p_name == $pluginname) {
1477 * added for Codendi compatibility
1478 * usesServices - returns true if the group uses a particular plugin or feature
1480 * @param string name of the plugin
1481 * @return boolean whether plugin is being used or not
1483 function usesService($feature) {
1484 $plugins_data = $this->getPlugins() ;
1485 $pm = plugin_manager_get_object();
1486 foreach ($plugins_data as $p_id => $p_name) {
1487 if ($p_name == $feature) {
1490 if ($pm->getPluginByName($p_name)->provide($feature) ) {
1498 * setPluginUse - enables/disables plugins for the group
1500 * @param string name of the plugin
1501 * @param boolean the new state
1502 * @return string database result
1504 function setPluginUse($pluginname, $val=true) {
1505 if ($val == $this->usesPlugin($pluginname)) {
1506 // State is already good, returning
1509 $res = db_query_params ('SELECT plugin_id FROM plugins WHERE plugin_name=$1',
1510 array ($pluginname));
1511 $rows = db_numrows($res);
1513 // Error: no plugin by that name
1516 $plugin_id = db_result($res,0,'plugin_id');
1518 unset ($this->plugins_data) ;
1520 $res = db_query_params ('INSERT INTO group_plugin (group_id, plugin_id) VALUES ($1, $2)',
1521 array ($this->getID(),
1525 $res = db_query_params ('DELETE FROM group_plugin WHERE group_id=$1 AND plugin_id=$2',
1526 array ($this->getID(),
1530 $this->normalizeAllRoles () ;
1534 * getDocEmailAddress - get email address(es) to send doc notifications to.
1536 * @return string email address.
1538 function getDocEmailAddress() {
1539 return $this->data_array['new_doc_address'];
1543 * DocEmailAll - whether or not this group has opted to use receive notices on all doc updates.
1545 * @return boolean email_on_all_doc_updates.
1547 function docEmailAll() {
1548 return $this->data_array['send_all_docs'];
1553 * getHomePage - The URL for this project's home page.
1555 * @return string homepage URL.
1557 function getHomePage() {
1558 if (!preg_match("/^[a-zA-Z][a-zA-Z0-9+.-]*:/",
1559 $this->data_array['homepage'])) {
1560 $this->data_array['homepage'] = util_url_prefix() .
1561 $this->data_array['homepage'];
1563 return $this->data_array['homepage'];
1567 * getTags - Tags of this project.
1569 * @return string List of tags.
1571 function getTags() {
1572 $sql = 'SELECT name FROM project_tags WHERE group_id = $1';
1573 $res = db_query_params($sql, array($this->getID()));
1574 return join(', ', util_result_column_to_array($res));
1578 * setTags - Set tags of this project.
1580 * @return string database result.
1582 function setTags($tags) {
1584 $sql='DELETE FROM project_tags WHERE group_id=$1';
1585 $res=db_query_params($sql, array($this->getID()));
1587 $this->setError('Deleting old tags: '.db_error());
1591 $inserted = array();
1592 $tags_array = preg_split('/[;,]/', $tags);
1593 foreach ($tags_array as $tag) {
1594 $tag = preg_replace('/[\t\r\n]/', ' ', $tag);
1595 // Allowed caracteres: [A-Z][a-z][0-9] -_&'#+.
1596 if (preg_match('/[^[:alnum:]| |\-|_|\&|\'|#|\+|\.]/', $tag)) {
1597 $this->setError(_('Bad tag name, you only can use the following characters: [A-Z][a-z][0-9]-_&\'#+. and space'));
1602 if ($tag == '' || array_search($tag, $inserted) !== false) continue;
1603 $sql='INSERT INTO project_tags (group_id,name) VALUES ($1, $2)';
1604 $res=db_query_params($sql, array($this->getID(), $tag));
1606 $this->setError(_('Setting tags:') . ' ' .
1618 * getPermission - Return a Permission for this Group
1620 * @return object The Permission.
1622 function &getPermission() {
1623 return permission_get_object($this);
1627 function delete($sure,$really_sure,$really_really_sure) {
1628 if (!$sure || !$really_sure || !$really_really_sure) {
1629 $this->setMissingParamsError(_('Please tick all checkboxes.'));
1632 if ($this->getID() == forge_get_config('news_group') ||
1633 $this->getID() == 1 ||
1634 $this->getID() == forge_get_config('stats_group') ||
1635 $this->getID() == forge_get_config('peer_rating_group')) {
1636 $this->setError(_('Cannot Delete System Group'));
1639 $perm =& $this->getPermission ();
1640 if (!$perm || !is_object($perm)) {
1641 $this->setPermissionDeniedError();
1643 } elseif ($perm->isError()) {
1644 $this->setPermissionDeniedError();
1646 } elseif (!$perm->isSuperUser()) {
1647 $this->setPermissionDeniedError();
1653 // Remove all the members
1655 $members =& $this->getMembers();
1656 foreach ($members as $i) {
1657 $this->removeUser($i->getID());
1659 // Failsafe until user_group table is gone
1660 $res = db_query_params ('DELETE FROM user_group WHERE group_id=$1',
1661 array ($this->getID())) ;
1663 // unlink roles from this project
1664 $ra = RoleAnonymous::getInstance();
1665 $rl = RoleLoggedIn::getInstance();
1666 $ra->unlinkProject($this);
1667 $rl->unlinkProject($this);
1668 // @todo : unlink all the other roles created in the project...
1673 $atf = new ArtifactTypeFactory($this);
1674 $at_arr =& $atf->getArtifactTypes();
1675 foreach ($at_arr as $i) {
1676 if (!is_object($i)) {
1684 $ff = new ForumFactory($this);
1685 $f_arr =& $ff->getForums();
1686 foreach ($f_arr as $i) {
1687 if (!is_object($i)) {
1693 // Delete Subprojects
1695 $pgf = new ProjectGroupFactory($this);
1696 $pg_arr =& $pgf->getProjectGroups();
1697 foreach ($pg_arr as $i) {
1698 if (!is_object($i)) {
1704 // Delete FRS Packages
1706 //$frspf = new FRSPackageFactory($this);
1707 $res = db_query_params ('SELECT * FROM frs_package WHERE group_id=$1',
1708 array ($this->getID())) ;
1709 //echo 'frs_package'.db_error();
1710 //$frsp_arr =& $frspf->getPackages();
1711 while ($arr = db_fetch_array($res)) {
1712 //if (!is_object($pg_arr[$i])) {
1713 // echo "Not Object: ProjectGroup: ".$i;
1716 $frsp=new FRSPackage($this,$arr['package_id'],$arr);
1722 $news_group=group_get_object(forge_get_config('news_group'));
1723 $res = db_query_params ('SELECT forum_id FROM news_bytes WHERE group_id=$1',
1724 array ($this->getID())) ;
1726 $this->setError(_('Error Deleting News: ').db_error());
1731 for ($i=0; $i<db_numrows($res); $i++) {
1732 $Forum = new Forum($news_group,db_result($res,$i,'forum_id'));
1733 if (!$Forum->delete(1,1)) {
1734 printf (_("Could Not Delete News Forum: %d"),$Forum->getID());
1737 $res = db_query_params ('DELETE FROM news_bytes WHERE group_id=$1',
1738 array ($this->getID())) ;
1740 $this->setError(_('Error Deleting News: ').db_error());
1748 $res = db_query_params ('DELETE FROM doc_data WHERE group_id=$1',
1749 array ($this->getID())) ;
1751 $this->setError(_('Error Deleting Documents: ').db_error());
1756 $res = db_query_params ('DELETE FROM doc_groups WHERE group_id=$1',
1757 array ($this->getID())) ;
1759 $this->setError(_('Error Deleting Documents: ').db_error());
1767 $res=db_query_params('DELETE FROM project_tags WHERE group_id=$1', array($this->getID()));
1769 $this->setError(_('Error Deleting Tags: ').db_error());
1775 // Delete group history
1777 $res = db_query_params ('DELETE FROM group_history WHERE group_id=$1',
1778 array ($this->getID())) ;
1780 $this->setError(_('Error Deleting Project History: ').db_error());
1786 // Delete group plugins
1788 $res = db_query_params ('DELETE FROM group_plugin WHERE group_id=$1',
1789 array ($this->getID())) ;
1791 $this->setError(_('Error Deleting Project Plugins: ').db_error());
1797 // Delete group cvs stats
1799 $res = db_query_params ('DELETE FROM stats_cvs_group WHERE group_id=$1',
1800 array ($this->getID())) ;
1802 $this->setError(_('Error Deleting SCM Statistics: ').db_error());
1810 $sf = new SurveyFactory($this);
1811 $s_arr =& $sf->getSurveys();
1812 foreach ($s_arr as $i) {
1813 if (!is_object($i)) {
1816 if (!$i->delete()) {
1817 $this->setError(_('Could not properly delete the survey'));
1823 // Delete SurveyQuestions
1825 $sqf = new SurveyQuestionFactory($this);
1826 $sq_arr =& $sqf->getSurveyQuestions();
1827 foreach ($sq_arr as $i) {
1828 if (!is_object($i)) {
1831 if (!$i->delete()) {
1832 $this->setError(_('Could not properly delete the survey questions'));
1838 // Delete Mailing List Factory
1840 $mlf = new MailingListFactory($this);
1841 $ml_arr = $mlf->getMailingLists();
1842 foreach ($ml_arr as $i) {
1843 if (!is_object($i)) {
1846 if (!$i->delete(1,1)) {
1847 $this->setError(_('Could not properly delete the mailing list'));
1855 $res = db_query_params ('DELETE FROM trove_group_link WHERE group_id=$1',
1856 array ($this->getID())) ;
1858 $this->setError(_('Error Deleting Trove: ').db_error());
1863 $res = db_query_params ('DELETE FROM trove_agg WHERE group_id=$1',
1864 array ($this->getID())) ;
1866 $this->setError(_('Error Deleting Trove: ').db_error());
1874 $res = db_query_params ('DELETE FROM project_sums_agg WHERE group_id=$1',
1875 array ($this->getID())) ;
1877 $this->setError(_('Error Deleting Counters: ').db_error());
1882 $res = db_query_params ('INSERT INTO deleted_groups (unix_group_name,delete_date,isdeleted) VALUES ($1, $2, $3)',
1883 array ($this->getUnixName(),
1887 $this->setError(_('Error Deleting Project:').' '.db_error());
1892 $res = db_query_params ('DELETE FROM groups WHERE group_id=$1',
1893 array ($this->getID())) ;
1895 $this->setError(_('Error Deleting Project:').' '.db_error());
1905 $hook_params = array ();
1906 $hook_params['group'] = $this;
1907 $hook_params['group_id'] = $this->getID();
1908 plugin_hook ("group_delete", $hook_params);
1910 if (forge_get_config('upload_dir') != '' && $this->getUnixName()) {
1911 exec('/bin/rm -rf '.forge_get_config('upload_dir').'/'.$this->getUnixName().'/');
1913 if (forge_get_config('ftp_upload_dir') != '' && $this->getUnixName()) {
1914 exec('/bin/rm -rf '.forge_get_config('ftp_upload_dir').'/'.$this->getUnixName().'/');
1919 $res = db_query_params ('DELETE FROM rep_group_act_monthly WHERE group_id=$1',
1920 array ($this->getID())) ;
1921 //echo 'rep_group_act_monthly'.db_error();
1922 $res = db_query_params ('DELETE FROM rep_group_act_weekly WHERE group_id=$1',
1923 array ($this->getID())) ;
1924 //echo 'rep_group_act_weekly'.db_error();
1925 $res = db_query_params ('DELETE FROM rep_group_act_daily WHERE group_id=$1',
1926 array ($this->getID())) ;
1927 //echo 'rep_group_act_daily'.db_error();
1928 unset($this->data_array);
1936 Basic functions to add/remove users to/from a group
1937 and update their permissions
1943 * addUser - controls adding a user to a group.
1945 * @param string Unix name of the user to add OR integer user_id.
1946 * @param int The role_id this user should have.
1947 * @return boolean success.
1950 function addUser($user_identifier,$role_id) {
1953 Admins can add users to groups
1956 if (!forge_check_perm ('project_admin', $this->getID())) {
1957 $this->setPermissionDeniedError();
1963 get user id for this user's unix_name
1965 if (is_int ($user_identifier)) { // user_id or user_name
1966 $res_newuser = db_query_params ('SELECT * FROM users WHERE user_id=$1', array ($user_identifier)) ;
1968 $res_newuser = db_query_params ('SELECT * FROM users WHERE user_name=$1', array ($user_identifier)) ;
1970 if (db_numrows($res_newuser) > 0) {
1972 // make sure user is active
1974 if (db_result($res_newuser,0,'status') != 'A') {
1975 $this->setError(_('User is not active. Only active users can be added.'));
1981 // user was found - set new user_id var
1983 $user_id = db_result($res_newuser,0,'user_id');
1985 $role = new Role($this,$role_id);
1986 if (!$role || !is_object($role)) {
1987 $this->setError(_('Error Getting Role Object'));
1990 } elseif ($role->isError()) {
1991 $this->setError('addUser::roleget::'.$role->getErrorMessage());
1997 $role->addUser (user_get_object ($user_id)) ;
1998 if (!$SYS->sysCheckCreateGroup($this->getID())){
1999 $this->setError($SYS->getErrorMessage());
2003 if (!$SYS->sysCheckCreateUser($user_id)) {
2004 $this->setError($SYS->getErrorMessage());
2008 if (!$SYS->sysGroupCheckUser($this->getID(),$user_id)) {
2009 $this->setError($SYS->getErrorMessage());
2016 // if not already a member, add them
2018 $res_member = db_query_params ('SELECT user_id
2020 WHERE user_id=$1 AND group_id=$2',
2021 array ($user_id, $this->getID())) ;
2023 if (db_numrows($res_member) < 1) {
2025 // Create this user's row in the user_group table
2027 $res = db_query_params ('INSERT INTO user_group
2028 (user_id,group_id,admin_flags,forum_flags,project_flags,
2029 doc_flags,cvs_flags,member_role,release_flags,artifact_flags)
2030 VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10)',
2042 //verify the insert worked
2043 if (!$res || db_affected_rows($res) < 1) {
2044 $this->setError(sprintf(_('ERROR: Could Not Add User To Group: %s'),db_error()));
2049 // check and create if group doesn't exists
2051 //echo "<h2>Group::addUser SYS->sysCheckCreateGroup(".$this->getID().")</h2>";
2052 if (!$SYS->sysCheckCreateGroup($this->getID())){
2053 $this->setError($SYS->getErrorMessage());
2058 // check and create if user doesn't exists
2060 //echo "<h2>Group::addUser SYS->sysCheckCreateUser($user_id)</h2>";
2061 if (!$SYS->sysCheckCreateUser($user_id)) {
2062 $this->setError($SYS->getErrorMessage());
2069 //echo "<h2>Group::addUser role->setUser($user_id)</h2>";
2070 if (!$role->setUser($user_id)) {
2071 $this->setError('addUser::role::setUser'.$role->getErrorMessage());
2077 // user was already a member
2078 // make sure they are set up
2080 $user= user_get_object($user_id,$res_newuser);
2081 $user->fetchData($user->getID());
2082 $role = new Role($this,$role_id);
2083 if (!$role || !is_object($role)) {
2084 $this->setError(_('Error Getting Role Object'));
2087 } elseif ($role->isError()) {
2088 $this->setError('addUser::roleget::'.$role->getErrorMessage());
2092 //echo "<h2>Already Member Group::addUser role->setUser($user_id)</h2>";
2093 if (!$role->setUser($user_id)) {
2094 $this->setError('addUser::role::setUser'.$role->getErrorMessage());
2099 // set up their system info
2101 //echo "<h2>Already Member Group::addUser SYS->sysCheckCreateUser($user_id)</h2>";
2102 if (!$SYS->sysCheckCreateUser($user_id)) {
2103 $this->setError($SYS->getErrorMessage());
2111 // user doesn't exist
2113 $this->setError(_('ERROR: User does not exist'));
2118 $hook_params['group'] = $this;
2119 $hook_params['group_id'] = $this->getID();
2120 $hook_params['user'] = &user_get_object($user_id);
2121 $hook_params['user_id'] = $user_id;
2122 plugin_hook ("group_adduser", $hook_params);
2127 $this->addHistory('Added User',$user_identifier);
2133 * removeUser - controls removing a user from a group.
2135 * Users can remove themselves.
2137 * @param int The ID of the user to remove.
2138 * @return boolean success.
2140 function removeUser($user_id) {
2143 if ($user_id != user_getid()
2144 && !forge_check_perm ('project_admin', $this->getID())) {
2145 $this->setPermissionDeniedError();
2152 $user = user_get_object ($user_id) ;
2153 $roles = RBACEngine::getInstance()->getAvailableRolesForUser ($user) ;
2154 $found_role = NULL ;
2155 foreach ($roles as $role) {
2156 if ($role->getHomeProject() && $role->getHomeProject()->getID() == $this->getID()) {
2157 $found_role = $role ;
2161 if ($found_role == NULL) {
2162 $this->setError(sprintf(_('ERROR: User not removed: %s')));
2166 $found_role->removeUser ($user) ;
2167 if (!$SYS->sysGroupCheckUser($this->getID(),$user_id)) {
2168 $this->setError($SYS->getErrorMessage());
2174 $res = db_query_params ('DELETE FROM user_group WHERE group_id=$1 AND user_id=$2',
2175 array ($this->getID(),
2177 if (!$res || db_affected_rows($res) < 1) {
2178 $this->setError(sprintf(_('ERROR: User not removed: %s'),db_error()));
2185 // reassign open artifacts to id=100
2187 $res = db_query_params ('UPDATE artifact SET assigned_to=100
2188 WHERE group_artifact_id
2189 IN (SELECT group_artifact_id
2190 FROM artifact_group_list
2191 WHERE group_id=$1 AND status_id=1 AND assigned_to=$2)',
2192 array ($this->getID(),
2195 $this->setError(_('ERROR: DB: artifact:').' '.db_error());
2201 // reassign open tasks to id=100
2202 // first have to purge any assignments that would cause
2203 // conflict with existing assignment to 100
2205 $res = db_query_params ('DELETE FROM project_assigned_to
2206 WHERE project_task_id IN (SELECT pt.project_task_id
2207 FROM project_task pt, project_group_list pgl, project_assigned_to pat
2208 WHERE pt.group_project_id = pgl.group_project_id
2209 AND pat.project_task_id=pt.project_task_id
2210 AND pt.status_id=1 AND pgl.group_id=$1
2211 AND pat.assigned_to_id=$2)
2212 AND assigned_to_id=100',
2213 array ($this->getID(),
2216 $this->setError(sprintf(_('ERROR: DB: project_assigned_to %d: %s'),1,db_error()));
2220 $res = db_query_params ('UPDATE project_assigned_to SET assigned_to_id=100
2221 WHERE project_task_id IN (SELECT pt.project_task_id
2222 FROM project_task pt, project_group_list pgl
2223 WHERE pt.group_project_id = pgl.group_project_id
2224 AND pt.status_id=1 AND pgl.group_id=$1)
2225 AND assigned_to_id=$2',
2226 array ($this->getID(),
2229 $this->setError(sprintf(_('ERROR: DB: project_assigned_to %d: %s'),2,db_error()));
2235 // Remove user from system
2237 if (!$SYS->sysGroupRemoveUser($this->getID(),$user_id)) {
2238 $this->setError($SYS->getErrorMessage());
2243 $hook_params['group'] = $this;
2244 $hook_params['group_id'] = $this->getID();
2245 $hook_params['user'] = user_get_object($user_id);
2246 $hook_params['user_id'] = $user_id;
2247 plugin_hook ("group_removeuser", $hook_params);
2250 $this->addHistory('Removed User',$user_id);
2257 * updateUser - controls updating a user's role in this group.
2259 * @param int The ID of the user.
2260 * @param int The role_id to set this user to.
2261 * @return boolean success.
2263 function updateUser($user_id,$role_id) {
2266 if (!forge_check_perm ('project_admin', $this->getID())) {
2267 $this->setPermissionDeniedError();
2272 $newrole = RBACEngine::getInstance()->getRoleById ($role_id) ;
2273 if (!$newrole || !is_object($newrole)) {
2274 $this->setError(_('Could Not Get Role'));
2276 } elseif ($newrole->isError()) {
2277 $this->setError(sprintf(_('Role: %s'),$role->getErrorMessage()));
2279 } elseif ($newrole->getHomeProject() == NULL
2280 || $newrole->getHomeProject()->getID() != $this->getID()) {
2281 $this->setError(_('Wrong destination role'));
2284 $user = user_get_object ($user_id) ;
2285 $roles = RBACEngine::getInstance()->getAvailableRolesForUser ($user) ;
2286 $found_role = NULL ;
2287 foreach ($roles as $role) {
2288 if ($role->getHomeProject() && $role->getHomeProject()->getID() == $this->getID()) {
2289 $found_role = $role ;
2293 if ($found_role == NULL) {
2294 $this->setError(sprintf(_('ERROR: User not removed: %s')));
2298 $found_role->removeUser ($user) ;
2299 $newrole->addUser ($user) ;
2301 $role = new Role($this,$role_id);
2302 if (!$role || !is_object($role)) {
2303 $this->setError(_('Could Not Get Role'));
2305 } elseif ($role->isError()) {
2306 $this->setError(sprintf(_('Role: %s'),$role->getErrorMessage()));
2309 //echo "<h3>Group::updateUser role->setUser($user_id)</h3>";
2310 if (!$role->setUser($user_id)) {
2311 $this->setError(sprintf(_('Role: %s'),$role->getErrorMessage()));
2316 $this->addHistory('Updated User',$user_id);
2321 * addHistory - Makes an audit trail entry for this project.
2323 * @param string The name of the field.
2324 * @param string The Old Value for this $field_name.
2325 * @return database result handle.
2328 function addHistory($field_name, $old_value) {
2329 return db_query_params ('INSERT INTO group_history(group_id,field_name,old_value,mod_by,adddate)
2330 VALUES ($1,$2,$3,$4,$5)',
2331 array ($this->getID(),
2339 * activateUsers - Make sure that group members have unix accounts.
2341 * Setup unix accounts for group members. Can be called even
2342 * if members are already active.
2346 function activateUsers() {
2348 Activate member(s) of the project
2352 $members = $this->getUsers (true) ;
2354 foreach ($members as $member) {
2356 foreach (RBACEngine::getInstance()->getAvailableRolesForUser ($member) as $role) {
2357 if ($role->getHomeProject() && $role->getHomeProject()->getID() == $this->getID()) {
2360 if (!$this->addUser($member->getUnixName(),$role->getID())) {
2367 $res_member = db_query_params ('SELECT user_id,role_id FROM user_group WHERE group_id=$1',
2368 array ($this->getID())) ;
2369 while ($row_member = db_fetch_array($res_member)) {
2370 $u = user_get_object($row_member['user_id']) ;
2371 if (!$this->addUser($u->getUnixName(),$row_member['role_id'])) {
2381 * getMembers - returns array of User objects for this project
2383 * @return array of User objects for this group.
2385 function getMembers() {
2386 return $this->getUsers (true) ;
2390 * replaceTemplateStrings - fill-in some blanks with project name
2392 * @param string Template string
2393 * @return string String after replacements
2395 function replaceTemplateStrings($string) {
2396 $string = str_replace ('UNIXNAME', $this->getUnixName(), $string) ;
2397 $string = str_replace ('PUBLICNAME', $this->getPublicName(), $string) ;
2398 $string = str_replace ('DESCRIPTION', $this->getDescription(), $string) ;
2403 * approve - Approve pending project.
2405 * @param object The User object who is doing the updating.
2408 function approve(&$user) {
2410 require_once $gfcommon.'widget/WidgetLayoutManager.class.php';
2412 if ($this->getStatus()=='A') {
2413 $this->setError(_("Group already active"));
2419 // Step 1: Activate group and create LDAP entries
2420 if (!$this->setStatus($user, 'A')) {
2425 // Switch to system language for item creation
2426 setup_gettext_from_sys_lang ();
2428 // Create default roles
2430 $idadmin_group = NULL ;
2431 foreach (get_group_join_requests ($this) as $gjr) {
2432 $idadmin_group = $gjr->getUserID() ;
2435 if ($idadmin_group == NULL) {
2436 $idadmin_group = $user->getID();
2439 $admin_group = db_query_params ('SELECT user_id FROM user_group WHERE group_id=$1 AND admin_flags=$2',
2440 array ($this->getID(),
2442 if (db_numrows($admin_group) > 0) {
2443 $idadmin_group = db_result($admin_group,0,'user_id');
2445 $idadmin_group = $user->getID();
2446 db_query_params ('INSERT INTO user_group (user_id, group_id, admin_flags) VALUES ($1, $2, $3)',
2447 array ($idadmin_group,
2453 $template = $this->getTemplateProject() ;
2454 $id_mappings = array ();
2455 $seen_admin_role = false ;
2457 // Copy roles from template project
2458 foreach ($template->getRoles() as $oldrole) {
2459 if ($oldrole->getHomeProject() != NULL) {
2460 $role = new Role ($this) ;
2462 // Need to use a different role name so that the permissions aren't set from the hardcoded defaults
2463 $role->create ('TEMPORARY ROLE NAME', $data, true) ;
2464 $role->setName ($oldrole->getName()) ;
2465 if ($oldrole->getSetting ('project_admin', $template->getID())) {
2466 $seen_admin_role = true ;
2470 $role->linkProject ($this) ;
2472 $id_mappings['role'][$oldrole->getID()] = $role->getID() ;
2473 // Reuse the project_admin permission
2474 $role->setSetting ('project_admin', $this->getID(), $oldrole->getSetting ('project_admin', $template->getID())) ;
2478 if (!$seen_admin_role) {
2479 $role = new Role($this);
2480 $adminperms = array ('project_admin' => array ($this->getID() => 1)) ;
2481 $role_id = $role->create ('Admin', $adminperms, true) ;
2485 $roles = $this->getRoles() ;
2486 foreach ($roles as $r) {
2487 if ($r->getHomeProject() == NULL) {
2490 if ($r->getSetting ('project_admin', $this->getID())) {
2491 $r->addUser (user_get_object ($idadmin_group)) ;
2496 // Temporarily switch to the submitter's identity
2497 $saved_session = session_get_user () ;
2498 session_set_internal ($idadmin_group) ;
2501 if (forge_get_config ('use_tracker')) {
2502 $this->setUseTracker ($template->usesTracker()) ;
2503 if ($template->usesTracker()) {
2504 $oldatf = new ArtifactTypeFactory ($template) ;
2505 foreach ($oldatf->getArtifactTypes() as $o) {
2506 $t = new ArtifactType ($this) ;
2507 $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()) ;
2508 $id_mappings['tracker'][$o->getID()] = $t->getID() ;
2509 $t->cloneFieldsFrom ($o->getID()) ;
2514 if (forge_get_config ('use_pm')) {
2515 $this->setUsePM ($template->usesPM()) ;
2516 if ($template->usesPM()) {
2517 $oldpgf = new ProjectGroupFactory ($template) ;
2518 foreach ($oldpgf->getProjectGroups() as $o) {
2519 $pg = new ProjectGroup ($this) ;
2520 $pg->create ($this->replaceTemplateStrings($o->getName()),$this->replaceTemplateStrings($o->getDescription()),$o->isPublic(),$o->getSendAllPostsTo()) ;
2521 $id_mappings['pm'][$o->getID()] = $pg->getID() ;
2526 if (forge_get_config ('use_forum')) {
2527 $this->setUseForum ($template->usesForum()) ;
2528 if ($template->usesForum()) {
2529 $oldff = new ForumFactory ($template) ;
2530 foreach ($oldff->getForums() as $o) {
2531 $f = new Forum ($this) ;
2532 $f->create ($this->replaceTemplateStrings($o->getName()),$this->replaceTemplateStrings($o->getDescription()),$o->isPublic(),$o->getSendAllPostsTo(),1,$o->allowAnonymous(),$o->getModerationLevel()) ;
2533 $id_mappings['forum'][$o->getID()] = $f->getID() ;
2538 if (forge_get_config ('use_docman')) {
2539 $this->setUseDocman ($template->usesDocman()) ;
2540 if ($template->usesDocman()) {
2541 $olddgf = new DocumentGroupFactory ($template) ;
2542 // First pass: create all docgroups
2543 $id_mappings['docman_docgroup'][0] = 0 ;
2544 foreach ($olddgf->getDocumentGroups() as $o) {
2545 $ndgf = new DocumentGroup ($this) ;
2546 $ndgf->create($this->replaceTemplateStrings($o->getName())) ;
2547 $id_mappings['docman_docgroup'][$o->getID()] = $ndgf->getID() ;
2549 // Second pass: restore hierarchy links
2550 foreach ($olddgf->getDocumentGroups() as $o) {
2551 $ndgf = new DocumentGroup ($this) ;
2552 $ndgf->fetchData ($id_mappings['docman_docgroup'][$o->getID()]) ;
2553 $ndgf->update ($ndgf->getName(),$id_mappings['docman_docgroup'][$o->getParentID()]) ;
2558 if (forge_get_config ('use_frs')) {
2559 $this->setUseFRS ($template->usesFRS()) ;
2560 if ($template->usesFRS()) {
2561 foreach (get_frs_packages ($template) as $o) {
2562 $newp = new FRSPackage ($this) ;
2563 $nname = $this->replaceTemplateStrings($o->getName()) ;
2564 $newp->create ($nname, $o->isPublic()) ;
2569 if (forge_get_config ('use_mail')) {
2570 $this->setUseMail ($template->usesMail()) ;
2571 if ($template->usesMail()) {
2572 $oldmlf = new MailingListFactory ($template) ;
2573 foreach ($oldmlf->getMailingLists() as $o) {
2574 $ml = new MailingList ($this) ;
2575 $nname = preg_replace ('/^'.$template->getUnixName().'-/','',$o->getName()) ;
2577 $ndescription = $this->replaceTemplateStrings($o->getDescription()) ;
2578 $ml->create ($nname, $ndescription, $o->isPublic()) ;
2584 /* use SCM plugin from template group */
2585 $this->setUseSCM($template->usesSCM());
2587 foreach ($template->getPlugins() as
2588 $plugin_id => $plugin_name) {
2589 $this->setPluginUse($plugin_name);
2592 /* use SCM choice from registration page */
2594 foreach ($template->getPlugins() as
2595 $plugin_id => $plugin_name) {
2596 if (substr($plugin_name, 3) == 'scm' &&
2597 $plugin_name != 'scmhook') {
2598 /* skip copying scm plugins */
2601 /* enable other plugins though */
2602 $this->setPluginUse($plugin_name);
2606 foreach ($template->getRoles() as $oldrole) {
2607 $newrole = RBACEngine::getInstance()->getRoleById ($id_mappings['role'][$oldrole->getID()]) ;
2608 if ($oldrole->getHomeProject() != NULL
2609 && $oldrole->getHomeProject()->getID() == $template->getID()) {
2610 $newrole->setPublic ($oldrole->isPublic()) ;
2612 $oldsettings = $oldrole->getSettingsForProject ($template) ;
2614 $sections = array ('project_read', 'project_admin', 'frs', 'scm', 'docman', 'tracker_admin', 'new_tracker', 'forum_admin', 'new_forum', 'pm_admin', 'new_pm') ;
2615 foreach ($sections as $section) {
2616 $newrole->setSetting ($section, $this->getID(), $oldsettings[$section][$template->getID()]) ;
2619 $sections = array ('tracker', 'pm', 'forum') ;
2620 foreach ($sections as $section) {
2621 if (isset ($oldsettings[$section])) {
2622 foreach ($oldsettings[$section] as $k => $v) {
2623 // Only copy perms for tools that have been copied
2624 if (isset ($id_mappings[$section][$k])) {
2625 $newrole->setSetting ($section,
2626 $id_mappings[$section][$k],
2634 $lm = new WidgetLayoutManager();
2635 $lm->createDefaultLayoutForProject ($this->getID(), $template->getID()) ;
2637 $params = array () ;
2638 $params['template'] = $template ;
2639 $params['project'] = $this ;
2640 $params['id_mappings'] = $id_mappings ;
2641 plugin_hook_by_reference ('clone_project_from_template', $params) ;
2643 // Disable everything
2644 $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',
2646 array ($this->getID())) ;
2649 $this->normalizeAllRoles () ;
2650 $this->activateUsers();
2652 // Delete fake join request
2654 foreach (get_group_join_requests ($this) as $gjr) {
2655 $gjr->delete(true) ;
2659 // Switch back to user preference
2660 session_set_internal ($saved_session->getID()) ;
2661 setup_gettext_from_context();
2665 $this->sendApprovalEmail();
2666 $this->addHistory('Approved', 'x');
2669 // Plugin can make approve operation there
2672 $params[0] = $idadmin_group ;
2673 $params[1] = $this->getID();
2674 plugin_hook('group_approved',$params);
2682 * sendApprovalEmail - Send new project email.
2684 * @return boolean success.
2687 function sendApprovalEmail() {
2688 $admins = RBACEngine::getInstance()->getUsersByAllowedAction ('project_admin', $this->getID()) ;
2690 if (count($admins) < 1) {
2691 $this->setError(_("Group does not have any administrators."));
2695 // send one email per admin
2696 foreach ($admins as $admin) {
2697 setup_gettext_for_user ($admin) ;
2699 $message=sprintf(_('Your project registration for %4$s has been approved.
2701 Project Full Name: %1$s
2702 Project Unix Name: %2$s
2704 Your DNS will take up to a day to become active on our site.
2705 Your web site is accessible through your shell account. Please read
2706 site documentation (see link below) about intended usage, available
2707 services, and directory layout of the account.
2710 own project page in %4$s while logged in, you will find
2711 additional menu functions to your left labeled \'Project Admin\'.
2713 We highly suggest that you now visit %4$s and create a public
2714 description for your project. This can be done by visiting your project
2715 page while logged in, and selecting \'Project Admin\' from the menus
2716 on the left (or by visiting %3$s
2719 Your project will also not appear in the Trove Software Map (primary
2720 list of projects hosted on %4$s which offers great flexibility in
2721 browsing and search) until you categorize it in the project administration
2722 screens. So that people can find your project, you should do this now.
2723 Visit your project while logged in, and select \'Project Admin\' from the
2726 Enjoy the system, and please tell others about %4$s. Let us know
2727 if there is anything we can do to help you.
2730 htmlspecialchars_decode($this->getPublicName()),
2731 $this->getUnixName(),
2732 util_make_url ('/project/admin/?group_id='.$this->getID()),
2733 forge_get_config ('forge_name'));
2735 util_send_message($admin->getEmail(), sprintf(_('%1$s Project Approved'), forge_get_config ('forge_name')), $message);
2737 setup_gettext_from_context();
2745 * sendRejectionEmail - Send project rejection email.
2747 * This function sends out a rejection message to a user who
2748 * registered a project.
2750 * @param int The id of the response to use.
2751 * @param string The rejection message.
2752 * @return completion status.
2755 function sendRejectionEmail($response_id, $message="zxcv") {
2756 $submitters = array () ;
2758 foreach (get_group_join_requests ($this) as $gjr) {
2759 $submitters[] = user_get_object($gjr->getUserID()) ;
2762 $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",
2764 while ($arr = db_fetch_array ($res)) {
2765 $submitter[] =& user_get_object($arr['user_id']);
2769 if (count ($submitters) < 1) {
2770 $this->setError(_("Group does not have any administrators."));
2774 foreach ($submitters as $admin) {
2775 setup_gettext_for_user ($admin) ;
2777 $response=sprintf(_('Your project registration for %3$s has been denied.
2779 Project Full Name: %1$s
2780 Project Unix Name: %2$s
2782 Reasons for negative decision:
2784 '), $this->getPublicName(), $this->getUnixName(), forge_get_config ('forge_name'));
2786 // Check to see if they want to send a custom rejection response
2787 if ($response_id == 0) {
2788 $response .= $message;
2790 $response .= db_result (
2791 db_query_params('SELECT response_text FROM canned_responses WHERE response_id=$1', array ($response_id)),
2796 util_send_message($admin->getEmail(), sprintf(_('%1$s Project Denied'), forge_get_config ('forge_name')), $response);
2797 setup_gettext_from_context();
2804 * sendNewProjectNotificationEmail - Send new project notification email.
2806 * This function sends out a notification email to the
2807 * SourceForge admin user when a new project is
2810 * @return boolean success.
2813 function sendNewProjectNotificationEmail() {
2814 // Get the user who wants to register the project
2815 $submitters = array () ;
2817 foreach (get_group_join_requests ($this) as $gjr) {
2818 $submitters[] = user_get_object($gjr->getUserID()) ;
2821 $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",
2823 while ($arr = db_fetch_array ($res)) {
2824 $submitter[] =& user_get_object($arr['user_id']);
2827 if (count ($submitters) < 1) {
2828 $this->setError(_("Could not find user who has submitted the project."));
2832 $admins = RBACEngine::getInstance()->getUsersByAllowedAction ('approve_projects', -1) ;
2834 if (count($admins) < 1) {
2835 $this->setError(_("There is no administrator to send the mail to."));
2839 foreach ($admins as $admin) {
2840 $admin_email = $admin->getEmail () ;
2841 setup_gettext_for_user ($admin) ;
2843 foreach ($submitters as $u) {
2844 $submitter_names[] = $u->getRealName() ;
2847 $message = sprintf(_('New %1$s Project Submitted
2849 Project Full Name: %2$s
2850 Submitted Description: %3$s
2852 forge_get_config ('forge_name'),
2853 htmlspecialchars_decode($this->getPublicName()),
2854 htmlspecialchars_decode($this->getRegistrationPurpose()));
2856 foreach ($submitters as $submitter) {
2857 $message .= sprintf(_('Submitter: %1$s (%2$s)
2859 $submitter->getRealName(),
2860 $submitter->getUnixName());
2863 $message .= sprintf (_('
2864 Please visit the following URL to approve or reject this project:
2866 util_make_url ('/admin/approve-pending.php')) ;
2867 util_send_message($admin_email, sprintf(_('New %1$s Project Submitted'), forge_get_config ('forge_name')), $message);
2868 setup_gettext_from_context();
2872 $email = $submitter->getEmail() ;
2873 setup_gettext_for_user ($submitter) ;
2875 $message=sprintf(_('New %1$s Project Submitted
2877 Project Full Name: %2$s
2878 Submitted Description: %3$s
2880 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'));
2882 util_send_message($email, sprintf(_('New %1$s Project Submitted'), forge_get_config ('forge_name')), $message);
2883 setup_gettext_from_context();
2892 * validateGroupName - Validate the group name
2894 * @param string Group name.
2896 * @return an error false and set an error is the group name is invalide otherwise return true
2898 function validateGroupName($group_name) {
2899 if (strlen($group_name)<3) {
2900 $this->setError(_('Group name is too short'));
2902 } else if (strlen(htmlspecialchars($group_name))>50) {
2903 $this->setError(_('Group name is too long'));
2905 } else if ($group=group_get_object_by_publicname($group_name)) {
2906 $this->setError(_('Group name already taken'));
2914 * getRoles - Get the roles of the group.
2916 * @return array of Role id of this group.
2918 function getRolesId () {
2919 $role_ids = array () ;
2922 $res = db_query_params ('SELECT role_id FROM pfo_role WHERE home_group_id=$1',
2923 array ($this->getID()));
2924 while ($arr = db_fetch_array($res)) {
2925 $role_ids[] = $arr['role_id'] ;
2927 $res = db_query_params ('SELECT role_id FROM role_project_refs WHERE group_id=$1',
2928 array ($this->getID()));
2929 while ($arr = db_fetch_array($res)) {
2930 $role_ids[] = $arr['role_id'] ;
2933 $res = db_query_params ('SELECT role_id FROM role WHERE group_id=$1',
2934 array ($this->getID()));
2935 while ($arr = db_fetch_array($res)) {
2936 $role_ids[] = $arr['role_id'] ;
2940 return array_unique ($role_ids) ;
2943 function getRoles () {
2944 $result = array () ;
2946 $roles = $this->getRolesId () ;
2948 $engine = RBACEngine::getInstance() ;
2949 foreach ($roles as $role_id) {
2950 $result[] = $engine->getRoleById ($role_id) ;
2953 foreach ($roles as $role_id) {
2954 $result[] = new Role ($this, $role_id) ;
2961 function normalizeAllRoles () {
2962 $roles = $this->getRoles () ;
2964 foreach ($roles as $r) {
2965 $r->normalizeData () ;
2970 * getUnixStatus - Status of activation of unix account.
2972 * @return char (N)one, (A)ctive, (S)uspended or (D)eleted
2974 function getUnixStatus() {
2975 return $this->data_array['unix_status'];
2979 * setUnixStatus - Sets status of activation of unix account.
2981 * @param string The unix status.
2987 * @return boolean success.
2989 function setUnixStatus($status) {
2992 $res = db_query_params ('UPDATE groups SET unix_status=$1 WHERE group_id=$2',
2997 $this->setError(sprintf(_('ERROR - Could Not Update Group Unix Status: %s'),db_error()));
3001 if ($status == 'A') {
3002 if (!$SYS->sysCheckCreateGroup($this->getID())) {
3003 $this->setError($SYS->getErrorMessage());
3008 if ($SYS->sysCheckGroup($this->getID())) {
3009 if (!$SYS->sysRemoveGroup($this->getID())) {
3010 $this->setError($SYS->getErrorMessage());
3017 $this->data_array['unix_status']=$status;
3024 * getUsers - Get the users of a group
3026 * @return array of user's objects.
3028 function getUsers($onlylocal = true) {
3029 if (!isset($this->membersArr)) {
3030 $this->membersArr = array () ;
3034 foreach ($this->getRoles() as $role) {
3036 && ($role->getHomeProject() == NULL || $role->getHomeProject()->getID() != $this->getID())) {
3039 foreach ($role->getUsers() as $user) {
3040 $ids[] = $user->getID() ;
3043 $ids = array_unique ($ids) ;
3044 foreach ($ids as $id) {
3045 $u = user_get_object ($id) ;
3046 if ($u->isActive()) {
3047 $this->membersArr[] = $u ;
3052 $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',
3053 array ($this->getID(),
3055 if (!$users_group_res) {
3056 $this->setError(_('Error: Enable to get users from group'). ' ' . $this->getID() . ' ' .db_error());
3060 for ($i=0; $i<db_numrows($users_group_res); $i++) {
3061 $this->membersArr[$i] = new GFUser(db_result($users_group_res,$i,'user_id'),false);
3066 return $this->membersArr;
3069 function setDocmanCreateOnlineStatus($status) {
3071 /* if we activate search engine, we probably want to reindex */
3072 $res = db_query_params ('UPDATE groups SET use_docman_create_online=$1 WHERE group_id=$2',
3077 $this->setError(sprintf(_('ERROR - Could Not Update Group DocmanCreateOnline Status: %s'),db_error()));
3081 $this->data_array['use_docman_create_online']=$status;
3087 function setDocmanWebdav($status) {
3089 /* if we activate search engine, we probably want to reindex */
3090 $res = db_query_params ('UPDATE groups SET use_webdav=$1 WHERE group_id=$2',
3095 $this->setError(sprintf(_('ERROR - Could Not Update Group UseWebdab Status: %s'),db_error()));
3099 $this->data_array['use_webdav']=$status;
3105 function setDocmanSearchStatus($status) {
3107 /* if we activate search engine, we probably want to reindex */
3108 $res = db_query_params ('UPDATE groups SET use_docman_search=$1, force_docman_reindex=$1 WHERE group_id=$2',
3113 $this->setError(sprintf(_('ERROR - Could Not Update Group UseDocmanSearch Status: %s'),db_error()));
3117 $this->data_array['use_docman_search']=$status;
3123 function setDocmanForceReindexSearch($status) {
3125 /* if we activate search engine, we probably want to reindex */
3126 $res = db_query_params ('UPDATE groups SET force_docman_reindex=$1 WHERE group_id=$2',
3131 $this->setError(sprintf(_('ERROR - Could Not Update Group force_docman_reindex %s'),db_error()));
3135 $this->data_array['force_docman_reindex']=$status;
3141 function setStorageAPI($type) {
3145 function getStorageAPI() {
3151 * group_getname() - get the group name
3153 * @param int The group ID
3157 function group_getname ($group_id = 0) {
3158 $grp = group_get_object($group_id);
3160 return $grp->getPublicName();
3167 * group_getunixname() - get the unixname for a group
3169 * @param int The group ID
3173 function group_getunixname ($group_id) {
3174 $grp = group_get_object($group_id);
3176 return $grp->getUnixName();
3183 * group_get_result() - Get the group object result ID.
3185 * @param int The group ID
3189 function &group_get_result($group_id=0) {
3190 $grp = group_get_object($group_id);
3192 return $grp->getData();
3198 function getAllProjectTags($onlyvisible = true) {
3199 $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',
3202 if (!$res || db_numrows($res) == 0) {
3208 while ($arr = db_fetch_array($res)) {
3210 $group_id = $arr[1];
3211 if (!isset($result[$tag])) {
3212 $result[$tag] = array();
3215 if (!$onlyvisible || forge_check_perm('project_read', $group_id)) {
3216 $p = group_get_object($group_id);
3217 $result[$tag][] = array('unix_group_name' => $p->getUnixName(),
3218 'group_id' => $group_id);
3225 class ProjectComparator {
3226 var $criterion = 'name' ;
3228 function Compare ($a, $b) {
3229 switch ($this->criterion) {
3232 $namecmp = strcoll ($a->getPublicName(), $b->getPublicName()) ;
3233 if ($namecmp != 0) {
3236 /* If several projects share a same public name */
3237 return strcoll ($a->getUnixName(), $b->getUnixName()) ;
3240 return strcmp ($a->getUnixName(), $b->getUnixName()) ;
3243 $aid = $a->getID() ;
3244 $bid = $b->getID() ;
3248 return ($a < $b) ? -1 : 1;
3254 function sortProjectList (&$list, $criterion='name') {
3255 $cmp = new ProjectComparator () ;
3256 $cmp->criterion = $criterion ;
3258 return usort ($list, array ($cmp, 'Compare')) ;
3263 // c-file-style: "bsd"