GitHub Access Token became invalid

It seems like the GitHub access token used for retrieving details about this repository from GitHub became invalid. This might prevent certain types of inspections from being run (in particular, everything related to pull requests).
Please ask an admin of your repository to re-new the access token on this website.

ArtifactType   F
last analyzed

Complexity

Total Complexity 290

Size/Duplication

Total Lines 1897
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 15
Metric Value
wmc 290
lcom 1
cbo 15
dl 0
loc 1897
rs 0.6314

76 Methods

Rating   Name   Duplication   Size   Complexity  
A getGroup() 0 3 1
A getID() 0 3 1
A getGroupID() 0 3 1
A getOpenCount() 0 4 2
A getTotalCount() 0 4 2
A isInstantiatedForNewProjects() 0 3 1
A allowsCopy() 0 3 1
A getSubmitInstructions() 0 3 1
A getBrowseInstructions() 0 3 1
A getName() 0 3 1
A getItemName() 0 3 1
A getCapsItemName() 0 3 1
A getDescription() 0 3 1
A isValid() 0 3 1
A getStopNotification() 0 3 1
A preDelete() 0 18 4
A getFieldPermissions() 0 14 4
A getWatchers() 0 4 1
A buildFieldName() 0 3 1
A cutExportQuery() 0 13 4
A deleteCC() 0 19 4
A getAttachedFiles() 0 4 1
A deleteDependencies() 0 14 4
A getReferenceDao() 0 3 1
A getCrossReferenceDao() 0 3 1
A getArtifactGroupListDao() 0 3 1
C ArtifactType() 0 47 11
B createUserPerms() 0 29 4
A getNotificationRoles() 0 6 1
A getNotificationEvents() 0 6 1
A fetchData() 0 15 3
A allowsAnon() 0 11 3
A getCannedResponses() 0 10 2
A setStopNotification() 0 9 1
B addUser() 0 21 5
A existUser() 0 15 3
A updateUser() 0 21 4
A deleteUser() 0 21 4
B delay() 0 22 4
A restore() 0 17 3
B updateUsers() 0 32 6
C userCanView() 0 32 8
C userHasFullAccess() 0 28 7
A userIsAdmin() 0 14 3
C userCanSubmit() 0 30 7
A getCurrentUserPerm() 0 15 3
A getUserPerm() 0 8 1
C update() 0 71 17
A updateNotificationSettings() 0 6 1
A deleteWatchees() 0 6 1
A getWatchees() 0 5 1
C setWatchees() 0 39 8
A deleteNotification() 0 5 1
A setNotification() 0 14 3
A getSubmitters() 0 14 2
A getUsersPerm() 0 8 1
A copyNotificationEvent() 0 15 3
A copyNotificationRole() 0 15 3
B getOpenArtifactsByAge() 0 31 3
B getArtifactsByAge() 0 29 3
B getArtifactsBy() 0 24 6
B getOpenArtifactsBy() 0 25 6
B getArtifactsByField() 0 26 6
B getOpenArtifactsByField() 0 27 6
D checkNotification() 0 139 41
A buildNotificationMatrix() 0 10 2
A getNotificationWithLabels() 0 21 1
A getNextFieldID() 0 10 3
D getExportQueryElements() 0 97 13
C buildExportQuery() 0 43 7
A buildDefaultRecord() 0 12 2
A getCC() 0 5 1
C deleteAttachedFiles() 0 27 8
A getDependencies() 0 10 1
A copyArtifacts() 0 7 3
C copyArtifact() 0 52 10

How to fix   Complexity   

Complex Class

Complex classes like ArtifactType often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use ArtifactType, and based on these observations, apply Extract Interface, too.

1
<?php
2
/**
3
 * Copyright (c) Xerox Corporation, Codendi Team, 2001-2009. All rights reserved
4
 *
5
 * This file is a part of Codendi.
6
 *
7
 * Codendi is free software; you can redistribute it and/or modify
8
 * it under the terms of the GNU General Public License as published by
9
 * the Free Software Foundation; either version 2 of the License, or
10
 * (at your option) any later version.
11
 *
12
 * Codendi is distributed in the hope that it will be useful,
13
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15
 * GNU General Public License for more details.
16
 *
17
 * You should have received a copy of the GNU General Public License
18
 * along with Codendi. If not, see <http://www.gnu.org/licenses/>.
19
 */
20
require_once('common/include/Error.class.php');
21
require_once('www/project/admin/permissions.php');
22
require_once('common/tracker/ArtifactFieldSetFactory.class.php');
23
require_once('common/dao/ReferenceDao.class.php');
24
require_once('common/dao/CrossReferenceDao.class.php');
25
require_once('common/dao/ArtifactGroupListDao.class.php');
26
27
28
class ArtifactType extends Error {
29
30
	/**
31
	 * The Group object.
32
	 *
33
	 * @var		object	$Group.
34
	 */
35
	var $Group; 
36
37
	/**
38
	 * Current user permissions.
39
	 *
40
	 * @var		int		$current_user_perm.
41
	 */
42
	var $current_user_perm;
43
44
45
	/**
46
	 * Canned responses resource ID.
47
	 *
48
	 * @var		int		$cannecresponses_res.
49
	 */
50
	var $cannedresponses_res;
51
52
	/**
53
	 * Array of artifact data.
54
	 *
55
	 * @var		array	$data_array.
56
	 */
57
	var $data_array;
58
59
	/**
60
	 * number of notification events
61
	 *
62
	 * @var		array	
63
	 */
64
	var $num_events = 0;
65
66
	/**
67
	 * Array of events
68
	 *
69
	 * @var		array	
70
	 */
71
	var $arr_events = array();
72
73
	/**
74
	 * number of roles
75
	 *
76
	 * @var		array	
77
	 */
78
	var $num_roles = 0;
79
80
	/**
81
	 * Array of roles
82
	 *
83
	 * @var		array	
84
	 */
85
	var $arr_roles = array();
86
87
	/**
88
	 * Technicians db resource ID.
89
	 *
90
	 * @var		int		$admins_res.
91
	 */
92
   	var $admins_res;
93
94
	/**
95
	 *	ArtifactType - constructor.
96
	 *
97
	 *	@param	object	The Group object.
98
	 *	@param	int		The id # assigned to this artifact type in the db.
99
	 *  @param	array	The associative array of data.
100
	 *	@return boolean	success.
101
	 */
102
	function ArtifactType(&$Group,$artifact_type_id=false, $arr=false) {
103
	  global $Language;
104
105
		$this->Error();
106
		if (!$Group || !is_object($Group)) {
107
			$this->setError($Language->getText('tracker_common_type','invalid'));
108
			return false;
109
		}
110
		if ($Group->isError()) {
111
			$this->setError('ArtifactType: '.$Group->getErrorMessage());
112
			return false;
113
		}
114
		
115
		$this->Group =& $Group;
116
		if ($artifact_type_id) {
117
			$res_events = $this->getNotificationEvents($artifact_type_id);
118
			$this->num_events = db_numrows($res_events);
119
			$i=0;
120
			while ($arr_events = db_fetch_array($res_events)) {
121
    				$this->arr_events[$i] = $arr_events; $i++;
122
			}
123
124
			$res_roles = $this->getNotificationRoles($artifact_type_id);
125
			$this->num_roles = db_numrows($res_roles);
126
			$i=0;
127
			while ($arr_roles = db_fetch_array($res_roles)) {
128
    				$this->arr_roles[$i] = $arr_roles; $i++;
129
			}
130
131
			if (!$arr || !is_array($arr)) {
132
				if (!$this->fetchData($artifact_type_id)) {
133
					return false;
134
				}
135
			} else {
136
				$this->data_array = $arr;
137
				if ($this->data_array['group_id'] != $this->Group->getID()) {
138
					$this->setError($Language->getText('tracker_common_type','no_match'));
139
					$this->data_array = null;
140
					return false;
141
				}
142
			}
143
		}
144
145
		unset($this->admins_res);
146
		unset($this->current_user_perm);
147
		unset($this->cannedresponses_res);
148
	}
149
150
	/**
151
	 *	Create user permissions: Tech Only for group members and Tech & Admin for group admin
152
	 *
153
	 *	@param	atid: the artfact type id 
154
	 *
155
	 *	@return boolean
156
	 */
157
	function createUserPerms($atid) {
158
	  global $Language;
159
160
		$sql = "SELECT "
161
			. "user.user_id AS user_id, "
162
			. "user_group.admin_flags "
163
			. "FROM user,user_group WHERE "
164
			. "user.user_id=user_group.user_id AND user_group.group_id=". db_ei($this->Group->getID()) ;
165
		$res = db_query($sql);
166
		
167
		while ($row = db_fetch_array($res)) {
168
			if ( $row['admin_flags'] == "A" ) {
169
				// Admin user
170
				$perm = 3;
171
					
172
			} else {
173
				// Standard user
174
				$perm = 0;
175
			}
176
177
			if ( !$this->addUser($row['user_id'],$perm) ) {
178
				$this->setError($Language->getText('tracker_common_type','perm_fail',$this->getErrorMessage()));
179
				return false;
180
			}
181
		}
182
		
183
		return true;
184
185
	}
186
187
	
188
	
189
190
	/**
191
	 *  fetch the notification roles for this ArtifactType from the database.
192
	 *
193
	 *  @param	int		The artifact type ID.
194
	 *  @return query result.
195
	 */
196
	function getNotificationRoles($artifact_type_id) {
197
	    $sql = 'SELECT * FROM artifact_notification_role WHERE group_artifact_id='. db_ei($artifact_type_id) .' ORDER BY rank ASC;';
198
	    //$sql = 'SELECT * FROM artifact_notification_role_default ORDER BY rank ASC;';
199
	    //echo $sql.'<br>';
200
	    return db_query($sql);
201
	}
202
203
	/**
204
	 *  fetch the notification events for this ArtifactType from the database.
205
	 *
206
	 *  @param	int		The artifact type ID.
207
	 *  @return query result.
208
	 */
209
	function getNotificationEvents($artifact_type_id) {
210
	    $sql = 'SELECT * FROM artifact_notification_event WHERE group_artifact_id='. db_ei($artifact_type_id) .' ORDER BY rank ASC;';
211
	    //$sql = 'SELECT * FROM artifact_notification_event_default ORDER BY rank ASC;';
212
	    //echo $sql.'<br>';
213
		return db_query($sql);
214
	}
215
216
	/**
217
	 *  fetchData - re-fetch the data for this ArtifactType from the database.
218
	 *
219
	 *  @param	int		The artifact type ID.
220
	 *  @return boolean	success.
221
	 */
222
	function fetchData($artifact_type_id) {
223
	  global $Language;
224
225
		$sql = "SELECT * FROM artifact_group_list
226
			WHERE group_artifact_id='". db_ei($artifact_type_id) ."' 
227
			AND group_id='".  db_ei($this->Group->getID())  ."'";
228
		$res=db_query($sql);
229
		if (!$res || db_numrows($res) < 1) {
230
			$this->setError('ArtifactType: '.$Language->getText('tracker_common_type','invalid_at'));
231
			return false;
232
		}
233
		$this->data_array = db_fetch_array($res);
234
		db_free_result($res);
235
		return true;
236
	}
237
238
	/**
239
	 *	  getGroup - get the Group object this ArtifactType is associated with.
240
	 *
241
	 *	  @return	Object	The Group object.
242
	 */
243
	function &getGroup() {
244
		return $this->Group;
245
	}
246
247
	/**
248
	 *	  getID - get this ArtifactTypeID.
249
	 *
250
	 *	  @return	int	The group_artifact_id #.
251
	 */
252
	function getID() {
253
		return $this->data_array['group_artifact_id'];
254
	}
255
256
	/**
257
	 *	  getID - get this Artifact Group ID.
258
	 *
259
	 *	  @return	int	The group_id #.
260
	 */
261
	function getGroupID() {
262
		return $this->data_array['group_id'];
263
	}
264
265
	/**
266
	 *	  getOpenCount - get the count of open tracker items in this tracker type.
267
	 *
268
	 *	  @return	int	The count.
269
	 */
270
	function getOpenCount() {
271
            $count=$this->data_array['open_count'];
272
            return ($count?$count:0);
273
	}
274
275
	/**
276
	 *	  getTotalCount - get the total number of tracker items in this tracker type.
277
	 *
278
	 *	  @return	int	The total count.
279
	 */
280
	function getTotalCount() {
281
            $count=$this->data_array['count'];
282
            return ($count?$count:0);
283
	}
284
285
	/**
286
	 *	  isInstantiatedForNewProjects
287
	 *
288
	 *	  @return	boolean - true if the tracker is instantiated for new projects (tracker templates).
289
	 */
290
	function isInstantiatedForNewProjects() {
291
		return $this->data_array['instantiate_for_new_projects'];
292
	}
293
294
	/**
295
	 *	  allowsAnon - determine if non-logged-in users can post.
296
	 *
297
	 *	  @return	boolean allow_anonymous_submissions.
298
	 */
299
	function allowsAnon() {
300
            if (! isset($this->data_array['allow_anon'])) {
301
                // First, check that anonymous users can access the tracker
302
                if ($this->userCanView(100)) {
303
                    // Then check if they can submit a field
304
                    $this->data_array['allow_anon']=$this->userCanSubmit(100);
305
                } else $this->data_array['allow_anon']=false;
306
307
            }
308
            return $this->data_array['allow_anon'];
309
	}
310
311
	/**
312
	 *	  allowsCopy - determine if artifacts can be copied using a copy button
313
	 *
314
	 *	  @return	boolean	allow_copy.
315
	 */
316
	function allowsCopy() {
317
		return $this->data_array['allow_copy'];
318
	}
319
320
	/**
321
	 *	  getSubmitInstructions - get the free-form string strings.
322
	 *
323
	 *	  @return	string	instructions.
324
	 */
325
	function getSubmitInstructions() {
326
		return $this->data_array['submit_instructions'];
327
	}
328
329
	/**
330
	 *	  getBrowseInstructions - get the free-form string strings.
331
	 *
332
	 *	  @return string instructions.
333
	 */
334
	function getBrowseInstructions() {
335
		return $this->data_array['browse_instructions'];
336
	}
337
338
	/**
339
	 *	  getName - the name of this ArtifactType.
340
	 *
341
	 *	  @return	string	name.
342
	 */
343
	function getName() {
344
		return $this->data_array['name'];
345
	}
346
347
	/**
348
	 *	  getItemName - the item name of this ArtifactType.
349
	 *
350
	 *	  @return	string	name.
351
	 */
352
	function getItemName() {
353
		return $this->data_array['item_name'];
354
	}
355
356
	/**
357
	 *	  getCapsItemName - the item name of this ArtifactType with the first letter in caps.
358
	 *
359
	 *	  @return	string	name.
360
	 */
361
	function getCapsItemName() {
362
		return strtoupper(substr($this->data_array['item_name'],0,1)).substr($this->data_array['item_name'],1);
363
	}
364
365
	/**
366
	 *	  getDescription - the description of this ArtifactType.
367
	 *
368
	 *	  @return	string	description.
369
	 */
370
	function getDescription() {
371
		return $this->data_array['description'];
372
	}
373
374
	/**
375
	 *	  this tracker is not deleted
376
	 *
377
	 *	  @return boolean.
0 ignored issues
show
Documentation introduced by
The doc-type boolean. could not be parsed: Unknown type name "boolean." at position 0. (view supported doc-types)

This check marks PHPDoc comments that could not be parsed by our parser. To see which comment annotations we can parse, please refer to our documentation on supported doc-types.

Loading history...
378
	 */
379
	function isValid() {
380
		return ($this->data_array['status'] == 'A');
381
	}
382
383
384
385
	/**
386
	 *	getCannedResponses - returns a result set of canned responses.
387
	 *
388
	 *	@return database result set.
389
	 */
390
	function getCannedResponses() {
391
		if (!isset($this->cannedresponses_res)) {
392
			$sql="SELECT artifact_canned_id,title,body
393
				FROM artifact_canned_responses 
394
				WHERE group_artifact_id='".  db_ei($this->getID())  ."'";
395
			//echo $sql;
396
			$this->cannedresponses_res = db_query($sql);
397
		}
398
		return $this->cannedresponses_res;
399
	}
400
401
	/**
402
	 * getStopNotification - get notification status in this tracker (1 for stopped or 0 for active)
403
	 * 
404
	 * @return boolean: true if notification stopped, false if notification is active
0 ignored issues
show
Documentation introduced by
The doc-type boolean: could not be parsed: Unknown type name "boolean:" at position 0. (view supported doc-types)

This check marks PHPDoc comments that could not be parsed by our parser. To see which comment annotations we can parse, please refer to our documentation on supported doc-types.

Loading history...
405
	 */
406
	function getStopNotification() {
407
		return $this->data_array['stop_notification'];
408
	}
409
	
410
	/**
411
	 *  setStopNotification - set notification status in this tracker (1 for stopped or 0 for active) 
412
	 */
413
	function setStopNotification($stop_notification) {
414
    
415
		$sql = 'UPDATE artifact_group_list'
416
            .' SET stop_notification = '.  db_ei($stop_notification) 
417
            .' WHERE group_artifact_id = '.  db_ei($this->getID()) 
418
            .' AND group_id = '.  db_ei($this->Group->getID()) ;
419
		return db_query($sql);
420
		
421
	}
422
	
423
	/**
424
	 *	addUser - add a user to this ArtifactType - depends on UNIQUE INDEX preventing duplicates.
425
	 *
426
	 *	@param	int		user_id of the new user.
427
	 *  @param  value: the value permission
428
	 *
429
	 *	@return boolean	success.
430
	 */
431
	function addUser($id,$value) {
432
	  global $Language;
433
434
		if (!$this->userIsAdmin()) {
435
			$this->setError($Language->getText('tracker_common_canned','perm_denied'));
436
			return false;
437
		}
438
		if (!$id) {
439
			$this->setError($Language->getText('tracker_common_canned','missing_param'));
440
			return false;
441
		}
442
		$sql="INSERT INTO artifact_perm (group_artifact_id,user_id,perm_level) 
443
			VALUES ('". db_ei($this->getID()) ."','". db_ei($id) ."',". db_ei($value) .")";
444
		$result=db_query($sql);
445
		if ($result && db_affected_rows($result) > 0) {
446
			return true;
447
		} else {
448
			$this->setError(db_error());
449
			return false;
450
		}
451
	}
452
453
	/**
454
	 *	existUser - check if a user is already in the project permissions
455
	 *
456
	 *	@param	int		user_id of the new user.
457
	 *	@return boolean	success.
458
	 */
459
	function existUser($id) {
460
	 global $Language;
461
 
462
		if (!$id) {
463
			$this->setError($Language->getText('tracker_common_canned','missing_param'));
464
			return false;
465
		}
466
		$sql="SELECT * FROM artifact_perm WHERE user_id=". db_ei($id) ." AND group_artifact_id=". db_ei($this->getID()) ;
467
		$result=db_query($sql);
468
		if (db_numrows($result) > 0) {
469
			return true;
470
		} else {
471
			return false;
472
		}
473
	}
474
475
	/**
476
	 *	updateUser - update a user's permissions.
477
	 *
478
	 *	@param	int		user_id of the user to update.
479
	 *	@param	int		(1) tech only, (2) admin & tech (3) admin only.
480
	 *	@return boolean	success.
481
	 */
482
	function updateUser($id,$perm_level) {
483
	  global $Language;
484
485
		if (!$this->userIsAdmin()) {
486
			$this->setError($Language->getText('tracker_common_canned','perm_denied'));
487
			return false;
488
		}
489
		if (!$id) {
490
			$this->setError($Language->getText('tracker_common_canned','missing_param').': '.$id.'|'.$perm_level);
491
			return false;
492
		}
493
		$sql="UPDATE artifact_perm SET perm_level='". db_ei($perm_level) ."'
494
			WHERE user_id='". db_ei($id) ."' AND group_artifact_id='". db_ei($this->getID()) ."'";
495
		$result=db_query($sql);
496
		if ($result) {
497
			return true;
498
		} else {
499
			$this->setError(db_error());
500
			return false;
501
		}
502
	}
503
504
	/**
505
	 *	deleteUser - delete a user's permissions.
506
	 *
507
	 *	@param	int		user_id of the user who's permissions to delete.
508
	 *	@return boolean	success.
509
	 */
510
	function deleteUser($id) {
511
	  global $Language;
512
513
		if (!$id) {
514
			$this->setError($Language->getText('tracker_common_canned','missing_param'));
515
			return false;
516
		}
517
		if (!$this->userIsAdmin($id)) {
518
			//$this->setError($Language->getText('tracker_common_canned','perm_denied'));
519
			return true;
520
		}
521
		$sql="DELETE FROM artifact_perm
522
			WHERE user_id='". db_ei($id) ."' AND group_artifact_id='". db_ei($this->getID()) ."'";
523
		$result=db_query($sql);
524
		if ($result) {
525
			return true;
526
		} else {
527
			$this->setError(db_error());
528
			return false;
529
		}
530
	}
531
532
	/**
533
	 *	preDelete - Mark this for deletion.
534
	 *
535
	 * @param Boolean $bypassPerms Set to true to bypass testing if user is tracker admin
536
	 *
537
	 *	@return boolean	success.
538
	 */
539
	function preDelete($bypassPerms = false) {
540
	  global $Language;
541
542
		if (!$bypassPerms && !$this->userIsAdmin()) {
543
			$this->setError($Language->getText('tracker_common_canned','perm_denied'));
544
			return false;
545
		}
546
		$date = (time() + 1000000); // 12 days of delay
547
		$sql="update artifact_group_list SET status='D', deletion_date='". db_ei($date) ."'
548
			WHERE group_artifact_id='". db_ei($this->getID()) ."'";
549
		$result=db_query($sql);
550
		if ($result) {
551
			return true;
552
		} else {
553
			$this->setError(db_error());
554
			return false;
555
		}
556
	}
557
558
	/**
559
	 *	delay - change date for deletion.
560
	 *
561
	 *	@return boolean	success.
562
	 */
563
	function delay($date) {
564
		global $Language;
565
		if (!$this->userIsAdmin()) {
566
			$this->setError($Language->getText('tracker_common_canned','perm_denied'));
567
			return false;		
568
		}
569
		$keywords = preg_split("/-/", $date);
570
		$ts = mktime("23", "59", "59", $keywords[1], $keywords[2], $keywords[0]);
571
		if (time() > $ts) {
572
		 	$this->setError($Language->getText('tracker_common_type','invalid_date'));
573
			return false;
574
		}
575
		$sql="update artifact_group_list SET deletion_date='". db_ei($ts) ."'
576
			WHERE group_artifact_id='". db_ei($this->getID()) ."'";
577
		$result=db_query($sql);
578
		if ($result) {
579
			return true;
580
		} else {
581
			$this->setError(db_error());
582
			return false;
583
		}
584
	}
585
586
	/**
587
	 *	restore - Unmark this for deletion.
588
	 *
589
	 *	@return boolean	success.
590
	 */
591
	function restore() {
592
	  global $Language;
593
594
		if (!$this->userIsAdmin()) {
595
			$this->setError($Language->getText('tracker_common_canned','perm_denied'));
596
			return false;
597
		}
598
		$sql="update artifact_group_list SET status='A'
599
			WHERE group_artifact_id='". db_ei($this->getID()) ."'";
600
		$result=db_query($sql);
601
		if ($result) {
602
			return true;
603
		} else {
604
			$this->setError(db_error());
605
			return false;
606
		}
607
	}
608
609
	/**
610
	 *	updateUsers - update the user's permissions.
611
	 *
612
	 *  @param atid: the group artifact id
613
	 *	@param array: the array which contains the user permissions.
614
	 *	@return boolean	success.
615
	 */
616
	function updateUsers($atid,$user_name) {
617
	  global $Language;
618
619
	    $result=$this->getUsersPerm($this->getID());
620
	    $rows=db_numrows($result);
621
	
622
	    if ( ($rows > 0)&&(is_array($user_name)) ) {
623
624
			$update_error = "";
625
				
626
			for ($i=0; $i < $rows; $i++) {
627
				$user_id = db_result($result, $i, 'user_id');
628
				$sql = "update artifact_perm set perm_level = ". db_ei($user_name[$i]) ." where ";
629
				$sql .= "group_artifact_id = ". db_ei($atid) ." and user_id = ". db_ei($user_id) ;
630
				//echo $sql."<br>";
631
				$result2=db_query($sql);
632
				if (!$result2) {
633
					$update_error .= " ".$Language->getText('tracker_common_type','perm_err',array($user_id,db_error()));
634
				}
635
				
636
			}
637
			
638
			if ($update_error) {
639
				$this->setError($update_error);
640
				return false;
641
			} else {
642
				return true;
643
			}
644
		}
645
		
646
		return false;
647
	}
648
649
	/*
650
651
		USER PERMISSION FUNCTIONS
652
653
	*/
654
655
	/**
656
	 *	  userCanView - determine if the user can view this artifact type.
657
         *        Note that if there is no group explicitely auhtorized, access is denied (don't check default values)
658
	 *
659
	 *	  @param $my_user_id	if not specified, use the current user id..
660
	 *	  @return boolean	user_can_view.
661
	 */
662
	function userCanView($my_user_id=0) {
663
            if (!$my_user_id) {
664
                // Super-user has all rights...
665
                if (user_is_super_user()) return true;
666
                $my_user_id=user_getid();
667
            } else {
668
                $u = UserManager::instance()->getUserById($my_user_id);
669
                if ($u->isSuperUser()) return true;
670
            }
671
            
672
            if ($this->userIsAdmin($my_user_id)) {
673
                return true;
674
            } else {
675
            
676
                $sql="SELECT ugroup_id 
677
                      FROM permissions 
678
                      WHERE permission_type LIKE 'TRACKER_ACCESS%'
679
                        AND object_id='". db_ei($this->getID()) ."' 
680
                      ORDER BY ugroup_id";
681
                $res=db_query($sql);
682
683
                if (db_numrows($res) > 0) {
684
                    while ($row = db_fetch_array($res)) {
685
                        // should work even for anonymous users
686
                        if (ugroup_user_is_member($my_user_id, $row['ugroup_id'], $this->Group->getID(), $this->getID())) {
687
                            return true;
688
                        }
689
                    }
690
                }
691
            }
692
            return false;
693
        }
694
695
696
	/**
697
	 *	  userHasFullAccess - A bit more restrictive than userCanView: determine if the user has
698
         *        the 'TRACKER_ACCESS_FULL' permission on the tracker.
699
	 *
700
	 *	  @param $my_user_id	if not specified, use the current user id..
701
	 *	  @return boolean
702
	 */
703
	function userHasFullAccess($my_user_id=0) {
704
            if (!$my_user_id) {
705
                // Super-user has all rights...
706
                if (user_is_super_user()) return true;
707
                $my_user_id=user_getid();
708
            } else {
709
                $u = UserManager::instance()->getUserById($my_user_id);
710
                if ($u->isSuperUser()) return true;
711
            }
712
            
713
            $sql="SELECT ugroup_id 
714
                  FROM permissions 
715
                  WHERE permission_type='TRACKER_ACCESS_FULL'
716
                    AND object_id='". db_ei($this->getID()) ."' 
717
                  ORDER BY ugroup_id";
718
            $res=db_query($sql);
719
720
            if (db_numrows($res) > 0) {
721
                while ($row = db_fetch_array($res)) {
722
                    // should work even for anonymous users
723
                    if (ugroup_user_is_member($my_user_id, $row['ugroup_id'], $this->Group->getID(), $this->getID())) {
724
                        return true;
725
                    }
726
                }
727
            }
728
            
729
            return false;
730
        }
731
732
	/**
733
	 *	userIsAdmin - see if the user's perms are >= 2 or project admin.
734
	 *
735
	 *  @param int $user_id the user ID to test, or current user if false
736
	 *	@return boolean
737
	 */
738
	function userIsAdmin($user_id = false) { 
739
	    $um =& UserManager::instance();
740
        if (! $user_id) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $user_id of type false|integer is loosely compared to false; this is ambiguous if the integer can be zero. You might want to explicitly use === null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For integer values, zero is a special case, in particular the following results might be unexpected:

0   == false // true
0   == null  // true
123 == false // false
123 == null  // false

// It is often better to use strict comparison
0 === false // false
0 === null  // false
Loading history...
741
            $user =& $um->getCurrentUser();
742
            $user_id = $user->getId();
743
        } else {
744
            $user =& $um->getUserById($user_id);    
745
        }
746
        if ($user->isTrackerAdmin($this->Group->getID(),$this->getID())) {
747
		    return true;
748
        } else {
749
            return false;
750
        }
751
	}
752
753
754
	/**
755
	 *	  userCanSubmit - determine if the user can submit an artifact (if he can submit a field).
756
         *        Note that if there is no group explicitely auhtorized, access is denied (don't check default values)
757
	 *
758
	 *	  @param $my_user_id	if not specified, use the current user id..
759
	 *	  @return boolean	user_can_submit.
760
	 */
761
        function userCanSubmit($my_user_id=0) {
762
763
            if (!$my_user_id) {
764
                // Super-user has all rights...
765
                if (user_is_super_user()) return true;
766
                $my_user_id=user_getid();
767
            } else {
768
                $u = UserManager::instance()->getUserById($my_user_id);
769
                if ($u->isSuperUser()) return true;
770
            }
771
772
            // Select submit permissions for all fields
773
            $sql="SELECT ugroup_id 
774
                  FROM permissions 
775
                  WHERE permission_type='TRACKER_FIELD_SUBMIT' 
776
                    AND object_id LIKE '". db_ei($this->getID()) ."#%' 
777
                  GROUP BY ugroup_id";
778
            $res=db_query($sql);
779
            
780
            if (db_numrows($res) > 0) {
781
                while ($row = db_fetch_array($res)) {
782
                    // should work even for anonymous users
783
                    if (ugroup_user_is_member($my_user_id, $row['ugroup_id'], $this->Group->getID(), $this->getID())) {
784
                        return true;
785
                    }
786
                }
787
            }
788
            
789
            return false;
790
        }
791
792
	/**
793
	 *	getCurrentUserPerm - get the logged-in user's perms from artifact_perm.
794
	 *
795
	 *	@return int perm level for the logged-in user.
796
	 */
797
	function getCurrentUserPerm() {
798
		if (!user_isloggedin()) {
799
			return 0;
800
		} else {
801
			if (!isset($this->current_user_perm)) {
802
				$sql="select perm_level
803
				FROM artifact_perm
804
				WHERE group_artifact_id='".  db_ei($this->getID())  ."'
805
				AND user_id='". db_ei(user_getid()) ."'";
806
				//echo $sql;
807
				$this->current_user_perm=db_result(db_query($sql),0,0);
808
			}
809
			return $this->current_user_perm;
810
		}
811
	}
812
813
	/**
814
	 *	getUserPerm - get a user's perms from artifact_perm.
815
	 *
816
	 *	@return int perm level for a user.
817
	 */
818
	function getUserPerm($user_id) {
819
		$sql="select perm_level
820
		FROM artifact_perm
821
		WHERE group_artifact_id='".  db_ei($this->getID())  ."'
822
		AND user_id='". db_ei($user_id) ."'";
823
		//echo $sql."<br>";
824
		return db_result(db_query($sql),0,0);
825
	}
826
827
	/**
828
	 * Get permissions for all fields based on the ugroups the user is part of
829
	 *
830
	 */
831
	function getFieldPermissions($ugroups) {
832
	  $art_field_fact = new ArtifactFieldFactory($this);
833
	  $used_fields = $art_field_fact->getAllUsedFields();
834
	  $field_perm = array();
835
836
	  reset($used_fields);
837
	  foreach ($used_fields as $field) {
838
	    $perm = $field->getPermissionForUgroups($ugroups,$this->getID());
839
	    if ($perm && !empty($perm)) {
840
	      $field_perm[$field->getName()] = $perm;
841
	    }
842
	  }
843
	  return $field_perm;
844
	}
845
846
	/**
847
	 *  update - use this to update this ArtifactType in the database.
848
	 *
849
	 *  @param	string	The item name.
850
	 *  @param	string	The item description.
851
	 *  @param	int		Days before this item is considered overdue.
852
	 *  @param	int		Days before stale items time out.
853
	 *  @param	bool	(1) true (0) false - whether the resolution box should be shown.
854
	 *  @param	string	Free-form string that project admins can place on the submit page.
855
	 *  @param	string	Free-form string that project admins can place on the browse page.
856
	 *  @param	bool	instantiate_for_new_projects (1) true (0) false - instantiate this tracker template for new projects
857
	 *  @return true on success, false on failure.
858
	 */
859
	function update($name,$description,$itemname,$allow_copy,
860
		            $submit_instructions,$browse_instructions,$instantiate_for_new_projects) {
861
	  global $Language;
862
     
863
		if ( !$this->userIsAdmin() ) {
864
			$this->setError('ArtifactType: '.$Language->getText('tracker_common_canned','perm_denied'));
865
			return false;
866
		}
867
		
868
		if (!$name || !$description || !$itemname || trim($name) == "" || trim($description) == "" || trim($itemname) == ""  ) {
869
			$this->setError('ArtifactType: '.$Language->getText('tracker_common_type','name_requ'));
870
			return false;
871
		}
872
        
873
        if (!eregi("^[a-zA-Z0-9_]+$",$itemname)) {
874
            $hp = Codendi_HTMLPurifier::instance();
875
            $this->setError($Language->getText('tracker_common_type','invalid_shortname', $hp->purify($itemname, CODENDI_PURIFIER_CONVERT_HTML) ));
876
            return false;
877
        }
878
        
879
        $group_id = $this->Group->getID();
880
        $old_name = $this->getName();
881
        
882
        if ($old_name != $name) {
883
            $atf = new ArtifactTypeFactory($this->Group);
884
            if($atf->isNameExists($name, $group_id)) {
885
                $this->setError($Language->getText('tracker_common_type','name_already_exists',$itemname));
886
                return false;
887
            }
888
        }         
889
         
890
		$allow_copy = ((!$allow_copy) ? 0 : $allow_copy);
891
        $instantiate_for_new_projects = ((!$instantiate_for_new_projects) ? 0 : $instantiate_for_new_projects); 
892
       
893
        $old_item_name=$this->getItemName() ;
894
       
895
        if ($old_item_name != $itemname) {
896
            $reference_manager = ReferenceManager::instance();
897
           
898
            if(!$reference_manager->checkKeyword($itemname) ) {
899
                $this->setError($Language->getText('tracker_common_type','invalid_shortname',$itemname));
900
                return false;
901
            }
902
           
903
            if($reference_manager->_isKeywordExists($itemname, $group_id)) {
904
                $this->setError($Language->getText('tracker_common_type','shortname_already_exists',$itemname));
905
                return false;
906
            }
907
         
908
           //Update table 'reference'
909
           $reference_dao =$this->getReferenceDao();
910
           $result =$reference_dao->update_keyword($old_item_name, $itemname, $this->Group->getID());
911
       
912
           //Update table 'cross_reference'
913
           $reference_dao = $this->getCrossReferenceDao();
914
           $result =$reference_dao->updateTargetKeyword($old_item_name, $itemname, $this->Group->getID());
915
           $result2 =$reference_dao->updateSourceKeyword($old_item_name, $itemname, $this->Group->getID());
916
       }
917
       
918
       //Update table 'artifact_group_list'
919
       $reference_dao = $this->getArtifactGroupListDao();
920
       $result = $reference_dao->updateArtifactGroupList($this->getID(), $this->Group->getID(), $name, $description, $itemname, $allow_copy, $submit_instructions, $browse_instructions, $instantiate_for_new_projects);
921
               
922
		if (!$result) {
923
			$this->setError('ArtifactType::Update(): '.db_error());
924
			return false;
925
		} else {
926
			$this->fetchData($this->getID());
927
			return true;
928
		}
929
	}
930
931
    /**
932
	 *  updateNotificationSettings - use this to update this ArtifactType in the database.
933
	 *
934
	 *  @param	int	uid the user to set watches on
935
	 *  @param	string	the list of users to watch
936
	 *  @param	string	the list of watching users
937
	 *  @return true on success, false on failure.
938
	 */
939
	function updateNotificationSettings($user_id, $watchees, $stop_notification) {
940
	    $this->setStopNotification($stop_notification);
941
		$this->setWatchees($user_id, $watchees);
942
        $this->fetchData($this->getID());
943
        return true;
944
	}
945
	
946
	function deleteWatchees($user_id) {
947
948
    		$sql = "DELETE FROM artifact_watcher WHERE user_id='". db_ei($user_id) ."' AND artifact_group_id='". db_ei($this->getID()) ."'";
949
		//echo $sql."<br>";
950
    		return db_query($sql);
951
	}
952
	
953
	function getWatchees($user_id) {
954
	    $sql = "SELECT watchee_id FROM artifact_watcher WHERE user_id='". db_ei($user_id) ."' AND artifact_group_id=". db_ei($this->getID()) ;
955
		//echo $sql."<br>";
956
	    return db_query($sql);    
957
	}
958
	
959
	function setWatchees($user_id, $watchees) {
960
	    global $Language;
961
		//echo "setWatchees($user_id, $watchees)<br>";
962
		if ($watchees) {
963
			//echo "watchees";
964
   			$res_watch = true;
965
            $arr_user_names = split('[,;]', $watchees);
966
			$arr_user_ids = array();
967
			while (list(,$user_name) = each($arr_user_names)) {
968
			    $user_ident = util_user_finder($user_name, true);
969
                $res = user_get_result_set_from_unix($user_ident);
970
			    if (!$res || (db_numrows($res) <= 0)) {
971
				// user doesn;t exist  so abort this step and give feedback
972
				$this->setError(" - ".$Language->getText('tracker_common_type','invalid_name',$user_name));
973
				$res_watch = false;
974
				continue;
975
			    } else {
976
				// store in a hash to eliminate duplicates. skip user itself
977
				if (db_result($res,0,'user_id') != $user_id)
978
				    $arr_user_ids[db_result($res,0,'user_id')] = 1;
979
			    }
980
			}
981
			
982
			if ($res_watch) {
983
			    $this->deleteWatchees($user_id); 
984
			    $arr_watchees = array_keys($arr_user_ids);
985
			    $sql = 'INSERT INTO artifact_watcher (artifact_group_id, user_id,watchee_id) VALUES ';
986
    			    $num_watchees = count($arr_watchees);
987
    			    for ($i=0; $i<$num_watchees; $i++) {
988
				$sql .= "('". db_ei($this->getID()) ."','". db_ei($user_id) ."','". db_ei($arr_watchees[$i]) ."'),";
989
    			    } 
990
    			$sql = substr($sql,0,-1); // remove extra comma at the end 
991
			//echo $sql."<br>";
992
    			return db_query($sql);
993
994
			}   
995
		} else 
996
			$this->deleteWatchees($user_id);	
997
	}
998
	
999
	function getWatchers($user_id) {
1000
	    $sql = "SELECT user_id FROM artifact_watcher WHERE watchee_id='". db_ei($user_id) ."' AND artifact_group_id=". db_ei($this->getID()) ;
1001
	    return db_query($sql);    
1002
	}
1003
	
1004
	function deleteNotification($user_id) {
1005
	    $sql = "DELETE FROM artifact_notification WHERE user_id='". db_ei($user_id) ."' AND group_artifact_id='". db_ei($this->getID()) ."'";
1006
	    //echo $sql."<br>";
1007
	    return db_query($sql);
1008
	}
1009
1010
	function setNotification($user_id,$arr_notification) {
1011
	    $sql = 'INSERT INTO artifact_notification (group_artifact_id, user_id,role_id,event_id,notify) VALUES ';
1012
	
1013
	    for ($i=0; $i<$this->num_roles; $i++) {
1014
			$role_id = $this->arr_roles[$i]['role_id'];
1015
			for ($j=0; $j<$this->num_events; $j++) { 
1016
			$event_id = $this->arr_events[$j]['event_id'];
1017
			$sql .= "('". db_ei($this->getID()) ."','". db_ei($user_id) ."','". db_ei($role_id) ."','". db_ei($event_id) ."','". db_ei($arr_notification[$role_id][$event_id]) ."'),"; 
1018
			} 
1019
		} 
1020
		$sql = substr($sql,0,-1); // remove extra comma at the end 
1021
		//echo $sql."<br>";
1022
		return db_query($sql); 
1023
	}
1024
1025
	
1026
	// People who have once submitted a bug
1027
	function getSubmitters ($with_display_preferences=false) {
1028
        $sqlname="user.user_name";
1029
        if ($with_display_preferences) {
1030
            $uh = new UserHelper();
1031
            $sqlname=$uh->getDisplayNameSQLQuery();
1032
        }
1033
		$group_artifact_id = $this->getID();
1034
		$sql="(SELECT DISTINCT user.user_id, ".$sqlname." , user.user_name ".
1035
			"FROM user,artifact ".
1036
			"WHERE (user.user_id=artifact.submitted_by ".
1037
			"AND artifact.group_artifact_id='". db_ei($group_artifact_id) ."') ".
1038
			"ORDER BY user.user_name)";
1039
		return $sql;
1040
	}
1041
		
1042
1043
	function getUsersPerm($group_artifact_id) {
1044
		$sql="SELECT u.user_id,u.user_name,au.perm_level ".
1045
			"FROM user u,artifact_perm au ".
1046
			"WHERE u.user_id=au.user_id AND au.group_artifact_id=". db_ei($group_artifact_id) ." ".
1047
			"ORDER BY u.user_name";
1048
		//echo $sql;
1049
		return db_query($sql);
1050
	}
1051
1052
	/**
1053
	 * Copy notification event from default
1054
	 *
1055
	 * @param group_artifact_id: the destination artifact type id
1056
	 *
1057
	 * @return boolean
1058
	 */
1059
	function copyNotificationEvent($group_artifact_id) {
1060
	    global $Language;
1061
		$sql = "insert into artifact_notification_event ".
1062
			   "select event_id,". db_ei($group_artifact_id) .",event_label,rank,short_description_msg,description_msg ".
1063
			   "from artifact_notification_event_default";
1064
			   
1065
		$res_insert = db_query($sql);
1066
		
1067
		if (!$res_insert || db_affected_rows($res_insert) <= 0) {
1068
			$this->setError($Language->getText('tracker_common_type','copy_fail'));
1069
			return false;
1070
		}
1071
		
1072
		return true;
1073
	}
1074
1075
	/**
1076
	 * Copy notification role from default
1077
	 *
1078
	 * @param group_artifact_id: the destination artifact type id
1079
	 *
1080
	 * @return boolean
1081
	 */
1082
	function copyNotificationRole($group_artifact_id) {
1083
	    global $Language;
1084
		$sql = "insert into artifact_notification_role ".
1085
			   "select role_id,". db_ei($group_artifact_id) .",role_label ,rank, short_description_msg,description_msg ".
1086
			   "from artifact_notification_role_default";
1087
			   
1088
		$res_insert = db_query($sql);
1089
		
1090
		if (!$res_insert || db_affected_rows($res_insert) <= 0) {
1091
			$this->setError($Language->getText('tracker_common_type','notif_fail'));
1092
			return false;
1093
		}
1094
		
1095
		return true;
1096
	}
1097
 
1098
	/**
1099
	 *
1100
	 * Get artifacts by age
1101
	 *
1102
	 * @return boolean
1103
	 */
1104
	function getOpenArtifactsByAge() {
1105
		$time_now=time();
1106
		//			echo $time_now."<P>";
1107
		
1108
		for ($counter=1; $counter<=8; $counter++) {
1109
		
1110
			$start=($time_now-($counter*604800));
1111
			$end=($time_now-(($counter-1)*604800));
1112
			
1113
			$sql="SELECT count(*) 
1114
                  FROM artifact 
1115
                  WHERE open_date >= $start AND open_date <= $end 
1116
                  AND status_id = '1' 
1117
                  AND group_artifact_id='". db_ei($this->getID()) ."'";
1118
			
1119
			$result = db_query($sql);
1120
			
1121
			$names[$counter-1]=format_date("m/d/y",($start))." to ".format_date("m/d/y",($end));
1122
			if (db_numrows($result) > 0) {
1123
				$values[$counter-1]=db_result($result, 0,0);
1124
			} else {
1125
				$values[$counter-1]='0';
1126
			}
1127
		}
1128
		
1129
		$results['names'] = $names;
1130
		$results['values'] = $values;
1131
		
1132
		return $results;
1133
	
1134
	}
1135
	
1136
	/**
1137
	 *
1138
	 * Get artifacts by age
1139
	 *
1140
	 * @return boolean
1141
	 */
1142
	function getArtifactsByAge() {
1143
		$time_now=time();
1144
		
1145
		for ($counter=1; $counter<=8; $counter++) {
1146
		
1147
			$start=($time_now-($counter*604800));
1148
			$end=($time_now-(($counter-1)*604800));
1149
			
1150
			$sql="SELECT avg((close_date-open_date)/86400) 
1151
                  FROM artifact 
1152
                  WHERE close_date > 0 AND (open_date >= $start AND open_date <= $end) 
1153
                  AND status_id <> '1' 
1154
                  AND group_artifact_id='". db_ei($this->getID()) ."'";
1155
			
1156
			$result = db_query($sql);
1157
			$names[$counter-1]=format_date("m/d/y",($start))." to ".format_date("m/d/y",($end));		
1158
			if (db_numrows($result) > 0) {
1159
				$values[$counter-1]=db_result($result, 0,0);
1160
			} else {
1161
				$values[$counter-1]='0';
1162
			}
1163
		}
1164
		
1165
		$results['names'] = $names;
1166
		$results['values'] = $values;
1167
		
1168
		return $results;
1169
		
1170
	}
1171
	
1172
	/**
1173
	 *
1174
	 * Get artifacts grouped by standard field
1175
	 *
1176
	 * @return boolean
1177
	 */
1178
	function getArtifactsBy($field) {
1179
	
1180
		$sql="SELECT ".$field->getName().", count(*) AS Count FROM artifact ".
1181
		" WHERE  artifact.group_artifact_id=". db_ei($this->getID()) .
1182
		" GROUP BY ".$field->getName();
1183
		
1184
		$result=db_query($sql);
1185
		if ($result && db_numrows($result) > 0) {
1186
			for ($j=0; $j<db_numrows($result); $j++) {
1187
				if ( $field->isSelectBox() || $field->isMultiSelectBox() ) {
1188
					$labelValue = $field->getLabelValues($this->getID(), array(db_result($result, $j, 0)));
1189
					$names[$j] = $labelValue[0];
1190
				} else {
1191
					$names[$j] = db_result($result, $j, 0);
1192
				}
1193
				$values[$j]= db_result($result, $j, 1);
1194
			}
1195
		}
1196
		
1197
		$results['names'] = $names;
1198
		$results['values'] = $values;
1199
		
1200
		return $results;
1201
	}
1202
	
1203
	/**
1204
	 *
1205
	 * Get open artifacts grouped by standard field
1206
	 *
1207
	 * @return boolean
1208
	 */
1209
	function getOpenArtifactsBy($field) {
1210
	
1211
		$sql="SELECT ".$field->getName().", count(*) AS Count FROM artifact ".
1212
		" WHERE artifact.group_artifact_id='". db_ei($this->getID()) ."' ".
1213
		" AND artifact.status_id=1".
1214
		" GROUP BY ".$field->getName();
1215
				
1216
		$result = db_query($sql);
1217
		if ($result && db_numrows($result) > 0) {
1218
			for ($j=0; $j<db_numrows($result); $j++) {
1219
				if ( $field->isSelectBox() || $field->isMultiSelectBox() ) {
1220
					$labelValue = $field->getLabelValues($this->getID(), array(db_result($result, $j, 0)));
1221
					$names[$j] = $labelValue[0];
1222
				} else {
1223
					$names[$j] = db_result($result, $j, 0);
1224
				}
1225
				$values[$j]= db_result($result, $j, 1);
1226
			}
1227
		}
1228
		
1229
		$results['names'] = $names;
1230
		$results['values'] = $values;
1231
		
1232
		return $results;
1233
	}
1234
	
1235
	/**
1236
	 *
1237
	 * Get artifacts grouped by field
1238
	 *
1239
	 * @return boolean
1240
	 */
1241
	function getArtifactsByField($field) {
1242
	
1243
		$sql="SELECT ".$field->getValueFieldName().", count(*) AS Count FROM artifact_field_value, artifact ".
1244
		    " WHERE  artifact.group_artifact_id='". db_ei($this->getID()) ."' ".
1245
		    " AND artifact_field_value.artifact_id=artifact.artifact_id".
1246
		    " AND artifact_field_value.field_id=". db_ei($field->getID()) .
1247
		    " GROUP BY ".$field->getValueFieldName();
1248
		
1249
		$result = db_query($sql);
1250
		if ($result && db_numrows($result) > 0) {
1251
			for ($j=0; $j<db_numrows($result); $j++) {
1252
				if ( $field->isSelectBox() || $field->isMultiSelectBox() ) {
1253
					$labelValue = $field->getLabelValues($this->getID(), array(db_result($result, $j, 0)));
1254
					$names[$j] = $labelValue[0];
1255
				} else {
1256
					$names[$j] = db_result($result, $j, 0);
1257
				}
1258
				
1259
				$values[$j]= db_result($result, $j, 1);
1260
			}
1261
			$results['names'] = $names;
1262
			$results['values'] = $values;
1263
1264
		}
1265
		return $results;
1266
	}
1267
	
1268
	/**
1269
	 *
1270
	 * Get open artifacts grouped by field
1271
	 *
1272
	 * @return boolean
1273
	 */
1274
	function getOpenArtifactsByField($field) {
1275
	
1276
		$sql="SELECT ".$field->getValueFieldName().", count(*) AS Count FROM artifact_field_value, artifact ".
1277
		" WHERE  artifact.group_artifact_id='". db_ei($this->getID()) ."' ".
1278
		" AND artifact_field_value.artifact_id=artifact.artifact_id".
1279
		" AND artifact_field_value.field_id=". db_ei($field->getID()) .
1280
		" AND artifact.status_id=1".  
1281
		" GROUP BY ".$field->getValueFieldName();
1282
		
1283
		$result = db_query($sql);
1284
		if ($result && db_numrows($result) > 0) {
1285
			for ($j=0; $j<db_numrows($result); $j++) {
1286
				if ( $field->isSelectBox() || $field->isMultiSelectBox() ) {
1287
					$labelValue = $field->getLabelValues($this->getID(), array(db_result($result, $j, 0)));
1288
					$names[$j] = $labelValue[0];
1289
				} else {
1290
					$names[$j] = db_result($result, $j, 0);
1291
				}
1292
				
1293
				$values[$j]= db_result($result, $j, 1);
1294
			}
1295
			$results['names'] = $names;
1296
			$results['values'] = $values;
1297
		
1298
		}
1299
		return $results;
1300
	}
1301
	
1302
1303
1304
	/**
1305
	 * Check if for a user and for role, there is a change
1306
	 *
1307
	 * @param user_id: the user id
1308
	 * @param role: the role
1309
	 * @param changes: array of changes
1310
	 *
1311
	 * @return boolean
1312
	 */
1313
	function checkNotification($user_id, $role, $changes=false) {
1314
	
1315
	    $send = false;
1316
	    $arr_notif = $this->buildNotificationMatrix($user_id);
1317
	    if (!$arr_notif || (count($arr_notif) == 0)) { return true; }
0 ignored issues
show
Bug Best Practice introduced by
The expression $arr_notif of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
1318
	
1319
	    // echo "==== DBG Checking Notif. for $user_id (role=$role)<br>";
1320
	    $user_name = user_getname($user_id);
1321
	
1322
	    //----------------------------------------------------------
1323
	    // If it's a new bug only (changes is false) check the NEW_BUG event and
1324
	    // ignore all other events
1325
	    if ($changes==false) {
0 ignored issues
show
Coding Style Best Practice introduced by
It seems like you are loosely comparing two booleans. Considering using the strict comparison === instead.

When comparing two booleans, it is generally considered safer to use the strict comparison operator.

Loading history...
1326
			if ($arr_notif[$role]['NEW_ARTIFACT']) {
1327
			    // echo "DBG NEW_ARTIFACT notified<br>";
1328
			    return true;
1329
			} else {
1330
			    // echo "DBG No notification<br>";
1331
			    return false;
1332
			}
1333
	    }
1334
	
1335
	    //----------------------------------------------------------
1336
	    //Check: I_MADE_IT  (I am the author of the change )
1337
	    // Check this one first because if the user said no she doesn't want to be 
1338
	    // aware of any of her change in this role and we can return immediately.
1339
	    if (($user_id == user_getid()) && !$arr_notif[$role]['I_MADE_IT']) {
1340
			 //echo "DBG Dont want to receive my own changes<br>";
1341
			return false;
1342
	    }
1343
	    
1344
	    //----------------------------------------------------------
1345
	    // Check :  NEW_COMMENT  A new followup comment is added 
1346
	    if ($arr_notif[$role]['NEW_COMMENT'] && isset($changes['comment'])) {
1347
			// echo "DBG NEW_COMMENT notified<br>";
1348
			return true;
1349
	    }
1350
	
1351
	    //----------------------------------------------------------
1352
	    //Check: NEW_FILE  (A new file attachment is added)
1353
	    if ($arr_notif[$role]['NEW_FILE'] && isset($changes['attach'])) {
1354
			// echo "DBG NEW_FILE notified<br>";
1355
			return true;
1356
	    }
1357
	  
1358
	    //----------------------------------------------------------
1359
	    //Check: CLOSED  (The bug is closed)
1360
	    // Rk: this one has precedence over PSS_CHANGE. So notify even if PSS_CHANGE
1361
	    // says no.
1362
	    if ($arr_notif[$role]['CLOSED'] && (isset($changes['status_id']) && $changes['status_id']['add'] == 'Closed')) {
1363
			// echo "DBG CLOSED bug notified<br>";
1364
			return true;
1365
	    }
1366
	
1367
	    //----------------------------------------------------------
1368
	    //Check: PSS_CHANGE  (Priority,Status,Severity changes)
1369
	    if ($arr_notif[$role]['PSS_CHANGE'] && 
1370
		(isset($changes['priority']) || isset($changes['status_id']) || isset($changes['severity'])) ) {
1371
			// echo "DBG PSS_CHANGE notified<br>";
1372
			return true;
1373
	    }
1374
	
1375
	
1376
	    //----------------------------------------------------------
1377
	    // Check :  ROLE_CHANGE (I'm added to or removed from this role)
1378
	    // Rk: This event is meanningless for Commenters. It also is for submitter but may be
1379
	    // one day the submitter will be changeable by the project admin so test it.
1380
	    // Rk #2: check this one at the end because it is the most CPU intensive and this
1381
	    // event seldomly happens
1382
	    if ($arr_notif['SUBMITTER']['ROLE_CHANGE'] &&
1383
		isset($changes['submitted_by']) && (($changes['submitted_by']['add'] == $user_name) || ($changes['submitted_by']['del'] == $user_name)) &&
1384
		($role == 'SUBMITTER') ) {
1385
			// echo "DBG ROLE_CHANGE for submitter notified<br>";
1386
			return true;
1387
	    }
1388
	
1389
	    if ($arr_notif['ASSIGNEE']['ROLE_CHANGE'] &&
1390
		isset($changes['assigned_to']) && (($changes['assigned_to']['add'] == $user_name) || ($changes['assigned_to']['del'] == $user_name)) &&
1391
		($role == 'ASSIGNEE') ) {
1392
			// echo "DBG ROLE_CHANGE for role assignee notified<br>";
1393
			return true;
1394
	    }
1395
	
1396
	    $arr_cc_changes = array();
1397
	    if (isset($changes['CC']['add'])) {
1398
			$arr_cc_changes = split('[,;]',$changes['CC']['add']);
1399
		}
1400
	    $arr_cc_changes[] = isset($changes['CC']['del']) ? $changes['CC']['del'] : null;
1401
	    $is_user_in_cc_changes = in_array($user_name,$arr_cc_changes);    
1402
	    $are_anyother_user_in_cc_changes =
1403
		(!$is_user_in_cc_changes || count($arr_cc_changes)>1);    
1404
	
1405
	    if ($arr_notif['CC']['ROLE_CHANGE'] && ($role == 'CC')) {
1406
			if ($is_user_in_cc_changes) {
1407
			    // echo "DBG ROLE_CHANGE for cc notified<br>";
1408
			    return true;
1409
			}
1410
	    }
1411
	    
1412
	    //----------------------------------------------------------
1413
	    //Check: CC_CHANGE  (CC_CHANGE is added or removed)
1414
	    // check this right after because  role cahange for cc can contradict
1415
	    // thee cc_change notification. If the role change on cc says no notification
1416
	    // then it has precedence over a cc_change
1417
	    if ($arr_notif[$role]['CC_CHANGE'] && isset($changes['CC'])) {
1418
			// it's enough to test role against 'CC' because if we are at that point
1419
			// it means that the role_change for CC was false or that role is not CC
1420
			// So if role is 'CC' and we are here it means that the user asked to not be
1421
			// notified on role_change as CC, unless other users are listed in the cc changes
1422
			if (($role != 'CC') || (($role == 'CC') && $are_anyother_user_in_cc_changes)) {
1423
			    // echo "DBG CC_CHANGE notified<br>";
1424
			    return true; 
1425
			}
1426
	    }
1427
	
1428
	
1429
	    //----------------------------------------------------------
1430
	    //Check: CHANGE_OTHER  (Any changes not mentioned above)
1431
	    // *** THIS ONE MUST ALWAYS BE TESTED LAST
1432
	    
1433
	    // Delete all tested fields from the $changes array. If any remains then it
1434
	    // means a notification must be sent
1435
	    unset($changes['comment']);
1436
	    unset($changes['attach']);
1437
	    unset($changes['priority']);
1438
	    unset($changes['severity']);
1439
	    unset($changes['status_id']);
1440
	    unset($changes['CC']);
1441
	    unset($changes['assigned_to']);
1442
	    unset($changes['submitted_by']);
1443
	    if ($arr_notif[$role]['ANY_OTHER_CHANGE'] && count($changes)) {
1444
			// echo "DBG ANY_OTHER_CHANGE notified<br>";
1445
			return true;
1446
	    }
1447
	
1448
	    // Sorry, no notification...
1449
	    // echo "DBG No notification!!<br>";
1450
	    return false;
1451
	}
1452
1453
	/**
1454
	 * Build the matrix role/event=notify
1455
	 *
1456
	 * @param user_id: the user id
1457
	 *
1458
	 * @return array
1459
	 */
1460
	function buildNotificationMatrix($user_id) {
1461
        $arr_notif = array();
1462
	    // Build the notif matrix indexed with roles and events labels (not id)
1463
	    $res_notif = $this->getNotificationWithLabels($user_id);
1464
	    while ($arr = db_fetch_array($res_notif)) {
1465
			//echo "<br>".$arr['role_label']." ".$arr['event_label']." ".$arr['notify'];
1466
			$arr_notif[$arr['role_label']][$arr['event_label']] = $arr['notify'];
1467
	    }
1468
	    return $arr_notif;
1469
	}
1470
1471
	/**
1472
	 * Retrieve the matrix role/event=notify from the db
1473
	 *
1474
	 * @param user_id: the user id
1475
	 *
1476
	 * @return array
1477
	 */
1478
	function getNotificationWithLabels($user_id) {
1479
		
1480
		$group = $this->getGroup();
1481
		$group_artifact_id = $this->getID();
1482
		
1483
	    $sql = "SELECT role_label,event_label,notify FROM artifact_notification_role r, artifact_notification_event e,artifact_notification n ".
1484
		"WHERE n.group_artifact_id=". db_ei($group_artifact_id) ." AND n.user_id=". db_ei($user_id) ." AND ".
1485
		"n.role_id=r.role_id AND r.group_artifact_id=". db_ei($group_artifact_id) ." AND ".
1486
		"n.event_id=e.event_id AND e.group_artifact_id=". db_ei($group_artifact_id) ;
1487
1488
/*
1489
	$sql = "SELECT role_label,event_label,notify FROM artifact_notification_role_default r, artifact_notification_event_default e,artifact_notification n ".
1490
		"WHERE n.user_id=$user_id AND ".
1491
		"n.role_id=r.role_id AND ".
1492
		"n.event_id=e.event_id";
1493
*/
1494
	    //echo $sql."<br>";
1495
	    return db_query($sql);
1496
	    
1497
	    
1498
	}
1499
1500
	/**
1501
	 * Retrieve the next free field id (computed by max(id)+1)
1502
	 *
1503
	 * @return int
1504
	 */
1505
	function getNextFieldID() {
1506
		$sql = "SELECT max(field_id)+1 FROM artifact_field WHERE group_artifact_id=". db_ei($this->getID()) ;
1507
			   
1508
		$result = db_query($sql);
1509
	    if ($result && db_numrows($result) > 0) {
1510
	    	return db_result($result, 0, 0);
1511
	    } else {
1512
	    	return -1;
1513
	    }
1514
	}
1515
1516
	/**
1517
	 * Return a field name built using an id
1518
	 *
1519
	 * @param id: the id used to build the field name
1520
	 *
1521
	 * @return array
1522
	 */
1523
	function buildFieldName($id) {
1524
		return "field_".$id;
1525
	}
1526
	
1527
	/**
1528
	 * Return the different elements for building the export query
1529
	 *
1530
	 * @param fields: the field list
1531
	 * @param select: the select value
1532
	 * @param from: the from value
1533
	 * @param where: the where value
1534
	 * @param count: the number of 
1535
	 *
1536
	 * @return void
1537
	 */
1538
	function getExportQueryElements($fields,&$select,&$from,&$where,&$count_user_fields) {
1539
		
1540
		//
1541
		// NOTICE
1542
		//
1543
		// Use left join because of the performance
1544
		// So the restriction to this: all fields used in the query must have a value.
1545
		// That involves artifact creation or artifact admin (add a field) must create
1546
		// empty records with default values for fields which haven't a value (from the user).
1547
		//
1548
		/* The query must be something like this :
1549
			SELECT a.artifact_id,u.user_name,v1.valueInt,v2.valueText,u3.user_name
1550
			FROM artifact a 
1551
                             LEFT JOIN artifact_field_value v1 ON (v1.artifact_id=a.artifact_id)
1552
                             LEFT JOIN artifact_field_value v2 ON (v2.artifact_id=a.artifact_id)
1553
                             LEFT JOIN artifact_field_value v3 ON (v2.artifact_id=a.artifact_id)
1554
                             LEFT JOIN user u3 ON (v3.valueInt = u3.user_id)
1555
                             LEFT JOIN user u
1556
			WHERE a.group_artifact_id = 100 and 
1557
			v1.field_id=101 and
1558
			v2.field_id=103 and
1559
			v3.field_id=104 and
1560
			a.submitted_by = u.user_id
1561
			group by a.artifact_id
1562
			order by v3.valueText,v1.valueInt
1563
		*/
1564
1565
1566
		$count = 1;
1567
		$count_user_fields = 0;
1568
		reset($fields);
1569
		
1570
		$select = "SELECT ";
1571
		$from = "FROM artifact a";
1572
		$where = "WHERE a.group_artifact_id = ". db_ei($this->getID()) ; 
1573
				
1574
		$select_count = 0;
1575
		
1576
		if ( count($fields) == 0 )
1577
			return;
1578
1579
		while (list($key,$field) = each($fields) ) {
0 ignored issues
show
Unused Code introduced by
The assignment to $key is unused. Consider omitting it like so list($first,,$third).

This checks looks for assignemnts to variables using the list(...) function, where not all assigned variables are subsequently used.

Consider the following code example.

<?php

function returnThreeValues() {
    return array('a', 'b', 'c');
}

list($a, $b, $c) = returnThreeValues();

print $a . " - " . $c;

Only the variables $a and $c are used. There was no need to assign $b.

Instead, the list call could have been.

list($a,, $c) = returnThreeValues();
Loading history...
1580
			
1581
		  //echo $field->getName()."-".$field->getID()."<br>";
1582
			
1583
			// If the field is a standard field ie the value is stored directly into the artifact table (severity, artifact_id, ...)
1584
			if ( $field->isStandardField() ) {
1585
				if ( $select_count != 0 ) {
1586
					$select .= ",";
1587
					$select_count ++;
1588
				} else {
1589
					$select_count = 1;
1590
				}
1591
1592
				// Special case for fields which are user name
1593
				if ( ($field->isUsername())&&(!$field->isSelectBox())&&(!$field->isMultiSelectBox()) ) {
1594
					$select .= " u.user_name as ".$field->getName();
1595
					$from .= " LEFT JOIN user u ON (u.user_id=a.".$field->getName().")";
1596
					$count_user_fields++;
1597
				} else {
1598
					$select .= " a.".$field->getName();
1599
				}
1600
				
1601
				
1602
			} else {
1603
				
1604
				// Special case for comment_type_id field - No data stored in artifact_field_value
1605
				if ( $field->getName() != "comment_type_id" ) {
1606
					// The field value is stored into the artifact_field_value table
1607
					// So we need to add a new join
1608
					if ( $select_count != 0 ) {
1609
						$select .= ",";
1610
						$select_count ++;
1611
					} else {
1612
						$select_count = 1;
1613
					}
1614
	
1615
					// Special case for fields which are user name
1616
					$from .= " LEFT JOIN artifact_field_value v".$count." ON (v".$count.".artifact_id=a.artifact_id".
1617
					  " and v".$count.".field_id=". db_ei($field->getID()) .")";
1618
					//$where .= " and v".$count.".field_id=".$field->getID();
1619
					if ( ($field->isUsername())&&(!$field->isSelectBox())&&(!$field->isMultiSelectBox()) ) {
1620
						$select .= " u".$count.".user_name as ".$field->getName();
1621
						$from .= " LEFT JOIN user u".$count." ON (v".$count.".".$field->getValueFieldName()." = u".$count.".user_id)";
1622
						$count_user_fields++;
1623
					} else {
1624
						$select .= " v".$count.".".$field->getValueFieldName()." as ".$field->getName();
1625
					}
1626
1627
1628
					$count ++;
1629
				}
1630
			}
1631
1632
		}
1633
		
1634
	}
1635
	
1636
	
1637
	/**
1638
	 * Return the query string, for export
1639
	 *
1640
	 * @param fields (OUT): the field list 
1641
	 * @param col_list (OUT): the field name list
1642
	 * @param lbl_list (OUT): the field label list
1643
	 * @param dsc_list (OUT): the field description list
1644
	 * @param select (OUT):
1645
	 * @param from (OUT):
1646
	 * @param where (OUT):
1647
	 * @param multiple_queries (OUT):
1648
	 * @param all_queries (OUT):
1649
	 *
1650
	 * @return string: the sql query
0 ignored issues
show
Documentation introduced by
The doc-type string: could not be parsed: Unknown type name "string:" at position 0. (view supported doc-types)

This check marks PHPDoc comments that could not be parsed by our parser. To see which comment annotations we can parse, please refer to our documentation on supported doc-types.

Loading history...
1651
	 */
1652
	function buildExportQuery(&$fields,&$col_list,&$lbl_list,&$dsc_list,&$select,&$from,&$where,&$multiple_queries,&$all_queries,$constraint=false) {
1653
	  global $art_field_fact,$art_fieldset_fact;
1654
	  $sql = null;
1655
	  $all_queries = array();
1656
	  // this array will be filled with the fields to export, ordered by fieldset and rank,
1657
      // and send as an output argument of the function
1658
      $fields = array();
1659
	  $fieldsets = $art_fieldset_fact->getAllFieldSetsContainingUsedFields();
1660
      // fetch the fieldsets
1661
      foreach ($fieldsets as $fieldset) {
1662
          $fields_in_fieldset = $fieldset->getAllUsedFields();
1663
          // for each fieldset, fetch the used fields inside
1664
          while (list(,$field) = each($fields_in_fieldset) ) {
1665
            if ( $field->getName() != "comment_type_id" ) {
1666
                $fields[$field->getName()] = $field;
1667
                $col_list[$field->getName()] = $field->getName();
1668
                $lbl_list[$field->getName()] = $field->getLabel();
1669
                $dsc_list[$field->getName()] = $field->getDescription();
1670
            }
1671
          }
1672
      }
1673
	  
1674
	  //it gets a bit more complicated if we have more fields than SQL wants to treat in one single query
1675
	  if (count($fields) > $GLOBALS['sys_server_join']) {
1676
	    $multiple_queries = true;
1677
	    $chunked_fields = array_chunk($fields,$GLOBALS['sys_server_join']-3,true);
1678
	    $this->cutExportQuery($chunked_fields,$select,$from,$where,$all_queries,$constraint);
1679
	      
1680
	      
1681
	  } else {
1682
	    $multiple_queries = false;
1683
	    $this->getExportQueryElements($fields,$select,$from,$where,$count_user_fields);
1684
	    
1685
	    if ($count_user_fields > $GLOBALS['sys_server_join'] - count($fields)) {
1686
	      $multiple_queries = true;
1687
	      $chunked_fields = array_chunk($fields,count($fields)/2,true);
1688
	      $this->cutExportQuery($chunked_fields,$select,$from,$where,$count_user_fields,$all_queries,$constraint);
1689
	    } else {
1690
	      $sql = $select." ".$from." ".$where." ".($constraint ? $constraint : "")." group by a.artifact_id";
1691
	    }
1692
	  }
1693
	  return $sql;
1694
	}
1695
	
1696
	function cutExportQuery($chunks,&$select,&$from,&$where,&$all_queries,$constraint=false) {
1697
	  foreach ($chunks as $chunk) {
1698
	    $this->getExportQueryElements($chunk,$select,$from,$where,$count_user_fields);
1699
	    if ($count_user_fields > $GLOBALS['sys_server_join'] - count($chunk)) {
1700
	      //for each user field we join another user table
1701
	      $chunked_fields = array_chunk($chunk,count($chunk)/2,true);
1702
	      $this->cutExportQuery($chunked_fields,$select,$from,$where,$count_user_fields,$all_queries,$constraint);
1703
	    } else {
1704
	      $sql = $select." ".$from." ".$where." ".($constraint ? $constraint : "")." group by a.artifact_id";
1705
	      $all_queries[] = $sql;
1706
	    }
1707
	  }
1708
	}
1709
1710
1711
	/**
1712
	 * Return the artifact data with all fields set to default values. (for export)
1713
	 *
1714
	 * @return array: the sql query
0 ignored issues
show
Documentation introduced by
The doc-type array: could not be parsed: Unknown type name "array:" at position 0. (view supported doc-types)

This check marks PHPDoc comments that could not be parsed by our parser. To see which comment annotations we can parse, please refer to our documentation on supported doc-types.

Loading history...
1715
	 */
1716
	function buildDefaultRecord() {
1717
		global $art_field_fact;
1718
		
1719
		$fields = $art_field_fact->getAllUsedFields();
1720
1721
		reset($fields);
1722
		while (list(,$field) = each($fields) ) {
1723
		  $record[$field->getName()] = $field->getDefaultValue();
1724
		}
1725
		
1726
		return $record;
1727
	}
1728
1729
1730
	/** retrieves all the cc addresses with their artifact_cc_ids
1731
	 * for a list of artifact_ids
1732
	 * @param change_ids: the list of artifact_ids for which we search the emails
1733
	 */ 
1734
	function getCC($change_ids) {
1735
		$sql = "select email,artifact_cc_id from artifact_cc where artifact_id in (". db_es(implode(",",$change_ids)) .") order by email";
1736
		$result = db_query($sql);
1737
		return $result;
1738
	}
1739
1740
	/**
1741
     	* Delete an email address in the CC list
1742
     	*
1743
     	* @param artifact_cc_id: cc list id
1744
     	* @param changes (OUT): list of changes
1745
     	*
1746
     	* @return boolean
1747
     	*/
1748
    	function deleteCC($delete_cc) {
1749
        	
1750
		$ok=true;
1751
		while (list(,$artifact_ccs) = each($delete_cc)) {
1752
			$artifact_cc_ids = explode(",",$artifact_ccs);
1753
			$i = 0;
1754
			while (list(,$artifact_cc_id) = each($artifact_cc_ids)) {
1755
	        		$sql = "SELECT artifact_id from artifact_cc WHERE artifact_cc_id=". db_ei($artifact_cc_id) ;
1756
        			$res = db_query($sql);
1757
        			if (db_numrows($res) > 0) {
1758
					$i++;
1759
					$aid = db_result($res, 0, 'artifact_id');
1760
					$ah = new ArtifactHtml($this,$aid);
1761
					$ok &= $ah->deleteCC($artifact_cc_id,$changes,true);
0 ignored issues
show
Bug introduced by
The variable $changes does not exist. Did you forget to declare it?

This check marks access to variables or properties that have not been declared yet. While PHP has no explicit notion of declaring a variable, accessing it before a value is assigned to it is most likely a bug.

Loading history...
1762
				}
1763
        		}
1764
		}
1765
		return $ok;
1766
    	}
1767
1768
1769
	/**
1770
	 * retrieves all the attached files with their size and id
1771
	 * for a list of artifact_ids
1772
	 * @param change_ids: the list of artifact_ids for which we search the attached files
1773
	*/
1774
	function getAttachedFiles($change_ids) {
1775
		$sql = "select filename,filesize,id from artifact_file where artifact_id in (". db_es(implode(",",$change_ids)) .") order by filename,filesize";
1776
		return db_query($sql);
1777
	}
1778
1779
1780
	/**
1781
	* Delete the files with specified id from $ids
1782
	* @return bool
1783
	*/
1784
	function deleteAttachedFiles($delete_attached) {
1785
		$ok=true;
1786
		$i = 0;
1787
		while (list(,$id_list) = each($delete_attached)) {
1788
			$ids = explode(",",$id_list);
1789
			while (list(,$id) = each($ids)) {
1790
				$sql = "SELECT artifact_id FROM artifact_file WHERE id = ". db_ei($id) ;
1791
				$res = db_query($sql);
1792
        			if (db_numrows($res) > 0) {
1793
					$aid = db_result($res, 0, 'artifact_id');
1794
					$ah = new ArtifactHtml($this,$aid);
1795
					$afh=new ArtifactFileHtml($ah,$id);
1796
                        		if (!$afh || !is_object($afh)) {
1797
                               	 		$GLOBALS['Response']->addFeedback('error', 'Could Not Create File Object::'.$afh->getName());
1798
                        		} elseif ($afh->isError()) {
1799
                                		$GLOBALS['Response']->addFeedback('error', $afh->getErrorMessage().'::'.$afh->getName());
1800
                        		} else {
1801
						$i++;
1802
                                		$okthis = $afh->delete();
1803
						if (!$okthis) $GLOBALS['Response']->addFeedback('error', '<br>File Delete: '.$afh->getErrorMessage());
1804
						$ok &= $okthis;
1805
                        		}	
1806
				}
1807
			}
1808
		}
1809
		return $ok;
1810
	}
1811
1812
	/**
1813
	 * retrieves all artifacts
1814
	 * for a list of artifact_ids
1815
	 * @param change_ids: the list of artifact_ids for which we search the attached files
1816
	*/
1817
	function getDependencies($change_ids) {
1818
		$sql = "select d.artifact_depend_id,d.is_dependent_on_artifact_id,a.summary,ag.name,g.group_name, g.group_id ".
1819
			"from artifact_dependencies as d, artifact_group_list ag, groups g, artifact a ".
1820
			"where d.artifact_id in (". db_es(implode(",",$change_ids)) .") AND ".
1821
			"d.is_dependent_on_artifact_id = a.artifact_id AND ".
1822
            		"a.group_artifact_id = ag.group_artifact_id AND ".
1823
            		"ag.group_id = g.group_id ".
1824
			"order by is_dependent_on_artifact_id";
1825
		return db_query($sql);
1826
	}
1827
1828
1829
	/** delete all the dependencies specified in delete_dependend */
1830
	function deleteDependencies($delete_depend) {
1831
	    global $Language;
1832
		$changed = true;
1833
		while (list(,$depend) = each($delete_depend)) {
1834
			$sql = "DELETE FROM artifact_dependencies WHERE artifact_depend_id IN (". db_es($depend) .")";
1835
        		$res = db_query($sql);
1836
        		if (!$res) {
1837
            			$GLOBALS['Response']->addFeedback('error', $Language->getText('tracker_common_type','del_err',array($dependent,db_error($res))));
0 ignored issues
show
Bug introduced by
The variable $dependent does not exist. Did you mean $depend?

This check looks for variables that are accessed but have not been defined. It raises an issue if it finds another variable that has a similar name.

The variable may have been renamed without also renaming all references.

Loading history...
1838
				$changed = false;
1839
        		}
1840
		}
1841
		if ($changed) $GLOBALS['Response']->addFeedback('info', $Language->getText('tracker_common_artifact','depend_removed'));
1842
		return $changed;
1843
        }	
1844
	
1845
1846
	/**
1847
	 * @param group_id: the group id of the new tracker
1848
	 * @param group_id_template: the template group id (used for the copy)
1849
	 * @param atid_template: the template artfact type id 
1850
	 */
1851
	function copyArtifacts($from_atid) {
1852
	  $result = db_query("SELECT artifact_id FROM artifact WHERE group_artifact_id='". db_ei($from_atid) ."'");
1853
	  while ($row = db_fetch_array($result)) {
1854
	    if (!$this->copyArtifact($from_atid,$row['artifact_id']) ) {return false;}
1855
	  }
1856
	  return true;
1857
	}
1858
	
1859
	
1860
	function copyArtifact($from_atid,$from_aid) {
1861
	    $aid = 0;
1862
	    $res = true;
1863
	    
1864
	    // copy common artifact fields
1865
        $id_sharing = new TrackerIdSharingDao();
1866
        if ($aid = $id_sharing->generateArtifactId()) {
1867
            $result = db_query("INSERT INTO artifact (artifact_id, group_artifact_id,status_id,submitted_by,open_date,close_date,summary,details,severity) ".
1868
                "SELECT $aid, ". db_ei($this->getID()) .",status_id,submitted_by,".time().",close_date,summary,details,severity ".
1869
                "FROM artifact ".
1870
                "WHERE artifact_id='". db_ei($from_aid) ."' ".
1871
                "AND group_artifact_id='". db_ei($from_atid) ."'");
1872
            if (!$result || db_affected_rows($result) == 0) {
1873
                $this->setError(db_error());
1874
                return false;
1875
            }
1876
            
1877
            
1878
            // copy specific artifact fields
1879
            $result = db_query("INSERT INTO artifact_field_value (field_id,artifact_id,valueInt,valueText,valueFloat,valueDate) ".
1880
                "SELECT field_id,". db_ei($aid) .",valueInt,valueText,valueFloat,valueDate ".
1881
                "FROM artifact_field_value ".
1882
                "WHERE artifact_id = '". db_ei($from_aid) ."'");
1883
            if (!$result || db_affected_rows($result) <= 0) {
1884
                $this->setError(db_error());
1885
                $res = false;
1886
            }
1887
            
1888
            //copy cc addresses
1889
            $result = db_query("INSERT INTO artifact_cc (artifact_id,email,added_by,comment,date) ".
1890
                "SELECT ". db_ei($aid) .",email,added_by,comment,date ".
1891
                "FROM artifact_cc ".
1892
                "WHERE artifact_id='". db_ei($from_aid) ."'");
1893
            if (!$result || db_affected_rows($result) <= 0) {
1894
                $this->setError(db_error());
1895
                $res = false;
1896
            }
1897
            
1898
            //copy artifact files
1899
            db_query("INSERT INTO artifact_file (artifact_id,description,bin_data,filename,filesize,filetype,adddate,submitted_by) ".
1900
                "SELECT ".$aid.",description,bin_data,filename,filesize,filetype,adddate,submitted_by ".
1901
                "FROM artifact_file ".
1902
                "WHERE artifact_id='". db_ei($from_aid) ."'");
1903
            if (!$result || db_affected_rows($result) <= 0) {
1904
                $this->setError(db_error());
1905
                $res = false;
1906
            }
1907
            
1908
            return $res;
1909
        }
1910
        return false;
1911
    }
1912
    
1913
    function getReferenceDao() {
1914
        return new ReferenceDao(CodendiDataAccess::instance());
1915
    }
1916
    
1917
    function getCrossReferenceDao() {
1918
        return new CrossReferenceDao(CodendiDataAccess::instance());
1919
    }
1920
    
1921
    function getArtifactGroupListDao() {
1922
        return new ArtifactGroupListDao(CodendiDataAccess::instance());
1923
    }
1924
}
1925
1926
?>
1927