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 |
||
| 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() { |
||
| 246 | |||
| 247 | /** |
||
| 248 | * getID - get this ArtifactTypeID. |
||
| 249 | * |
||
| 250 | * @return int The group_artifact_id #. |
||
| 251 | */ |
||
| 252 | function getID() { |
||
| 255 | |||
| 256 | /** |
||
| 257 | * getID - get this Artifact Group ID. |
||
| 258 | * |
||
| 259 | * @return int The group_id #. |
||
| 260 | */ |
||
| 261 | function getGroupID() { |
||
| 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() { |
||
| 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() { |
||
| 284 | |||
| 285 | /** |
||
| 286 | * isInstantiatedForNewProjects |
||
| 287 | * |
||
| 288 | * @return boolean - true if the tracker is instantiated for new projects (tracker templates). |
||
| 289 | */ |
||
| 290 | function isInstantiatedForNewProjects() { |
||
| 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() { |
||
| 319 | |||
| 320 | /** |
||
| 321 | * getSubmitInstructions - get the free-form string strings. |
||
| 322 | * |
||
| 323 | * @return string instructions. |
||
| 324 | */ |
||
| 325 | function getSubmitInstructions() { |
||
| 328 | |||
| 329 | /** |
||
| 330 | * getBrowseInstructions - get the free-form string strings. |
||
| 331 | * |
||
| 332 | * @return string instructions. |
||
| 333 | */ |
||
| 334 | function getBrowseInstructions() { |
||
| 337 | |||
| 338 | /** |
||
| 339 | * getName - the name of this ArtifactType. |
||
| 340 | * |
||
| 341 | * @return string name. |
||
| 342 | */ |
||
| 343 | function getName() { |
||
| 346 | |||
| 347 | /** |
||
| 348 | * getItemName - the item name of this ArtifactType. |
||
| 349 | * |
||
| 350 | * @return string name. |
||
| 351 | */ |
||
| 352 | function getItemName() { |
||
| 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() { |
||
| 364 | |||
| 365 | /** |
||
| 366 | * getDescription - the description of this ArtifactType. |
||
| 367 | * |
||
| 368 | * @return string description. |
||
| 369 | */ |
||
| 370 | function getDescription() { |
||
| 373 | |||
| 374 | /** |
||
| 375 | * this tracker is not deleted |
||
| 376 | * |
||
| 377 | * @return boolean. |
||
|
|
|||
| 378 | */ |
||
| 379 | function isValid() { |
||
| 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 |
||
| 405 | */ |
||
| 406 | function getStopNotification() { |
||
| 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) { |
||
| 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) { |
||
| 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) { |
||
| 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) { |
||
| 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; } |
||
| 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) { |
||
| 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) { |
||
| 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) ) { |
||
| 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 |
||
| 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) { |
||
| 1709 | |||
| 1710 | |||
| 1711 | /** |
||
| 1712 | * Return the artifact data with all fields set to default values. (for export) |
||
| 1713 | * |
||
| 1714 | * @return array: the sql query |
||
| 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) { |
||
| 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) { |
||
| 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) { |
||
| 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() { |
||
| 1916 | |||
| 1917 | function getCrossReferenceDao() { |
||
| 1920 | |||
| 1921 | function getArtifactGroupListDao() { |
||
| 1924 | } |
||
| 1925 | |||
| 1926 | ?> |
||
| 1927 |
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.