4 * Copyright 2016,2017, Franck Villaume - TrivialDev
5 * Copyright 2016, Stéphane-Eymeric Bredthauer - TrivialDev
6 * http://fusionforge.org
8 * This file is a part of FusionForge.
10 * FusionForge is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
15 * FusionForge is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
20 * You should have received a copy of the GNU General Public License
21 * along with FusionForge. If not, see <http://www.gnu.org/licenses/>.
24 require (dirname(__FILE__).'/../common/include/env.inc.php');
25 require_once $gfcommon.'include/pre.php';
26 require_once $gfcommon.'docman/Document.class.php';
28 define('MAXSIZE__USER_UNIXNAME', 32);
29 define('MAXSIZE__GROUP_UNIXNAME', 15);
30 define('MAXSIZE__GROUP_PROJECTNAME', 40);
31 define('MAXSIZE__DOCGROUP_NAME', 254);
32 define('MINSIZE__DOCUMENT_DESCRIPTION', 10);
33 define('MAXSIZE__DOCUMENT_DESCRIPTION', 254);
34 define('MAXSIZE__DOCUMENT_TITLE', 254);
35 define('MINSIZE__DOCUMENT_TITLE', 5);
36 define('MAXSIZE__DOCUMENT_VCOMMENT', 200);
37 define('MINSIZE__FRS_PACKAGE_NAME', 3);
39 // table ctf_mapping format
40 // xid | ffobject || ffid
41 // xid = ctf object unique id
42 // ffobject = type of fusionforge object created
43 // ffid = id of the fusionforge object created
44 // this table is used to identify which object has been injected in FusionForge
46 $ff_ctf_mapping = array();
48 $usage = 'Usage: '.$argv[0].' /path/where/is/located/the/splitted/project/xml'."\n";
50 echo 'Path parameter is missing'."\n";
54 $project_path = $argv[1];
56 $testres = db_query_params('select count(*) as count from ctf_mapping', array());
58 $res = db_query_params('CREATE TABLE "ctf_mapping" (
64 echo 'New table ctf_mapping created'."\n";
66 echo 'No database access'."\n";
70 db_query_params('DELETE FROM ctf_mapping where ffobject != $1', array('User'));
71 echo 'DB check OK'."\n";
73 echo 'Get default admin user'."\n";
74 $admins = RBACEngine::getInstance()->getUsersByAllowedAction("forge_admin", -1);
75 $adminUser = $admins[0];
76 if (!$adminUser || $adminUser->isError()) {
77 echo 'Cannot get default admin user'."\n";
80 // let start a new session with default user.
81 session_set_new($adminUser->getID());
82 if (is_dir($project_path.'/project')) {
84 echo 'project found to create or update'."\n";
85 if (is_file($project_path.'/project/project.xml')) {
86 echo 'found xml file to parse'."\n";
87 $simpleXmlLoadedFile = simplexml_load_file($project_path.'/project/project.xml');
88 if ($simpleXmlLoadedFile !== false) {
89 // do not inject deleted project!
90 if ($simpleXmlLoadedFile->isDeleted == "true") {
91 echo 'You are trying to inject deleted project! Aborting'."\n";
92 echo 'Operation not supported'."\n";
96 // generate a uniq project name using microtime
97 $uniq_project_name = microtime(true);
98 $uniq_project_name = preg_replace('/\./', '', $uniq_project_name);
99 // warning: underscore is forbidden by dns, therefore we replace it by dash
100 //$unixname = preg_replace('/_/','-',trim((string)$simpleXmlLoadedFile->name));
101 // ^- the above method does not generate an unique name...
102 $unixname = 'p'.$uniq_project_name;
103 // warning: max MAXSIZE__GROUP_UNIXNAME chars.
104 if (strlen($unixname) > MAXSIZE__GROUP_UNIXNAME) {
105 echo 'Warning! project unixname too long. '.MAXSIZE__GROUP_UNIXNAME.' chars max. Shorten to '.MAXSIZE__GROUP_UNIXNAME.' chars.'."\n";
106 $unixname = substr($unixname, 0, MAXSIZE__GROUP_UNIXNAME);
108 // check if another project exists with the same name
109 $ctfUnixname = group_get_object_by_name($unixname);
110 if ($ctfUnixname && !$ctfUnixname->isError()) {
111 echo 'You are willing to inject this project on a forge containing the same project unixname! Aborting'."\n";
112 echo 'Project unixname must be unique'."\n";
116 $fullname = trim((string)$simpleXmlLoadedFile->title);
117 if (strlen($fullname) > MAXSIZE__GROUP_PROJECTNAME) {
118 echo 'Warning! project title name too long. '.MAXSIZE__GROUP_PROJECTNAME.' chars max. Shorten to '.MAXSIZE__GROUP_PROJECTNAME.' chars.'."\n";
119 $fullname = substr($fullname, 0, MAXSIZE__GROUP_PROJECTNAME);
121 $description = trim((string)$simpleXmlLoadedFile->description);
122 $is_public = trim((string)$simpleXmlLoadedFile['accessLevel']);
123 $username = trim((string)$simpleXmlLoadedFile->createdByUsername);
124 $ctfxid = trim((string)$simpleXmlLoadedFile['xid']);
125 $status = trim((string)$simpleXmlLoadedFile->status);
126 // check if username exists in database. If not, then use the default admin account
127 // warning if $username is > MAXSIZE__USER_UNIXNAME chars, we need to shorten the $username to MAXSIZE__USER_UNIXNAME chars.
128 if (strlen($username) > MAXSIZE__USER_UNIXNAME) {
129 echo 'Information: username used to create project is too long, shorten to '.MAXSIZE__USER_UNIXNAME.' chars first!'."\n";
130 $username = substr($username, 0, MAXSIZE__USER_UNIXNAME);
132 $ctfUser = user_get_object_by_name($username);
133 if (!$ctfUser || $ctfUser->isError()) {
134 echo 'User: '.$username.' used to create the project does not exist in the forge!'."\n";
135 $ctfUser = $adminUser;
136 echo 'Information: fallback to default admin account: '.$ctfUser->getUnixName()."\n";
138 // now create the Group in DB
140 $r = $g->create($ctfUser, $fullname, $unixname, $description, 'Project injected into the database using CTF forklift XML export',
141 'shell', 'scm', $is_public, false);
144 echo 'Error: '.$g->getErrorMessage()."\n";
145 if (isset($GLOBALS['register_error'])) {
146 echo 'More error message: '.$GLOBALS['register_error']."\n";
151 $resxid = db_query_params('insert into ctf_mapping (xid, ffobject, ffid) values ($1, $2, $3)',
152 array($ctfxid, 'Group', $g->getID()));
154 echo 'Error: '.db_error()."\n";
159 // approve project according to XML status value
160 if ($status == 'Active') {
161 $r = $g->approve($adminUser);
163 echo 'Error: '.$g->getErrorMessage()."\n";
168 // is a template project?
169 $istemplate = (boolean)trim((string)$simpleXmlLoadedFile->isTemplate);
170 $g->setAsTemplate($istemplate);
172 echo 'Cannot load project XML file'."\n";
180 if (is_file($project_path.'/user.xml')) {
181 $ff_ctf_mapping['user'] = array();
182 $themeId = getThemeIdFromName(forge_get_config('default_theme'));
184 echo 'Error: missing theme id! Please setup default theme in your configuration file'."\n";
188 echo 'users found to inject'."\n";
189 $simpleXmlLoadedFile = simplexml_load_file($project_path.'/user.xml');
190 if ($simpleXmlLoadedFile !== false) {
191 $xmlObjectUsersArray = $simpleXmlLoadedFile->users->sfuser;
192 foreach ($xmlObjectUsersArray as $xmlObjectUser) {
195 $user_status = trim((string)$xmlObjectUser->status);
196 $user_username = strtolower(trim((string)$xmlObjectUser->username));
197 $original_username = $user_username;
198 $user_createdate = strtotime(trim((string)$xmlObjectUser->dateCreated));
199 // We only support active user.
200 // if another object depends on a deleted/removed user, we will use the "Nobody" user.
201 if ($user_status != 'Active') {
202 if (preg_match('/d-.*[0-9]{6}/', $user_username)) {
203 $user_username = substr($user_username, 2);
204 $underscore = strpos($user_username, '_');
205 $user_username = substr($user_username, 0, $underscore);
208 // $user_username must be 15 chars max!
209 if (strlen($user_username) > MAXSIZE__USER_UNIXNAME) {
210 echo 'Warning: username '.$user_username.' too long! '.MAXSIZE__USER_UNIXNAME.' chars max. removing extra chars'."\n";
211 $user_username = substr($user_username,0,MAXSIZE__USER_UNIXNAME);
213 // Check if another user with same unixname exists. Unixname must be unique!
214 $userObject = user_get_object_by_name($user_username);
215 if (is_object($userObject) && !$userObject->isError()) {
216 echo 'User '.$user_username.' already existing. Skipped!'."\n";
221 $user_email = (string)$xmlObjectUser->email;
222 if (forge_get_config('require_unique_email')) {
223 $userObject = user_get_object_by_email($user_email);
224 if (is_object($userObject) && !$userObject->isError()) {
225 echo 'User '.$user_username.' with email '.$user_email.' existing. Skipped!'."\n";
232 $user_fullname = trim((string)$xmlObjectUser->fullName);
233 // let's split that by default into 2 parts. First part will be firstname...
234 // if no second part, then set is to "unknown"
235 $user_fullnameSplitted = explode(' ', $user_fullname, 2);
236 $user_firstname = $user_fullnameSplitted[0];
237 if (isset($user_fullnameSplitted[1])) {
238 $user_lastname = $user_fullnameSplitted[1];
240 $user_lastname = 'unknown';
242 $user_isSuperUser = (string)$xmlObjectUser->isSuperUser;
243 $user_locale = (string)$xmlObjectUser->locale;
244 // check for language. if not found, set default to en
245 $res = db_query_params('select * from supported_languages where language_code = $1', array($user_locale));
247 if (db_numrows($res) == 0) {
250 $user_language = db_result($res, 0, 'language_id');
253 $user_timezone = (string)$xmlObjectUser->timeZone;
254 $user_xid = (string)$xmlObjectUser['xid'];
255 $user_default_password = 'user1234'; // how to set real value ? should be overwritten by ldap anyway
256 $userObject = new FFUser();
257 $r = $userObject->create($user_username, $user_firstname, $user_lastname,
258 $user_default_password, $user_default_password, $user_email,
259 1, 0, $user_language, $user_timezone, '', '',
260 $themeId, 'shell', '', '', '', '', '', 'US', false, true, $user_createdate);
262 echo 'Error: '.$user_username.' '.$userObject->getErrorMessage()."\n";
263 if (isset($GLOBALS['register_error'])) {
264 echo 'More error message: '.$GLOBALS['register_error']."\n";
269 $userObject->setStatus('A');
270 $resxid = db_query_params('insert into ctf_mapping (xid, ffobject, ffid) values ($1, $2, $3)',
271 array($user_xid, 'User', $userObject->getID()));
273 echo 'Error: '.db_error()."\n";
277 echo 'User '.$user_username.' injected and actived'."\n";
281 $roles = RBACEngine::getInstance()->getRolesByAllowedAction('project_admin', $g->getID());
282 foreach ($roles as $role) {
283 if ($role instanceof RoleExplicit) {
286 // by default there is only 1 admin role.
287 $role->addUser($userObject);
288 $default_added_role_to_user = $role;
293 $ff_ctf_mapping['user'][$original_username] = $user_username;
299 if (is_dir($project_path.'/project')) {
300 if (is_dir($project_path.'/project/roles')) {
301 if (is_file($project_path.'/project/roles/roles.xml')) {
302 $role_first_compute = false;
303 echo 'found roles to be injected into the project'."\n";
304 $simpleXmlLoadedFile = simplexml_load_file($project_path.'/project/roles/roles.xml');
305 if ($simpleXmlLoadedFile !== false) {
306 $roles = $simpleXmlLoadedFile->role;
308 // we have roles to create then delete default one.
309 $existing_roles = $g->getRoles();
310 foreach ($existing_roles as $existing_role) {
311 $existing_role->delete();
314 foreach ($roles as $role) {
315 $role_name = (string)$role->title;
316 $role_xid = (string)$role['xid'];
317 $permissionPerSectionArray = array();
318 $permissionPerSectionArray['project_read'][$g->getID()] = 1;
319 $ctfpermissionsSettings = $role->operationClusters->operation_cluster;
320 foreach ($ctfpermissionsSettings as $ctfpermissionsSetting) {
321 $ctfpermissionSetting = (string)$ctfpermissionsSetting->clusterName;
322 $ctfpermissionSettingFolder = (string)$ctfpermissionsSetting->resourceName;
323 if ($ctfpermissionSettingFolder == '*') {
324 switch ($ctfpermissionSetting) {
325 case 'docman_admin': // fusionforge value: docman 4
326 if (forge_get_config('use_docman') && $g->usesDocman())
327 $permissionPerSectionArray['docman'][$g->getID()] = 4;
329 case 'docman_create': // fusionforge value: docman 3
330 case 'docman_edit': // fusionforge value: docman 3
331 case 'docman_delete': // fusionforge value: docman 3
332 if (forge_get_config('use_docman') && $g->usesDocman()) {
333 if ((isset($permissionPerSectionArray['docman'][$g->getID()]) && $permissionPerSectionArray['docman'][$g->getID()] < 3)
334 || (!isset($permissionPerSectionArray['docman'][$g->getID()]))) {
335 $permissionPerSectionArray['docman'][$g->getID()] = 3;
339 case 'docman_view': // fusionforge value: docman 1
340 if (forge_get_config('use_docman') && $g->usesDocman()) {
341 if ((isset($permissionPerSectionArray['docman'][$g->getID()]) && $permissionPerSectionArray['docman'][$g->getID()] < 1)
342 || (!isset($permissionPerSectionArray['docman'][$g->getID()]))) {
343 $permissionPerSectionArray['docman'][$g->getID()] = 1;
347 case 'scm_admin': // fusionforge value: project_admin 1
348 if (forge_get_config('use_scm') && $g->usesSCM()) {
349 $permissionPerSectionArray['project_admin'][$g->getID()] = 1;
352 case 'scm_commit': // fusionforge value: scm 2
353 case 'scm_delete': // fusionforge value: scm 2
354 if (forge_get_config('use_scm') && $g->usesSCM()) {
355 if ((isset($permissionPerSectionArray['scm'][$g->getID()]) && $permissionPerSectionArray['scm'][$g->getID()] < 1)
356 || (!isset($permissionPerSectionArray['scm'][$g->getID()]))) {
357 $permissionPerSectionArray['scm'][$g->getID()] = 2;
361 case 'scm_view': // fusionforge value: scm 1
362 if (forge_get_config('use_scm') && $g->usesSCM()) {
363 if ((isset($permissionPerSectionArray['scm'][$g->getID()]) && $permissionPerSectionArray['scm'][$g->getID()] < 1)
364 || (!isset($permissionPerSectionArray['scm'][$g->getID()]))) {
365 $permissionPerSectionArray['scm'][$g->getID()] = 1;
369 case 'frs_admin': // fusionforge value: frs_admin 2 + new_frs 4 (package administrator)
372 if (forge_get_config('use_frs') && $g->usesFRS()) {
373 $permissionPerSectionArray['frs_admin'][$g->getID()] = 2;
374 $permissionPerSectionArray['new_frs'][$g->getID()] = 4;
377 case 'frs_view': // fusionforge value: frs_admin = 1 + new_frs = 1 (read only)
378 if (forge_get_config('use_frs') && $g->usesFRS()) {
379 $permissionPerSectionArray['frs_admin'][$g->getID()] = 1;
380 $permissionPerSectionArray['new_frs'][$g->getID()] = 1;
383 case 'discussion_admin': // fusionforge value: forum_admin 1 + new_forum 4 (forum moderator)
384 case 'discussion_delete':
385 if (forge_get_config('use_forum') && $g->usesForum()) {
386 $permissionPerSectionArray['forum_admin'][$g->getID()] = 1;
387 $permissionPerSectionArray['new_forum'][$g->getID()] = 4;
390 case 'discussion_participate': // fusionforge value: forum_admin = 0 + new_forum = 2 (moderated post)
391 if (forge_get_config('use_forum') && $g->usesForum()) {
392 $permissionPerSectionArray['forum_admin'][$g->getID()] = 1;
393 $permissionPerSectionArray['new_forum'][$g->getID()] = 2;
396 case 'discussion_view': // fusionforge value: forum_admin = 0 + new_forum = 1 (read only)
397 if (forge_get_config('use_forum') && $g->usesForum()) {
398 $permissionPerSectionArray['forum_admin'][$g->getID()] = 1;
399 $permissionPerSectionArray['new_forum'][$g->getID()] = 1;
402 case 'tracker_admin': // fusionforge value: tracker_admin 1 + new_tracker = 15 (manager + tech without vote)
403 if (forge_get_config('use_tracker') && $g->usesTracker()) {
404 $permissionPerSectionArray['tracker_admin'][$g->getID()] = 1;
405 $permissionPerSectionArray['new_tracker'][$g->getID()] = 15;
408 case 'tracker_create': // fusionforge value: tracker_admin = 0 + new_tracker = 11 (technician)
409 case 'tracker_delete':
411 if (forge_get_config('use_tracker') && $g->usesTracker()) {
412 $permissionPerSectionArray['tracker_admin'][$g->getID()] = 0;
413 $permissionPerSectionArray['new_tracker'][$g->getID()] = 11;
416 case 'tracker_view': // fusionforge value: tracker_admin = 0 + new_tracker = 1 (read only)
417 if (forge_get_config('use_tracker') && $g->usesTracker()) {
418 $permissionPerSectionArray['tracker_admin'][$g->getID()] = 0;
419 $permissionPerSectionArray['new_tracker'][$g->getID()] = 1;
422 case 'taskmgr_admin': // fusionforge value: pm_admin = 1 + new_pm = 7 (tech + manager)
423 case 'taskmgr_delete':
424 if (forge_get_config('use_pm') && $g->usesPM()) {
425 $permissionPerSectionArray['pm_admin'][$g->getID()] = 1;
426 $permissionPerSectionArray['new_pm'][$g->getID()] = 7;
430 echo 'Role permission setting '.$ctfpermissionSetting.' unknown? To be implemented'."\n";
435 $newrole = new Role($g);
436 if ($newrole->create($role_name, $permissionPerSectionArray)) {
437 echo 'New role '.$role_name.' created'."\n";
438 $role_members = $role->roleUsers->role_user;
439 foreach ($role_members as $role_member) {
440 $member_name = (string)$role_member->username;
441 // check user really exists before binding it to a role
442 if (strlen($member_name) > MAXSIZE__USER_UNIXNAME)
443 $member_name = substr($member_name, 0, MAXSIZE__USER_UNIXNAME);
444 $member_nameObject = user_get_object_by_name($member_name);
445 if ($member_nameObject && !$member_nameObject->isError()) {
446 if ($newrole->addUser($member_nameObject)) {
447 echo 'User '.$member_name.' binded to role '.$role_name."\n";
449 echo 'Cannot bind user '.$member_name.' to this role '.$role_name."\n";
452 echo 'User '.$member_name.' does not exist! Cannot bind it to this role '.$role_name."\n";
455 $resxid = db_query_params('insert into ctf_mapping (xid, ffobject, ffid) values ($1, $2, $3)',
456 array($role_xid, 'Role', $newrole->getID()));
457 echo $role_name.' injected'."\n";
459 echo 'Cannot create new role '.$role_name."\n";
462 $role_first_compute = true;
466 if (is_dir($project_path.'/project/applications')) {
467 echo 'found features to setup or update for this project'."\n";
468 $dummyFeatureStatusArr = array();
469 if (is_file($project_path.'/project/applications/applications.xml')) {
470 echo 'found xml to parse with dummy features to enable without any data'."\n";
471 $simpleXmlLoadedFile = simplexml_load_file($project_path.'/project/applications/applications.xml');
472 if ($simpleXmlLoadedFile !== false) {
473 foreach ($simpleXmlLoadedFile as $key => $value) {
474 $dummyFeatureStatusArr[(string)$key] = true;
477 echo 'Cannot load applications XML file'."\n";
481 $dirContentArray = scandir($project_path.'/project/applications');
482 if ($dirContentArray) {
483 if (count($dirContentArray) > 0) {
484 $mergeFeaturesArray = array_merge($dirContentArray, $dummyFeatureStatusArr);
486 $mergeFeaturesArray = $dummyFeatureStatusArr;
488 foreach ($mergeFeaturesArray as $contentElement) {
489 $feature_keep = true;
490 if ($contentElement == '.' || $contentElement == '..' || $contentElement == 'applications.xml')
491 $feature_keep = false;
494 enableFeature($g, $contentElement);
495 if (is_dir($project_path.'/project/applications/'.$contentElement)) {
496 if (is_file($project_path.'/project/applications/'.$contentElement.'/'.$contentElement.'.xml')) {
497 computeXmlApplication($g, $contentElement, $project_path);
503 echo 'Unable to list files & directories in '.$project_path.'/project/applications'."\n";
507 // second computation for roles on specific sections that requires to be create first before setting permissions.
508 if (is_dir($project_path.'/project/roles')) {
509 if (is_file($project_path.'/project/roles/roles.xml') && $role_first_compute) {
510 $simpleXmlLoadedFile = simplexml_load_file($project_path.'/project/roles/roles.xml');
511 if ($simpleXmlLoadedFile !== false) {
512 echo 'second computation of role to attribute correct permission to role based on injected objects'."\n";
513 $roles = $simpleXmlLoadedFile->role;
514 foreach ($roles as $role) {
515 $role_xid = (string)$role['xid'];
516 $roleFFId = get_ff_id('Role', $role_xid);
518 $roleFFObject = new Role($g, $roleFFId);
519 if ($roleFFObject && !$roleFFObject->isError()) {
520 $permissionPerSectionArray = $roleFFObject->getSettingsForProject($g);
521 $ctfpermissionsSettings = $role->operationClusters->operation_cluster;
522 foreach ($ctfpermissionsSettings as $ctfpermissionsSetting) {
523 $ctfpermissionSetting = (string)$ctfpermissionsSetting->clusterName;
524 $ctfpermissionSettingFolder = (string)$ctfpermissionsSetting->ressourceName;
525 if ($ctfpermissionSettingFolder != '*') {
526 $ctfpermissionSettingRessource = (string)$ctfpermissionsSetting->resourceValue;
528 switch ($ctfpermissionSetting) {
529 case 'docman_admin': // fusionforge value: docman 4; Warning: this is FusionForge specific. There is no permission per folder. We overwrite the general value if missing.
530 if (forge_get_config('use_docman') && $g->usesDocman())
531 $permissionPerSectionArray['docman'][$g->getID()] = 4;
533 case 'docman_create': // fusionforge value: docman 3; Warning: this is FusionForge specific. There is no permission per folder. We overwrite the general value if missing.
535 case 'docman_delete':
536 if (forge_get_config('use_docman') && $g->usesDocman()) {
537 if ((isset($permissionPerSectionArray['docman'][$g->getID()]) && $permissionPerSectionArray['docman'][$g->getID()] < 3)
538 || (!isset($permissionPerSectionArray['docman'][$g->getID()]))) {
539 $permissionPerSectionArray['docman'][$g->getID()] = 3;
543 case 'docman_view': // fusionforge value: docman 1; Warning: this is FusionForge specific. There is no permission per folder. We overwrite the general value if missing.
544 if (forge_get_config('use_docman') && $g->usesDocman()) {
545 if ((isset($permissionPerSectionArray['docman'][$g->getID()]) && $permissionPerSectionArray['docman'][$g->getID()] < 1)
546 || (!isset($permissionPerSectionArray['docman'][$g->getID()]))) {
547 $permissionPerSectionArray['docman'][$g->getID()] = 1;
551 case 'scm_admin': // fusionforge value: project_admin 1; Warning: this is FusionForge specific. There is no permission as scm_admin. We overwrite the general value if missing.
552 if (forge_get_config('use_scm') && $g->usesSCM()) {
553 $permissionPerSectionArray['project_admin'][$g->getID()] = 1;
556 case 'scm_commit': // fusionforge value: scm 2; Warning: this is FusionForge specific. There is no permission per repository. We overwrite the general value if missing.
558 if (forge_get_config('use_scm') && $g->usesSCM()) {
559 if ((isset($permissionPerSectionArray['scm'][$g->getID()]) && $permissionPerSectionArray['scm'][$g->getID()] < 1)
560 || (!isset($permissionPerSectionArray['scm'][$g->getID()]))) {
561 $permissionPerSectionArray['scm'][$g->getID()] = 2;
565 case 'scm_view': // fusionforge value: scm 1; Warning: this is FusionForge specific. There is no permission per repository. We overwrite the general value if missing.
566 if (forge_get_config('use_scm') && $g->usesSCM()) {
567 if ((isset($permissionPerSectionArray['scm'][$g->getID()]) && $permissionPerSectionArray['scm'][$g->getID()] < 1)
568 || (!isset($permissionPerSectionArray['scm'][$g->getID()]))) {
569 $permissionPerSectionArray['scm'][$g->getID()] = 1;
573 case 'frs_admin': // fusionforge value: frs 4 (package administrator)
576 if (forge_get_config('use_frs') && $g->usesFRS()) {
577 set_permission_in_role($permissionPerSectionArray, $ctfpermissionSettingRessource, 'FRSPackage', 'frs', 4);
580 case 'frs_view': // fusionforge value: frs_admin = 1 + new_frs = 1 (read only)
581 if (forge_get_config('use_frs') && $g->usesFRS()) {
582 set_permission_in_role($permissionPerSectionArray, $ctfpermissionSettingRessource, 'FRSPackage', 'frs', 1);
585 case 'discussion_admin': // fusionforge value: forum 4 (forum moderator)
586 case 'discussion_delete':
587 if (forge_get_config('use_forum') && $g->usesForum()) {
588 set_permission_in_role($permissionPerSectionArray, $ctfpermissionSettingRessource, 'Forum', 'forum', 4);
591 case 'discussion_participate': // fusionforge value: forum = 2 (moderated post)
592 if (forge_get_config('use_forum') && $g->usesForum()) {
593 set_permission_in_role($permissionPerSectionArray, $ctfpermissionSettingRessource, 'Forum', 'forum', 2);
596 case 'discussion_view': // fusionforge value: forum = 1 (read only)
597 if (forge_get_config('use_forum') && $g->usesForum()) {
598 set_permission_in_role($permissionPerSectionArray, $ctfpermissionSettingRessource, 'Forum', 'forum', 1);
601 case 'taskmgr_admin': // fusionforge value: pm = 7 (tech + manager)
602 case 'taskmgr_delete':
603 if (forge_get_config('use_pm') && $g->usesPM()) {
604 set_permission_in_role($permissionPerSectionArray, $ctfpermissionSettingRessource, 'ProjectGroup', 'pm', 7);
607 case 'tracker_admin': // fusionforge value: tracker_admin 1 + new_tracker = 15 (manager + tech without vote)
608 if (forge_get_config('use_tracker') && $g->usesTracker()) {
609 set_permission_in_role($permissionPerSectionArray, $ctfpermissionSettingRessource, 'ArtifactType', 'tracker', 15);
612 case 'tracker_create': // fusionforge value: tracker 11 (technician)
613 case 'tracker_delete':
615 if (forge_get_config('use_tracker') && $g->usesTracker()) {
616 set_permission_in_role($permissionPerSectionArray, $ctfpermissionSettingRessource, 'ArtifactType', 'tracker', 11);
619 case 'tracker_view': // fusionforge value: tracker = 1 (read only)
620 if (forge_get_config('use_tracker') && $g->usesTracker()) {
621 set_permission_in_role($permissionPerSectionArray, $ctfpermissionSettingRessource, 'ArtifactType', 'tracker', 1);
625 echo 'Specific Role Permission setting unknown. To be implemented?'."\n";
631 echo 'Cannot get Role with FF ID '.$roleFFId.' from database'."\n";
634 echo 'Cannot recompute this role '.$role_xid.'. Not injected in database.'."\n";
641 echo 'No project found'."\n";
642 echo 'Check path of the project tree'."\n";
646 if (is_file($project_path.'/user.xml')) {
648 echo 'users found to recheck for deletion & role cleaning'."\n";
649 $simpleXmlLoadedFile = simplexml_load_file($project_path.'/user.xml');
650 if ($simpleXmlLoadedFile !== false) {
651 $xmlObjectUsersArray = $simpleXmlLoadedFile->users->sfuser;
652 foreach ($xmlObjectUsersArray as $xmlObjectUser) {
653 $user_status = (string)$xmlObjectUser->status;
654 $user_username = (string)$xmlObjectUser->username;
655 // We only support active user.
656 // if another object depends on a deleted/removed user, we will use the "Nobody" user.
657 $user_xid = (string)$xmlObjectUser['xid'];
658 $userFFid = get_ff_id('User', $user_xid);
660 $user = user_get_object($userFFid);
661 if (isset($default_added_role_to_user)) {
662 echo 'removing default role to user '.$user->getUnixName();
663 $default_added_role_to_user->removeUser($user);
665 if ($user_status != 'Active') {
666 echo 'deleting user '.$user->getUnixName()."\n";
675 echo 'Project injected & parametrized'."\n";
678 function enablePlugin($pluginname) {
679 $pm = plugin_manager_get_object();
681 $pluginObject = plugin_get_object($pluginname);
682 if (!$pluginObject || !$pm->isPluginAvailable($pluginObject)) {
683 $res = $pm->activate($pluginname);
685 echo 'Unable to activate plugin: '.$pluginname.' with error: '.db_error()."\n";
688 // Load the plugin and now get information from it.
689 $pm = plugin_manager_get_object();
690 $pm->LoadPlugin($pluginname);
691 $plugin = $pm->GetPluginObject($pluginname);
692 if (!$plugin || $plugin->isError()) {
693 // we need to deactivate the plugin, something went wrong
694 $pm->deactivate($pluginname);
695 echo 'Could not get plugin object '.$pluginname."\n";
698 if (method_exists($plugin, 'install')) {
702 if ($plugin->isError()) {
703 echo 'Error: '.$plugin->getErrorMessage()."\n";
711 function enableFeature(&$g, $value) {
714 case 'discussionApplication': // usesForum
715 if (forge_get_config('use_forum'))
716 $status = $g->setUseForum(true);
718 case 'documentApplication': // usesDocman
719 if (forge_get_config('use_docman'))
720 $status = $g->setUseDocman(true);
722 case 'frsApplication': // usesFRS
723 if (forge_get_config('use_frs'))
724 $status = $g->setUseFRS(true);
726 case 'linkedAppApplication': // uses headermenu plugin
727 // be sure that headermenu plugin is on, if not enable it!
728 if (enablePlugin('headermenu'))
729 $status = $g->setPluginUse('headermenu');
731 case 'newsApplication': // usesNews
732 if (forge_get_config('use_news'))
733 $status = $g->setUseNews(true);
735 case 'pageApplication': // uses vhost ?
737 case 'planningApplication': // planning folder => roadmap from tracker ?
739 case 'reportingApplication': // uses Statistics
740 if (forge_get_config('use_activity'))
741 $status = $g->setUseActivity(true);
743 case 'scmApplication': // usesSCM
744 if (forge_get_config('use_scm'))
745 $status = $g->setUseSCM(true);
747 case 'taskApplication': // usesPM
748 if (forge_get_config('use_pm'))
749 $status = $g->setUsePM(true);
751 case 'trackerApplication': // usesTracker
752 if (forge_get_config('use_tracker'))
753 $status = $g->setUseTracker(true);
755 case 'wikiApplication': // uses wiki plugin ?
756 // be sure that moinmoin plugin is on, if not enable it!
757 if (enablePlugin('moinmoin'))
758 $status = $g->setPluginUse('moinmoin');
761 echo 'Unknown feature '.$value."\n";
765 echo 'feature '.$value.' enabled'."\n";
770 function computeXmlApplication(&$g, $feature, $project_path) {
773 case 'documentApplication': // usesDocman
774 if (forge_get_config('use_docman') && $g->usesDocman()) {
775 echo $feature.' data injection'."\n";
776 // disable search engine to speed up injection
777 //$g->setDocmanSearchStatus(0);
778 $g->setDocmanSearchStatus(1);
779 $status = computeXmldocumentApplication($g, $project_path);
780 // warning to set all permissions correctly
781 system('chown -R '.forge_get_config('apache_user').':'.forge_get_config('apache_group').' '.forge_get_config('data_path').'/docman');
785 case 'frsApplication': // usesFRS
786 if (forge_get_config('use_frs') && $g->usesFRS()) {
787 echo $feature.' data injection'."\n";
788 $status = computeXmlfrsApplication($g, $project_path);
789 system('chown -R '.forge_get_config('apache_user').':'.forge_get_config('apache_group').' '.forge_get_config('data_path').'/download');
792 case 'discussionApplication': // usesForum
793 if (forge_get_config('use_forum') && $g->usesForum()) {
794 echo $feature.' data injection'."\n";
795 $status = computeXmldiscussionApplication($g, $project_path);
798 case 'newsApplication': // usesNews
799 echo $feature.' data injection not yet implemented'."\n";
801 case 'linkedAppApplication': // uses headermenu plugin
802 if ($g->usesPlugin('headermenu')) {
803 echo $feature.' data injection'."\n";
804 $status = computeXmllinkedAppApplication($g, $project_path);
807 case 'pageApplication': // uses vhost ?
808 case 'planningApplication': // planning folder => roadmap from tracker ?
809 case 'reportingApplication': // uses Statistics
810 case 'scmApplication': // usesSCM
811 case 'taskApplication': // usesPM
812 echo $feature.' data injection not yet implemented'."\n";
814 case 'trackerApplication': // usesTracker
815 if (forge_get_config('use_tracker') && $g->usesTracker()) {
816 echo $feature.' data injection'."\n";
817 $status = computeXmltrackerApplication($g, $project_path);
818 system('chown -R '.forge_get_config('apache_user').':'.forge_get_config('apache_group').' '.forge_get_config('data_path').'/tracker');
821 case 'wikiApplication': // uses wiki plugin ?
823 echo $feature.' data injection not yet implemented'."\n";
827 echo 'feature '.$feature.' data injection done'."\n";
832 function computeXmldocumentApplication(&$g, $project_path) {
834 if (is_file($project_path.'/project/applications/documentApplication/documentApplication.xml')) {
835 $simpleXmlLoadedFile = simplexml_load_file($project_path.'/project/applications/documentApplication/documentApplication.xml');
836 if ($simpleXmlLoadedFile !== false) {
837 $documentFolders = $simpleXmlLoadedFile->document_root_folder->documentFolders->document_folder;
838 $subFolderStatus = array();
839 foreach ($documentFolders as $documentFolder) {
840 $subFolderStatus[] = inject_folder($g, $documentFolder, 0, $project_path);
842 if (!in_array(false, $subFolderStatus))
849 function inject_folder(&$g, $documentFolder, $parentFolderId, $project_path) {
851 $docgroup_name = trim((string)$documentFolder->title);
852 // limitation is 255 chars
853 if (strlen($docgroup_name) > MAXSIZE__DOCGROUP_NAME)
854 $docgroup_name = substr($docgroup_name, 0, MAXSIZE__DOCGROUP_NAME);
855 $docgroup_xid = trim((string)$documentFolder['xid']);
856 $docgroup_createdate = trim((string)$documentFolder->dateCreated);
857 $dg = new DocumentGroup($g);
858 // create a new DocumentGroup with default status: 1 = public
859 if ($dg->isError() || !$dg->create($docgroup_name, $parentFolderId, 1, strtotime($docgroup_createdate))) {
860 echo 'Error creation folder '.$dg->getErrorMessage();
865 $documents = $documentFolder->documents->document;
866 $subFolders = $documentFolder->documentFolders->document_folder;
867 $documentStatus = array();
868 foreach ($documents as $document) {
869 $subFolderStatus[] = inject_document($g, $document, $dg->getID(), $project_path);
871 $subFolderStatus = array();
872 foreach ($subFolders as $subFolder) {
873 $subFolderStatus[] = inject_folder($g, $subFolder, $dg->getID(), $project_path);
875 if (in_array(false, $subFolderStatus)) {
878 $resxid = db_query_params('insert into ctf_mapping (xid, ffobject, ffid) values ($1, $2, $3)',
879 array($docgroup_xid, 'DocumentGroup', $dg->getID()));
880 echo 'folder '.$docgroup_name.' injected'."\n";
886 function inject_document(&$g, $document, $folderId, $project_path) {
887 global $adminUser, $ff_ctf_mapping;
888 $document_current_version = 0;
889 $document_versions = $document->documentVersions->document_version;
890 $document_title = trim((string)$document->title);
891 if (strlen($document_title) > MAXSIZE__DOCUMENT_TITLE) {
892 echo 'Information: document title too long. Shorten to '.MAXSIZE__DOCUMENT_TITLE."\n";
893 $document_title = substr($document_title, 0, MAXSIZE__DOCUMENT_TITLE);
894 echo 'New document title: '.$document_title."\n";
896 if (strlen($document_title) < MINSIZE__DOCUMENT_TITLE) {
897 echo 'Information: document title too short. Extented to >'.MINSIZE__DOCUMENT_TITLE."\n";
898 $document_title .= ' [comment: title was too short for automatic import]';
899 echo 'New document title: '.$document_title."\n";
901 $document_description = trim((string)$document->description);
902 if (strlen($document_description) < MINSIZE__DOCUMENT_DESCRIPTION) {
903 echo 'Information: document description too short. Extented to >'.MINSIZE__DOCUMENT_DESCRIPTION."\n";
904 $document_description .= ' [comment: description was too short for automatic import]';
905 echo 'New document description: '.$document_description."\n";
907 if (strlen($document_description) > MAXSIZE__DOCUMENT_DESCRIPTION) {
908 echo 'Information: document description too long. Shorten to '.MAXSIZE__DOCUMENT_DESCRIPTION."\n";
909 $document_description = substr($document_description, 0, MAXSIZE__DOCUMENT_DESCRIPTION);
910 echo 'New document description: '.$document_description."\n";
912 $document_xid = trim((string)$document['xid']);
913 $lockByUsername = trim((string)$document->lockByUsername);
914 $first_version = true;
915 $d = new Document($g);
916 foreach ($document_versions as $document_version) {
917 if ((string)$document_version['currentVersion'] == 'true') {
918 $document_current_version = 1;
920 $filedata = $project_path.'/'.$document_version->attach['filename'];
921 $filename = trim((string)$document_version->attach['fileDisplayName']);
922 if (is_file($filedata)) {
923 $filetype = trim((string)$document_version->attach['mimeType']);
924 $createdByUsername = trim((string)$document_version->createdByUsername);
925 $createdate = trim((string)$document_version->dateCreated);
926 $versionComment = trim((string)$document_version->versionComment);
927 if (strlen($versionComment) > MAXSIZE__DOCUMENT_VCOMMENT) {
928 echo 'Information: document comment too long. Shorten to >'.MAXSIZE__DOCUMENT_VCOMMENT."\n";
929 $versionComment = substr($versionComment, 0, MAXSIZE__DOCUMENT_VCOMMENT);
930 echo 'New document comment: '.$versionComment."\n";
932 $createUserID = get_user_id_by_name($ff_ctf_mapping['user'][$createdByUsername]);
933 if ($createUserID == false) {
934 echo 'Creator User do not exist: use default admin user'."\n";
935 $createUserID = $adminUser->getID();
937 $importData = array('nonotice' => 1, 'nocheck' => 1, 'user' => $createUserID, 'time' => strtotime($createdate));
938 if ($first_version) {
939 if ($d->create($filename, $filetype, $filedata, $folderId, $document_title, $document_description, 1, $versionComment, $importData)) {
940 $resxid = db_query_params('insert into ctf_mapping (xid, ffobject, ffid) values ($1, $2, $3)',
941 array($document_xid, 'Document', $d->getID()));
942 echo 'file '.$filename.' injected'."\n";
943 $first_version = false;
945 echo 'file '.$filename.' injection error '.$d->getErrorMessage()."\n";
947 $first_version = true;
951 if ($d->update($filename, $filetype, $filedata, $folderId, $document_title, $document_description.' '.$versionComment, 1, 0, $document_current_version, 1, $importData, $versionComment)) {
952 echo 'file '.$filename.' new version injected'."\n";
954 echo 'file '.$filename.' new version injection error '.$d->getErrorMessage()."\n";
960 echo 'Error: file xid '.$document_xid.' - '.$filename.'::'.$filedata.' skipped. Missing file!'."\n";
963 if (!$first_version && (strlen($lockByUsername) > 0)) {
964 if (isset($ff_ctf_mapping['user'][$lockByUsername])) {
965 $ffUserID = get_user_id_by_name($ff_ctf_mapping['user'][$lockByUsername]);
966 if ($ffUserID != false) {
967 if ($d->setReservedBy(1, $ffUserID)) {
968 echo 'document reserved'."\n";
970 echo 'Error: unable to reserved document: '.$d->getErrorMessage()."\n";
974 echo 'Warning! cannot set reservation. username not existing.'."\n";
977 echo 'Warning! cannot set reservation. username not existing.'."\n";
983 function computeXmltrackerApplication(&$g, $project_path) {
985 if (is_file($project_path.'/project/applications/trackerApplication/trackerApplication.xml')) {
986 $simpleXmlLoadedFileTracker = simplexml_load_file($project_path.'/project/applications/trackerApplication/trackerApplication.xml');
987 if ($simpleXmlLoadedFileTracker === false) {
988 echo 'Error when loading file trackerApplication.xml'."\n";
989 foreach(libxml_get_errors() as $error) {
990 echo "\t", $error->message;
995 echo 'File not found: '.$project_path.'/project/applications/trackerApplication/trackerApplication.xml'."\n";
1000 if (is_file($project_path.'/project/artifactHistories/artifactHistories.xml')) {
1001 $simpleXmlLoadedFileArtifactHistories = simplexml_load_file($project_path.'/project/artifactHistories/artifactHistories.xml');
1002 if ($simpleXmlLoadedFileArtifactHistories === false) {
1003 echo 'Error when loading file artifactHistories.xml'."\n";
1004 foreach(libxml_get_errors() as $error) {
1005 echo "\t", $error->message;
1010 echo 'Warning: File not found '.$project_path.'/project/artifactHistories/artifactHistories.xml'."\n";
1011 $simpleXmlLoadedFileArtifactHistories = new SimpleXMLElement('<artifactHistories />');
1014 if (is_file($project_path.'/project/auditing/auditing.xml')) {
1015 $simpleXmlLoadedFileAuditing = simplexml_load_file($project_path.'/project/auditing/auditing.xml');
1016 if ($simpleXmlLoadedFileAuditing === false) {
1017 echo 'Error when loading file auditing.xml'."\n";
1018 foreach(libxml_get_errors() as $error) {
1019 echo "\t", $error->message;
1024 echo 'Warning: File not found '.$project_path.'/project/auditing/auditing.xml'."\n";
1025 $simpleXmlLoadedFileAuditing = new SimpleXMLElement('<auditing />');
1029 $trackers = $simpleXmlLoadedFileTracker->tracker;
1030 $histories = $simpleXmlLoadedFileArtifactHistories;
1031 $auditing = $simpleXmlLoadedFileAuditing;
1032 $trackerStatus = array();
1034 $tracker_xid = array();
1035 $default_values = array();
1037 echo 'traker XML :'."\n";
1038 foreach ($trackers as $tracker) {
1040 $tracker_xid[$key] = '';
1041 $default_values[$key]= array();
1042 echo 'key tracker :'.$key."\n";
1043 $trackerStatus[$key] = inject_tracker($g, $tracker, $t[$key], $tracker_xid[$key], $default_values[$key], $project_path);
1048 $artifactStatus = array();
1050 foreach ($trackers as $tracker) {
1051 echo 'key tracker :'.$key."\n";
1052 if ($trackerStatus[$key]) {
1053 $artifacts = $tracker->artifacts->artifact;
1054 if (is_array($artifacts) || is_object($artifacts)) {
1055 foreach ($artifacts as $artifact) {
1056 $artifactStatus[] = inject_artifact($g, $t[$key], $artifact, $histories, $auditing, $tracker_xid[$key], $default_values[$key], $project_path);
1063 if (!in_array(false, $trackerStatus) && !in_array(false, $artifactStatus)) {
1070 function inject_tracker(&$g, $tracker, &$t, &$tracker_xid, &$default_values, $project_path) {
1072 if ((string)$tracker->isDeleted == "true")
1074 $trackername = (string)$tracker->title;
1075 $description = (string)$tracker->description;
1076 if (trim($description)=="") {
1077 $description = $trackername;
1082 //lastModifiedByUsername
1085 $email_address = '';
1087 $use_resolution = '';
1088 $submit_instructions = '';
1089 $browse_instructions = '';
1090 $tracker_xid = (string)$tracker['xid'];
1091 $t = new ArtifactType ($g);
1092 $r = $t->create($trackername, $description, $email_all, $email_address, $due_period, $use_resolution, $submit_instructions, $browse_instructions);
1093 if ($t->isError() || !$r) {
1094 echo 'Error when creating tracker '.$trackername.': '.$t->getErrorMessage()."\n";
1098 $resxid = db_query_params('insert into ctf_mapping (xid, ffobject, ffid) values ($1, $2, $3)', array($tracker_xid, 'ArtifactType', $t->getID()));
1099 echo 'Tracker: '.$trackername.' injected'."\n";
1104 $fields = $tracker->fields->field;
1105 if (is_array($fields) || is_object($fields)) {
1106 $fieldStatus = array();
1107 foreach ($fields as $field) {
1108 $fieldStatus[] = inject_field($t, $field, $default_values, $project_path, $tracker_xid);
1110 if (in_array(false, $fieldStatus))
1121 if ($continue && !empty($tracker->workflow)) {
1123 // update workflow event sequence if < 100
1124 $res = db_query_params ("select setval('artifact_workflow_event_id_seq', GREATEST(currval('artifact_workflow_event_id_seq'),100))");
1125 $arr = db_fetch_array($res);
1126 $r=$t->fetchData($t->getID());
1127 $CSFid = $t->getCustomStatusField();
1128 $CSFname =$t->getExtraFieldName($CSFid);
1129 $CSFElements = $t->getExtraFieldElements($CSFid);
1130 $allElements = array_map('get_column_element_id',$CSFElements);
1131 // php>=5.5 : $allNodes = array_column($CSFElements, 'element_id');
1132 $CSFElements [] = Array( 'element_id' => 100, 'element_name'=>'fldv-new', 'status_id' => 0);
1134 $w = new ArtifactWorkflow($t, $CSFid);
1135 if (is_array($fields) || is_object($fields))
1136 foreach ($fields as $field) {
1137 if ($field->name == $CSFname) {
1144 $transitions = $tracker->workflow->transition;
1145 if (is_array($CSFElements) || is_object($CSFElements)) {
1146 foreach ($CSFElements as $element) {
1147 echo "element : ".$element ["element_name"]."\n";
1149 if (is_array ( $transitions ) || is_object ( $transitions ))
1150 foreach ($transitions as $transition) {
1151 $fromValue = (string)$transition->fromValue;
1152 if ($element ["element_name"] == $fromValue || $fromValue == 'fldv-any') {
1153 echo 'from value '.$fromValue."\n";
1154 $toValue = (string)$transition->toValue;
1155 echo 'to value '.$toValue."\n";
1156 if ($toValue == 'fldv-any') {
1157 $nodes = array_diff($allElements, array($element ["element_id"]));
1159 $toValueId = get_element_id_by_name ( $CSFElements, $toValue );
1161 echo 'Warning, unknown status in workflow : '.$toValue."\n";
1163 $nodes [] = $toValueId;
1168 if ($element ["status_id"] == 1 && empty($nodes)) {
1169 $nodes = array_diff($allElements, array($element ["element_id"]));
1171 $w->saveNextNodes ( $element ["element_id"], $nodes );
1175 $engine = RBACEngine::getInstance () ;
1176 $roleObjArr = $engine->getRolesByAllowedAction('tracker', $g->getID(), 'tech') ;
1177 $allRoles = array();
1178 foreach ($roleObjArr as $roleObj) {
1179 $allRoles [] = $roleObj->getID();
1182 if (is_array ( $transitions ) || is_object ( $transitions )) {
1183 foreach ($transitions as $transition) {
1184 $fromValue = (string)$transition->fromValue;
1185 if ($fromValue == 'fldv-any') {
1186 $fromValueIdArr = $allElements;
1188 $fromValueId = get_element_id_by_name ( $CSFElements, $fromValue );
1190 $fromValueIdArr = array($fromValueId);
1192 $fromValueIdArr = array();
1195 $toValue = (string)$transition->toValue;
1196 if ($toValue == 'fldv-any') {
1197 $toValueIdArr = $allElements;
1199 $toValueId = get_element_id_by_name ( $CSFElements, $toValue );
1201 $toValueIdArr = array($toValueId);
1203 $toValueIdArr = array();
1206 if (!empty($fromValueIdArr) && !empty($toValueIdArr)) {
1209 $transitionRoles = $transition->transitionRoles->transition_role;
1211 if (!empty($transitionRoles)) {
1212 if (is_array($transitionRoles) || is_object($transitionRoles)) {
1213 foreach ( $transitionRoles as $transitionRole ) {
1214 $roleId = get_role_id_by_name($g, (string)$transitionRole->title);
1216 echo 'Waring unknown role in workfow :'.(string)$transitionRole->title."\n";
1226 foreach ($fromValueIdArr as $fromValueId) {
1227 //$statusId = get_element_status_id_by_name($CSFElements, $fromValueId);
1228 foreach ($toValueIdArr as $toValueId) {
1229 if (!empty($transitionRoles)) {
1230 $w->saveAllowedRoles($fromValueId, $toValueId, $roles);
1232 $w->saveAllowedRoles($fromValueId, $toValueId, $allRoles);
1237 //transitionRequiredFields
1238 $transitionRequiredFields = $transition->transitionRequiredFields->transition_required_field;
1239 $requiredfields = array();
1240 if (is_array ( $transitionRequiredFields ) || is_object ( $transitionRequiredFields )) {
1241 foreach ($transitionRequiredFields as $transitionRequiredField) {
1242 $ef = get_extra_field_by_name($t, (string)$transitionRequiredField->requiredFieldName);
1244 echo 'Waring unknown extra field in workfow :'.(string)$transitionRequiredField->requiredFieldName."\n";
1246 $requiredfields[] = $ef['extra_field_id'];
1249 foreach ($fromValueIdArr as $fromValueId) {
1250 foreach ($toValueIdArr as $toValueId) {
1251 $w->saveRequiredFields($fromValueId, $toValueId, $requiredfields);
1262 function get_initial_fields_value($artifact, $auditEntries) {
1264 $fieldsValue = array();
1266 $details = (string)$artifact->description;
1268 $fieldsValue['title'] = (string)$artifact->title;
1269 $fieldsValue['priority'] = (string)$artifact->priority;
1270 $fieldsValue['description'] = (string)$artifact->description;
1272 $fieldsValue['estimatedEffort'] = (integer)$artifact->estimatedEffort;
1273 $fieldsValue['actualEffort'] = (integer)$artifact->actualEffort;
1274 $fieldsValue['remainingEffort'] = (integer)$artifact->remainingEffort;
1275 $fieldsValue['autosumming'] = (string)$artifact->autosumming;
1277 $fieldsValue['points'] = (integer)$artifact->points;
1279 $fieldsValue['group'] = (string)$artifact->group;
1280 $fieldsValue['category'] = (string)$artifact->category;
1281 $fieldsValue['status'] = (string)$artifact->status;
1282 $fieldsValue['customer'] = (string)$artifact->customer;
1283 $fieldsValue['assignedToUsername'] = (string)$artifact->assignedToUsername;
1284 $fieldsValue['plannedFor'] = (string)$artifact->plannedFor;
1285 $fieldsValue['reportedInRelease'] = (string)$artifact->reportedInRelease;
1286 $fieldsValue['resolvedInRelease'] = (string)$artifact->resolvedInRelease;
1288 $flexValues = $artifact->flexValues->flexValue;
1289 foreach ($flexValues as $flexValue) {
1290 $fieldsValue[(string)$flexValue->fieldName] = (string)$flexValue->fieldValue;
1293 $auditEntries = array_reverse($auditEntries);
1294 foreach ($auditEntries as $auditEntry) {
1295 $auditChanges = $auditEntry->auditChanges->audit_change;
1296 foreach ($auditChanges as $auditChange) {
1297 $propertyName = (string)$auditChange->propertyName;
1300 // audit >>> histo >>> artifact
1301 // releaseId >>> reportedInReleaseXid >>> reportedInRelease
1302 // resolvedReleaseId >>> fixedInReleaseXid >>>resolvedInRelease
1303 // planningFolder >>> planningFolderXid >>> plannedFor
1304 switch ($propertyName) {
1305 case 'planningFolder':
1306 $propertyName = 'plannedFor';
1309 $propertyName = 'reportedInRelease';
1311 case 'resolvedReleaseId':
1312 $propertyName = 'resolvedInRelease';
1316 // tracker or project move
1317 // folderId = tracker xid
1318 if ($propertyName == 'folderId') {
1319 $oldValue = (string)$auditChange->oldValue;
1320 $trackerId = get_traker_id_by_xid($oldValue);
1322 $fieldsValue[$propertyName] = $oldValue;
1325 $oldValue = (string)$auditChange->oldValue;
1326 $fieldsValue[$propertyName] = $oldValue;
1330 //var_dump($fieldsValue);
1331 return $fieldsValue;
1334 function inject_artifact(&$g, $tracker, $artifact, $histories, $auditing, $tracker_xid, $default_values, $project_path) {
1338 $r = $t->fetchData($t->getID());
1339 $artifact_xid = (string)$artifact['xid'];
1341 echo "Import artifact: ".$artifact_xid."\n";
1343 $auditEntries = $auditing->xpath("/auditing/audit_entry[./objectXid = '".$artifact_xid."']");
1344 usort($auditEntries, 'sort_audit_entries');
1346 $initialFieldsValue = get_initial_fields_value($artifact,$auditEntries);
1348 // if created in an other tracker (foldeId = tracker xid)
1349 if (isset($initialFieldsValue['folderId'])) {
1350 $trackerId = get_traker_id_by_xid($initialFieldsValue['folderId']);
1351 $t = new ArtifactType($g, $trackerId);
1352 $r = $t->fetchData($trackerId);
1353 if ($t->isError()) {
1354 echo 'Error traker '.$initialFieldsValue['folderId'].': '.$t->getErrorMessage()."\n";
1359 $new_artifact_type_id = $t->getID();
1360 $extraFields = $t->getExtraFields();
1361 $efStatusId = $t->getCustomStatusField();
1363 $extraFieldsName = array_map('get_column_field_name', $extraFields);
1365 $extraFieldTypesWithId = array(ARTIFACT_EXTRAFIELDTYPE_SELECT, ARTIFACT_EXTRAFIELDTYPE_CHECKBOX, ARTIFACT_EXTRAFIELDTYPE_RADIO, ARTIFACT_EXTRAFIELDTYPE_MULTISELECT, ARTIFACT_EXTRAFIELDTYPE_STATUS);
1367 $artifactOperations = array('$create');
1368 $attachmentOperations = array('$add_attachment','$delete_attachment');
1369 $specialFields = array('title','description', 'assignedTo', 'priority');
1370 $dontCareFields = array('plannedFor', 'closeDate');
1371 // projectId => move form a project to an other
1372 $notExtraFiels = array_merge($artifactOperations, $attachmentOperations, $specialFields, $dontCareFields);
1374 //non géré dans history ou audit
1375 // $details = (string)$artifact->description;
1379 $summary = $initialFieldsValue['title'];
1380 $details = $initialFieldsValue['description'];
1381 if (!isset($initialFieldsValue['assignedTo'])) {
1384 $assignedTo = $initialFieldsValue['assignedTo'];
1385 $assigned_to = get_user_id_by_name($assignedTo);
1386 if ($assigned_to == false)
1389 $priority = $initialFieldsValue['priority'];
1390 if (isset($initialFieldsValue['projectId'])) {
1391 $createdInProject = $initialFieldsValue['projectId'];
1394 $extra_fields = array();
1395 //echo 'Initials values'."\n";
1396 //var_dump($initialFieldsValue);
1397 foreach ($extraFields as $ef) {
1398 if (isset($initialFieldsValue[$ef['field_name']])) {
1399 $efvalue = $initialFieldsValue[$ef['field_name']];
1400 if (in_array($ef["field_type"],$extraFieldTypesWithId)) {
1402 $extra_fields[$ef['extra_field_id']] = 100;
1404 $efe = get_extra_field_element_by_name($t, $ef['extra_field_id'], $efvalue);
1406 echo 'Warning: extra field element '.$efvalue.' not found for extra field '.$ef['field_name']."\n";
1408 $extra_fields[$ef['extra_field_id']] = $efe['element_id'];
1412 $extra_fields[$ef['extra_field_id']] = $efvalue;
1417 $importData = array('nopermcheck' => true, 'nonotice' => true);
1420 foreach ($auditEntries as $auditEntry) {
1421 $aEOperation = (string)$auditEntry->operation;
1424 $createdBy = (string)$auditEntry->createdByUsername;
1425 $user = get_user_id_by_name($createdBy);
1426 if ($user == false) {
1427 echo 'Warning : user '.$createdBy.' not found'."\n";
1428 $user = $adminUser->getID();
1430 $datetime = (string)$auditEntry->dateCreated;
1431 $time = strtotime($datetime);
1432 $importData['user'] = $user;
1433 $importData['time'] = $time;
1437 $attachmentCounter=0;
1439 foreach ($auditEntry->auditChanges->audit_change as $auditChange) {
1440 $propertyName = (string)$auditChange->propertyName;
1441 $moveOfTraker = false;
1442 $moveOfProject = false;
1444 // audit >>> histo >>> artifact
1445 // releaseId >>> reportedInReleaseXid >>> reportedInRelease
1446 // resolvedReleaseId >>> fixedInReleaseXid >>>resolvedInRelease
1447 // planningFolder >>> planningFolderXid >>> plannedFor
1448 switch ($propertyName) {
1449 case 'planningFolder':
1450 $propertyName = 'plannedFor';
1453 $propertyName = 'reportedInRelease';
1455 case 'resolvedReleaseId':
1456 $propertyName = 'resolvedInRelease';
1459 switch ($propertyName) {
1460 case '$add_attachment':
1461 $filesXidArr = explode("\n",(string)$auditChange->newValue);
1462 $nbAttachment = count($filesXidArr);
1463 $fileXid = $filesXidArr[$attachmentCounter];
1465 case '$delete_attachment':
1466 $fileToDel = (string)$auditChange->oldValue;
1469 $summary = (string)$auditChange->newValue;
1473 $details = (string)$auditChange->newValue;
1477 $assignedTo = (string)$auditChange->newValue;
1478 if ($assignedTo == 'nobody') {
1481 $assigned_to = get_user_id_by_name($assignedTo);
1482 if ($assigned_to == false)
1488 $priority = (integer)$auditChange->newValue;
1492 $moveOfTraker = true;
1493 $moveTrackerXid = (string)$auditChange->newValue;
1494 $trackerId = get_traker_id_by_xid($moveTrackerXid);
1496 echo 'Error: tracker '.$moveTrackerXid.'not found'."\n";
1499 $new_artifact_type_id = $trackerId;
1502 $moveOfProject = true;
1503 $moveFromProject = (string)$auditChange->oldValue;
1504 $moveToProject = (string)$auditChange->newValue;
1507 if (!in_array($propertyName,$notExtraFiels)) {
1508 if (in_array($propertyName, $extraFieldsName)) {
1509 $ef = get_extra_field_by_name($t, $propertyName);
1510 $newValue = (string)$auditChange->newValue;
1511 if (in_array($ef["field_type"],$extraFieldTypesWithId)) {
1512 if ($newValue=='') {
1515 $efe = get_extra_field_element_by_name($t, $ef['extra_field_id'], $newValue);
1517 echo 'Warning: extra field element '.$newValue.' not found for extra field '.$propertyName."\n";
1519 $extra_fields[$ef['extra_field_id']] = $efe['element_id'];;
1524 $extra_fields[$ef['extra_field_id']] = $newValue;
1528 echo 'Warning, unknown propertyName: '.$propertyName."\n";
1534 switch ($aEOperation) {
1539 echo "\t".'create artifact '.$artifact_xid.' ('.$datetime.')'."\n";
1540 // if ((string)$history[0]->operation!='create') {
1541 // echo 'Error: create operation not found in artifact_history for artifact '.$artifact_xid."\n";
1544 $a = new Artifact($t);
1545 if ($a->isError()) {
1546 echo 'Error when creating artifact: '.$a->getErrorMessage()."\n";
1548 // echo 'tracker id : '.$a->ArtifactType->getID()."\n";
1549 //echo 'extra fields :'."\n";
1550 //var_dump($extra_fields);
1551 $r = $a->create($summary, $details, $assigned_to, $priority, $extra_fields, $importData);
1552 if ($a->isError() || !$r) {
1553 echo 'Error when creating artifact '.$summary.': '.$a->getErrorMessage()."\n";
1556 if (isset($createdInProject)) {
1557 $canned_response = 100;
1559 $CreatComment = 'Import information: Artifact create in project '.$createdInProject;
1560 $r = $a->update($priority, $status_id, $assigned_to, $summary, $canned_response, $CreatComment, $new_artifact_type_id, $extra_fields, $details, $importData);
1562 echo "\t".'artifact '.$artifact_xid.' created'."\n";
1567 if ($moveOfProject) {
1568 $canned_response = 100;
1570 $moveComment = 'Import information: Artifact move form project '.$moveFromProject.' to project'.$moveToProject;
1571 $r = $a->update($priority, $status_id, $assigned_to, $summary, $canned_response, $moveComment, $new_artifact_type_id, $extra_fields, $details, $importData);
1572 if ($a->isError() || !$r) {
1573 echo 'Error when updating/moving artifact '.$summary.': '.$a->getErrorMessage()."\n";
1576 echo "\t".'artifact '.$artifact_xid.' '.$aEOperation.'d'."\n";
1581 echo "\t".$aEOperation.' artifact '.$artifact_xid.' ('.$datetime.')'."\n";
1583 echo 'Error try to '.$aEOperation.' without having created the artifact '.$summary."\n";
1587 if (isset($auditEntry->comment)) {
1588 $comment = (string)$auditEntry->comment;
1595 $canned_response = 100;
1597 $r = $a->update($priority, $status_id, $assigned_to, $summary, $canned_response, $comment, $new_artifact_type_id, $extra_fields, $details, $importData);
1598 if ($a->isError() || !$r) {
1599 echo 'Error when updating/moving artifact '.$summary.': '.$a->getErrorMessage()."\n";
1602 echo "\t".'artifact '.$artifact_xid.' '.$aEOperation.'d'."\n";
1604 if ($moveOfTraker) {
1605 $extra_fields = $a->getExtraFieldData();
1606 $t = $a->getArtifactType();
1607 $r = $t->fetchData($new_artifact_type_id);
1612 echo 'Warning unknown artifact audit operation:'.$aEOperation;
1618 if (isset($auditEntry->attach)) {
1619 $filename = (string)$auditEntry->attach['fileDisplayName'];
1620 $filename = preg_replace("/[^-a-zA-Z0-9+_\. ~]/", "-", $filename);
1621 $fileLocation = $project_path.(string)$auditEntry->attach['filename'];
1622 $filetype = (string)$auditEntry->attach['mimeType'];
1623 if (is_file($fileLocation)) {
1624 $filesize = filesize($fileLocation);
1626 $file = new ArtifactFile($a);
1627 if (!$file || !is_object($file) || $file->isError()) {
1628 echo 'Error when creating ArtifactFile '.$filename.': '.$file->getErrorMessage()."\n";
1630 $r = $file->create($filename, $filetype, $filesize, $fileLocation, $description, $importData);
1631 if ($file->isError() || !$r) {
1632 echo 'Error when creating ArtifactFile '.$filename.': '.$file->getErrorMessage()."\n";
1634 $resxid = db_query_params('insert into ctf_mapping (xid, ffobject, ffid) values ($1, $2, $3)', array($fileXid, 'ArtifactFile', $file->getID()));
1635 echo "\t".'ArtifactFile: '.$filename.' injected'."\n";
1638 echo 'Error when creating ArtifactFile '.$filename.': file not found'."\n";
1640 if ($nbAttachment == ($attachmentCounter + 1)) {
1641 $attachmentCounter = 0;
1643 $attachmentCounter += 1;
1648 $attachedFiles = $a->getFiles();
1649 foreach ($attachedFiles as $attachedFile) {
1650 if ($fileToDel == $attachedFile->getName()) {
1651 $attachedFile->delete();
1657 echo 'Artifact '.$artifact_xid.' injected'."\n";
1660 function inject_field(&$t, $field, &$default_values, $project_path, $tracker_xid) {
1662 $fieldname = (string)$field->name;
1663 $displayType = (string)$field->displayType;
1664 $displaySize = (integer)$field->displaySize;
1665 $displayLines = (integer)$field->displayLines;
1666 $is_required = ((string)$field->isRequired=="true")?true:false;
1667 $is_disabled = ((string)$field->isDisabled=="true")?true:false;
1668 $is_hidden_on_submit = ((string)$field->isHiddenOnCreate=="true")?true:false;
1671 $description = (string)$field->helpText;
1672 $pattern = (string)$field->pattern;
1673 // createdByUsername
1674 // lastModifiedByUsername
1677 switch ($displayType) {
1679 switch ($fieldname) {
1681 $field_type = ARTIFACT_EXTRAFIELDTYPE_STATUS;
1683 case 'reportedInRelease':
1684 case 'resolvedInRelease':
1685 //$field_type = ARTIFACT_EXTRAFIELDTYPE_RELEASE;
1686 //$field_type = ARTIFACT_EXTRAFIELDTYPE_SELECT;
1687 $field_type = ARTIFACT_EXTRAFIELDTYPE_TEXT;
1692 $field_type = ARTIFACT_EXTRAFIELDTYPE_SELECT;
1696 // $field_type = ARTIFACT_EXTRAFIELDTYPE_CHECKBOX;
1699 // $field_type = ARTIFACT_EXTRAFIELDTYPE_RADIO;
1702 if (in_array($fieldname ,array('estimatedEffort', 'actualEffort', 'remainingEffort', 'points'))) {
1703 $field_type = ARTIFACT_EXTRAFIELDTYPE_INTEGER;
1704 $attribute1 = $displaySize;
1705 $attribute2 = $displaySize*4;
1706 } elseif ($displayLines > 1) {
1707 $field_type = ARTIFACT_EXTRAFIELDTYPE_TEXTAREA;
1708 $attribute1 = $displayLines;
1709 $attribute2 = $displaySize;
1711 $field_type = ARTIFACT_EXTRAFIELDTYPE_TEXT;
1712 $attribute1 = $displaySize;
1713 $attribute2 = $displaySize*4;
1717 $field_type = ARTIFACT_EXTRAFIELDTYPE_MULTISELECT;
1718 $attribute1 = $displayLines;
1719 $attribute2 = $displaySize;
1722 // $field_type = ARTIFACT_EXTRAFIELDTYPE_ASSIGNEE;
1725 // $field_type = ARTIFACT_EXTRAFIELDTYPE_RELATION;
1728 // $field_type = ARTIFACT_EXTRAFIELDTYPE_INTEGER;
1731 // $field_type = ARTIFACT_EXTRAFIELDTYPE_FORMULA;
1734 // $field_type = ARTIFACT_EXTRAFIELDTYPE_DATE;
1735 $field_type = ARTIFACT_EXTRAFIELDTYPE_TEXT;
1740 $field_type = ARTIFACT_EXTRAFIELDTYPE_USER;
1743 echo 'Unknow type :'.$displayType."\n";
1750 $show100label = 'none';
1754 $f = new ArtifactExtraField ($t);
1755 $r = $f->create($fieldname, $field_type, $attribute1, $attribute2, $is_required, $alias, $show100, $show100label, $description, $pattern, $parent, $autoassign, $is_hidden_on_submit, $is_disabled);
1756 if ($f->isError() || !$r) {
1757 echo 'Error when creating extra field '.$fieldname.': '.$f->getErrorMessage()."\n";
1761 $resxid = db_query_params('insert into ctf_mapping (xid, ffobject, ffid) values ($1, $2, $3)', array($tracker_xid."/".$fieldname, 'ArtifactExtraField', $f->getID()));
1762 echo 'Extra field: '.$fieldname.' injected'."\n";
1764 switch ($fieldname) {
1765 case 'estimatedEffort':
1766 case 'actualEffort':
1767 case 'remainingEffort':
1769 $default_values[$f->getID()]=0;
1773 $default_values[$f->getID()]=false;
1779 // delete default Open and Closed
1780 if ($field_type == ARTIFACT_EXTRAFIELDTYPE_STATUS) {
1781 $statusFieldValues = $f->getAvailableValues();
1782 $id = get_element_id_by_name($statusFieldValues,'Open');
1783 $element = new ArtifactExtraFieldElement($f,$id);
1785 $id = get_element_id_by_name($statusFieldValues,'Closed');
1786 $element = new ArtifactExtraFieldElement($f,$id);
1790 $fieldValues = $field->fieldValues->field_value;
1791 $fieldValueStatus = array();
1792 if (is_array($fieldValues) || is_object($fieldValues))
1793 foreach ($fieldValues as $fieldValue) {
1794 $fieldValueStatus[] = inject_fieldValue($f, $fieldValue, $default_values, $project_path, $tracker_xid);
1796 if (in_array(false, $fieldValueStatus))
1802 function inject_fieldValue(&$f, $fieldValue, &$default_values, $project_path, $tracker_xid) {
1804 $valuename = (string)$fieldValue->value;
1805 $default = (string)$fieldValue['default'];
1807 if ($f->getName () == "status") {
1808 if (( string ) $fieldValue->valueClass == "Open")
1814 $fv = new ArtifactExtraFieldElement ($f);
1815 $r = $fv->create($valuename,$status_id);
1816 if ($fv->isError() || !$r) {
1817 echo 'Error when creating extra field '.$valuename.': '.$fv->getErrorMessage()."\n";
1821 $displayOrder = (integer)$fieldValue->displayOrder;
1822 $r = $f->updateOrder($fv->getID(), $displayOrder);
1823 if ($f->isError() || !$r) {
1824 echo 'Error when update extra field value order'.$valuename.': '.$f->getErrorMessage()."\n";
1828 if ($default =='true') {
1829 $default_values[$f->getId()]=$fv->getID();
1831 $resxid = db_query_params('insert into ctf_mapping (xid, ffobject, ffid) values ($1, $2, $3)', array($tracker_xid."/".$f->getName()."/".$valuename, 'ArtifactExtraFieldElement', $fv->getID()));
1832 echo 'Extra field value: '.$valuename.' injected'."\n";
1838 function get_element_id_by_name($elements, $name) {
1840 foreach ( $elements as $element ) {
1841 if ($element ["element_name"] == $name) {
1842 $id = $element ["element_id"];
1847 echo 'Error unknow element: '.$name."\n";
1852 function get_element_status_id_by_name($elements, $name) {
1854 foreach ( $elements as $element ) {
1855 if ($element ["element_name"] == $name) {
1856 $status_id = $element ["status_id"];
1861 echo 'Error unknow element: '.$name."\n";
1866 function get_role_id_by_name($g, $name) {
1867 $roles = $g->getRoles();
1868 foreach ($roles as $role) {
1869 if ($role->getName() == $name) {
1870 return $role->getID();
1876 function get_user_id_by_name($name) {
1878 if (preg_match('/d-.*_[^_]*/', $name)) {
1879 $name = substr($name, 2);
1880 $underscore = strrpos($name, '_');
1881 $name = substr($name, 0, $underscore);
1883 if (strlen($name) > MAXSIZE__USER_UNIXNAME) {
1884 $name = substr($name, 0, MAXSIZE__USER_UNIXNAME);
1886 $userObject = user_get_object_by_name($name);
1887 if ($userObject && is_object($userObject) && !$userObject->isError()) {
1888 $id = $userObject->getID();
1893 function get_email_by_name($name) {
1895 if (preg_match('/d-.*_[^_]*/', $name)) {
1896 $name = substr($name, 2);
1897 $underscore = strrpos($name, '_');
1898 $name = substr($name, 0, $underscore);
1900 if (strlen($name) > MAXSIZE__USER_UNIXNAME) {
1901 $name = substr($name, 0, MAXSIZE__USER_UNIXNAME);
1903 $userObject = user_get_object_by_name($name);
1904 if ($userObject && is_object($userObject) && !$userObject->isError()) {
1905 $email = $userObject->getEmail();
1910 function get_extra_field_element_by_name($t, $extraFieldId, $name) {
1911 $extra_field_element=false;
1912 $r=$t->fetchData($t->getID());
1913 $elements = $t->getExtraFieldElements($extraFieldId);
1914 if (is_array($elements) || is_object($elements)) {
1915 foreach ($elements as $element) {
1916 if ($element ["element_name"] == $name) {
1917 $extra_field_element = $element;
1922 return $extra_field_element;
1925 function get_extra_field_by_name($t, $name) {
1927 $extraFields = $t->getExtraFields();
1928 if (is_array($extraFields) || is_object($extraFields)) {
1929 foreach ($extraFields as $extraField) {
1930 if ($extraField ["field_name"] == $name) {
1931 $extra_field = $extraField;
1936 return $extra_field;
1939 function get_traker_id_by_xid($xid) {
1941 $result = db_query_params('select ffid from ctf_mapping WHERE xid=$1',
1943 if ($result && db_numrows($result) > 0) {
1944 $id = db_result($result, 0, 'ffid');
1946 // echo "id tracker ".$xid.": ".$id."\n";
1949 function sort_audit_entries($ae1, $ae2) {
1950 return strcmp($ae1->dateCreated, $ae2->dateCreated);
1953 function sort_artifact_history($ah1, $ah2) {
1954 return strcmp($ah1->dateModified, $ah2->dateModified);
1957 function get_column_element_id ($array) {
1958 return $array['element_id'];
1961 function get_column_field_name ($array) {
1962 return $array['field_name'];
1965 function computeXmlfrsApplication(&$g, $project_path) {
1967 if (is_file($project_path.'/project/applications/frsApplication/frsApplication.xml')) {
1968 $simpleXmlLoadedFile = simplexml_load_file($project_path.'/project/applications/frsApplication/frsApplication.xml');
1969 if ($simpleXmlLoadedFile !== false) {
1970 $frsPackages = $simpleXmlLoadedFile->frs_package;
1971 $frsPackageStatus = array();
1972 foreach ($frsPackages as $frsPackage) {
1973 $frsPackageStatus[] = inject_package($g, $frsPackage, $project_path);
1975 if (!in_array(false, $frsPackageStatus))
1982 function inject_package(&$g, $frsPackage, $project_path) {
1985 if ((string)$frsPackage->isDeleted == "true")
1987 $packagename = trim((string)$frsPackage->title);
1988 $packagename = preg_replace("/[^-a-zA-Z0-9+_\. ~]/", "-", $packagename);
1989 if (strlen($packagename) < MINSIZE__FRS_PACKAGE_NAME) {
1990 echo 'Information: package name too short. Extended to >'.MINSIZE__FRS_PACKAGE_NAME."\n";
1991 $packagename .= '-migrated';
1992 echo 'New package name: '.$packagename."\n";
1994 $package_xid = (string)$frsPackage['xid'];
1995 $package = new FRSPackage ($g);
1996 $r = $package->create($packagename);
1997 if ($package->isError() || !$r) {
1998 echo 'Error when creating FRS package '.$packagename.': '.$package->getErrorMessage()."\n";
1999 $package->clearError();
2002 $resxid = db_query_params('insert into ctf_mapping (xid, ffobject, ffid) values ($1, $2, $3)', array($package_xid, 'FRSPackage', $package->getID()));
2003 echo 'FRS package: '.$packagename.' injected'."\n";
2006 $frsReleases = $frsPackage->frsReleases->frs_release;
2007 $frsReleaseStatus = array();
2008 foreach ($frsReleases as $frsRelease) {
2009 $frsReleaseStatus[] = inject_release($package, $frsRelease, $project_path);
2011 if (in_array(false, $frsReleaseStatus))
2017 function inject_release(&$package, $frsRelease, $project_path) {
2020 if ((string)$frsRelease->isDeleted == "true")
2022 $releasename = trim((string)$frsRelease->title);
2023 $releasename = preg_replace("/[^-a-zA-Z0-9+_\. ~]/", "-", $releasename);
2024 $notes = trim((string)$frsRelease->description);
2026 $preformatted = (substr_count($notes, "\n"));
2027 $release_date = (string)$frsRelease->dateCreated;
2028 $release_xid = (string)$frsRelease['xid'];
2029 $release = new FRSRelease($package);
2030 $r = $release->create($releasename, $notes, $changes, $preformatted ,($release_date)?strtotime($release_date):false);
2031 if ($release->isError() || !$r) {
2032 echo 'Error when creating FRS release '.$releasename.': '.$release->getErrorMessage()."\n";
2033 $release->clearError();
2036 $resxid = db_query_params('insert into ctf_mapping (xid, ffobject, ffid) values ($1, $2, $3)', array($release_xid, 'FRSRelease', $release->getID()));
2037 echo 'FRS release '.$releasename.' injected'."\n";
2040 if (strtolower(trim((string)$frsRelease->status)) != "active") {
2041 // not active = hidden = 3
2042 $release->update(3, $releasename, $notes, $changes, $preformatted ,($release_date)?strtotime($release_date):false);
2044 $frsFiles = $frsRelease->frsFiles->frs_file;
2045 $frsFileStatus = array();
2046 foreach ($frsFiles as $frsFile) {
2047 $frsFileStatus[] = inject_file($release, $frsFile, $project_path);
2049 if (in_array(false, $frsFileStatus))
2055 function inject_file(&$release, $frsFile, $project_path) {
2058 if ((string)$frsFile->isDeleted == "true")
2060 $filename = (string)$frsFile->attach['fileDisplayName'];
2061 $filename = preg_replace("/[^-a-zA-Z0-9+_\. ~]/", "-", $filename);
2062 $file_location = $project_path.'/'.(string)$frsFile->attach['filename'];
2064 $processor_id = 100;
2065 $release_time = (string)$frsFile->dateCreated;
2066 $file_xid = (string)$frsFile['xid'];
2067 $file = new FRSFile($release);
2068 $r = $file->create($filename, $file_location, $type_id, $processor_id, ($release_time)?strtotime($release_time):false);
2069 if ($file->isError() || !$r) {
2070 echo 'Error when creating FRS file '.$filename.': '.$file->getErrorMessage()."\n";
2071 $file->clearError();
2074 $resxid = db_query_params('insert into ctf_mapping (xid, ffobject, ffid) values ($1, $2, $3)', array($file_xid, 'FRSFile', $file->getID()));
2075 echo 'FRS file '.$filename.' injected'."\n";
2080 function computeXmldiscussionApplication(&$g, $project_path) {
2082 if (is_file($project_path.'/project/applications/discussionApplication/discussionApplication.xml')) {
2083 $simpleXmlLoadedFile = simplexml_load_file($project_path.'/project/applications/discussionApplication/discussionApplication.xml');
2084 if ($simpleXmlLoadedFile !== false) {
2085 $discussionFora = $simpleXmlLoadedFile->discussion_forum;
2086 $discussionForumStatus = array();
2087 foreach ($discussionFora as $discussionForum) {
2088 $discussionForumStatus[] = inject_forum($g, $discussionForum, $project_path);
2090 if (!in_array(false, $discussionForumStatus))
2097 function inject_forum(&$g, $discussionForum, $project_path) {
2099 if (strtolower(trim((string)$discussionForum->isDeleted)) == "true")
2101 $forumname = trim((string)$discussionForum->title);
2102 if (!preg_match('/^([_\.0-9a-z-])*$/i',$forumname)) {
2103 echo 'Warning: '.$forumname.' is invalid'."\n";
2104 $forumname = preg_replace('/ /', '_', $forumname);
2105 echo 'Warning: forum name renamed into '.$forumname."\n";
2107 $description = trim((string)$discussionForum->description);
2108 $forum_xid = (string)$discussionForum['xid'];
2109 $forum = new Forum($g);
2110 // $send_all_posts_to = '', $create_default_message = 1
2111 $r=$forum->create($forumname, $description);
2112 if ($forum->isError() || !$r) {
2113 echo 'Error when creating discussion forum '.$forumname.': '.$forum->getErrorMessage()."\n";
2114 $forum->clearError();
2117 $resxid = db_query_params('insert into ctf_mapping (xid, ffobject, ffid) values ($1, $2, $3)', array($forum_xid, 'Forum', $forum->getID()));
2118 echo 'Discussion forum '.$forumname.' injected'."\n";
2123 function computeXmllinkedAppApplication(&$g, $project_path) {
2125 if (is_file($project_path.'/project/applications/linkedAppApplication/linkedAppApplication.xml')) {
2126 $simpleXmlLoadedFile = simplexml_load_file($project_path.'/project/applications/linkedAppApplication/linkedAppApplication.xml');
2127 if ($simpleXmlLoadedFile !== false) {
2128 $linkedApps = $simpleXmlLoadedFile->linked_app;
2129 $linkedAppStatus = array();
2130 foreach ($linkedApps as $linkedApp) {
2131 $linkedAppStatus[] = inject_linkedapp($g, $linkedApp, $project_path);
2133 if (!in_array(false, $linkedAppStatus))
2140 function inject_linkedapp(&$g, $linkedApp, $project_path) {
2141 if (strtolower(trim((string)$linkedApp->isDeleted)) == "true") {
2144 $linkedAppTitle = trim((string)$linkedApp->title);
2145 $linkedAppUrl = trim((string)$linkedApp->applicationUrl);
2146 $linkedAppOrder = (int)$linkedApp->displayOrder;
2147 $headermenuPlugin = plugin_get_object('headermenu');
2148 if ($headermenuPlugin->addLink($linkedAppUrl, $linkedAppTitle, '', 'groupmenu', 'url', $g->getID(), '', $linkedAppOrder)) {
2154 function util_session_set_new($user) {
2155 if (strlen($user) > MAXSIZE__USER_UNIXNAME)
2156 $user = substr($user, 0, MAXSIZE__USER_UNIXNAME);
2157 // check if this user exists. if yes, then start a new session with. Used by create document function
2158 // we use the last update value, not the value from the version itself.
2159 $userObject = user_get_object_by_name($user);
2160 if ($userObject && is_object($userObject) && !$userObject->isError())
2161 session_set_new($userObject->getID());
2164 function get_ff_id($object_string, $xid) {
2165 $res = db_query_params('select ffid from ctf_mapping where xid = $1 and ffobject = $2', array($xid, $object_string));
2166 if ($res && db_numrows($res) == 1) {
2167 return db_result($res, 0, 'ffid');
2173 function set_permission_in_role(&$permissionPerSectionArray, $ctfpermissionSettingRessource, $ffobject, $section, $value) {
2174 $ffid = get_ff_id($ffobject, $ctfpermissionSettingRessource);
2176 $permissionPerSectionArray[$section][$ffid] = $value;
2178 echo 'Unable to find '.$ctfpermissionSettingRessource.' ressource in database. Not injected? Skipping permission setting.'."\n";