Complex classes like Artifact 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 Artifact, and based on these observations, apply Extract Interface, too.
| 1 | <?php |
||
| 29 | class Artifact extends Error { |
||
| 30 | |||
| 31 | const FORMAT_TEXT = 0; |
||
| 32 | const FORMAT_HTML = 1; |
||
| 33 | |||
| 34 | //The diffetents mode of display |
||
| 35 | const OUTPUT_BROWSER = 0; |
||
| 36 | const OUTPUT_EXPORT = 1; |
||
| 37 | const OUTPUT_MAIL_TEXT = 2; |
||
| 38 | |||
| 39 | /** |
||
| 40 | * Artifact Type object. |
||
| 41 | * |
||
| 42 | * @var object $ArtifactType. |
||
| 43 | */ |
||
| 44 | var $ArtifactType; |
||
| 45 | |||
| 46 | /** |
||
| 47 | * Array of artifact data. |
||
| 48 | * |
||
| 49 | * @var array $data_array. |
||
| 50 | */ |
||
| 51 | var $data_array; |
||
| 52 | |||
| 53 | |||
| 54 | /** |
||
| 55 | * Artifact - constructor. |
||
| 56 | * |
||
| 57 | * @param object The ArtifactType object. |
||
| 58 | * @param integer (primary key from database OR complete assoc array) |
||
| 59 | * ONLY OPTIONAL WHEN YOU PLAN TO IMMEDIATELY CALL ->create() |
||
| 60 | * @return boolean success. |
||
| 61 | */ |
||
| 62 | function Artifact(&$ArtifactType, $data=false, $checkPerms = true) { |
||
| 63 | global $Language; |
||
| 64 | $this->Error(); |
||
| 65 | |||
| 66 | $this->ArtifactType = $ArtifactType; |
||
| 67 | |||
| 68 | //was ArtifactType legit? |
||
| 69 | if (!$ArtifactType || !is_object($ArtifactType)) { |
||
| 70 | $this->setError('Artifact: '.$Language->getText('tracker_common_canned','not_valid')); |
||
| 71 | return false; |
||
| 72 | } |
||
| 73 | //did ArtifactType have an error? |
||
| 74 | if ($ArtifactType->isError()) { |
||
| 75 | $this->setError('Artifact: '.$ArtifactType->getErrorMessage()); |
||
| 76 | return false; |
||
| 77 | } |
||
| 78 | |||
| 79 | // |
||
| 80 | // make sure this person has permission to view artifacts belonging to this tracker |
||
| 81 | // |
||
| 82 | if ($checkPerms && !$this->ArtifactType->userCanView()) { |
||
| 83 | $this->setError('Artifact: '.$Language->getText('tracker_common_artifact','view_private')); |
||
| 84 | return false; |
||
| 85 | } |
||
| 86 | |||
| 87 | // |
||
| 88 | // set up data structures |
||
| 89 | // |
||
| 90 | if ($data) { |
||
| 91 | if (is_array($data)) { |
||
| 92 | $this->data_array = $data; |
||
| 93 | // |
||
| 94 | // Should verify ArtifactType ID |
||
| 95 | // |
||
| 96 | } else { |
||
| 97 | if (!$this->fetchData($data)) { |
||
| 98 | return false; |
||
| 99 | } |
||
| 100 | } |
||
| 101 | // |
||
| 102 | // make sure this person has permission to view this artifact |
||
| 103 | // |
||
| 104 | if ($checkPerms) { |
||
| 105 | if (!$this->userCanView()) { |
||
| 106 | $this->setError('Artifact: '.$Language->getText('tracker_common_artifact','view_private_artifact')); |
||
| 107 | return false; |
||
| 108 | } |
||
| 109 | } |
||
| 110 | } |
||
| 111 | return true; |
||
| 112 | } |
||
| 113 | |||
| 114 | |||
| 115 | /** |
||
| 116 | * fetchData - re-fetch the data for this Artifact from the database. |
||
| 117 | * |
||
| 118 | * @param int The artifact ID. |
||
| 119 | * @return boolean success. |
||
| 120 | */ |
||
| 121 | function fetchData($artifact_id) { |
||
| 122 | |||
| 123 | global $art_field_fact,$Language; |
||
| 124 | if (!$art_field_fact) { |
||
| 125 | $art_field_fact = new ArtifactFieldFactory($this->ArtifactType); |
||
| 126 | } |
||
| 127 | |||
| 128 | // first fetch values of standard fields |
||
| 129 | $sql = "SELECT * FROM artifact WHERE artifact_id='". db_ei($artifact_id) ."' AND group_artifact_id='". db_ei($this->ArtifactType->getID()) ."'"; |
||
| 130 | $res=db_query($sql); |
||
| 131 | if (!$res || db_numrows($res) < 1) { |
||
| 132 | $this->setError('Artifact: '.$Language->getText('tracker_common_artifact','invalid_id')); |
||
| 133 | return false; |
||
| 134 | } |
||
| 135 | $this->data_array = db_fetch_array($res); |
||
| 136 | db_free_result($res); |
||
| 137 | |||
| 138 | |||
| 139 | // now get the values for generic fields if any |
||
| 140 | $sql = "SELECT * FROM artifact_field_value WHERE artifact_id='". db_ei($artifact_id) ."'"; |
||
| 141 | $res=db_query($sql); |
||
| 142 | if (!$res || db_numrows($res) < 1) { |
||
| 143 | // if no result then it is possible that there isn't any generic fields |
||
| 144 | return true; |
||
| 145 | } |
||
| 146 | while ($row = db_fetch_array($res)) { |
||
| 147 | $data_fields[$row['field_id']] = $row; |
||
| 148 | } |
||
| 149 | |||
| 150 | // Get the list of all fields used by this tracker and append |
||
| 151 | // the values for these generic fields to data_array |
||
| 152 | $fields = $art_field_fact->getAllUsedFields(); |
||
| 153 | |||
| 154 | while (list($key,$field) = each($fields) ) { |
||
|
|
|||
| 155 | //echo $field->getName()."-".$field->getID()."<br>"; |
||
| 156 | // Skip! Standard field values fectched in previous query |
||
| 157 | // and comment_type_id is not stored in artifact_field_value table |
||
| 158 | if ( $field->isStandardField() || |
||
| 159 | $field->getName() == "comment_type_id") { |
||
| 160 | continue; |
||
| 161 | } |
||
| 162 | $this->data_array[$field->getName()] = $data_fields[$field->getID()][$field->getValueFieldName()]; |
||
| 163 | |||
| 164 | } |
||
| 165 | |||
| 166 | return true; |
||
| 167 | } |
||
| 168 | |||
| 169 | /** |
||
| 170 | * getArtifactType - get the ArtifactType Object this Artifact is associated with. |
||
| 171 | * |
||
| 172 | * @return object ArtifactType. |
||
| 173 | */ |
||
| 174 | function getArtifactType() { |
||
| 177 | |||
| 178 | /** |
||
| 179 | * getValue - get the value for this artifact field. |
||
| 180 | * |
||
| 181 | * @param name: the field name |
||
| 182 | * @return value |
||
| 183 | */ |
||
| 184 | function getValue($name) { |
||
| 187 | |||
| 188 | |||
| 189 | /** |
||
| 190 | * getMultiAssignedTo - get the value for the 'multi_assigned_to' field |
||
| 191 | * This function is needed because getValue() won't return an array. |
||
| 192 | * |
||
| 193 | * @return array |
||
| 194 | */ |
||
| 195 | function getMultiAssignedTo() { |
||
| 196 | $aid=$this->getID(); |
||
| 197 | if (!$aid) return; |
||
| 198 | $sql="SELECT afv.valueInt |
||
| 199 | FROM artifact_field_value afv, artifact a, artifact_field af |
||
| 200 | WHERE a.artifact_id=". db_ei($aid) ." |
||
| 201 | AND afv.artifact_id=". db_ei($aid) ." |
||
| 202 | AND a.group_artifact_id=af.group_artifact_id |
||
| 203 | AND afv.field_id=af.field_id |
||
| 204 | AND af.field_name='multi_assigned_to'"; |
||
| 205 | $res=db_query($sql); |
||
| 206 | $i=0; |
||
| 207 | $return_val = array(); |
||
| 208 | while($resrow = db_fetch_array($res)) { |
||
| 209 | $return_val[$i++]=$resrow['valueInt']; |
||
| 210 | } |
||
| 211 | return $return_val; |
||
| 212 | } |
||
| 213 | |||
| 214 | /** |
||
| 215 | * getID - get this ArtifactID. |
||
| 216 | * |
||
| 217 | * @return int The artifact_id #. |
||
| 218 | */ |
||
| 219 | function getID() { |
||
| 222 | |||
| 223 | /** |
||
| 224 | * useArtifactPermissions |
||
| 225 | * @return bool true if the artifact has individual permissions set |
||
| 226 | */ |
||
| 227 | function useArtifactPermissions() { |
||
| 230 | |||
| 231 | /** |
||
| 232 | * getStatusID - get open/closed/deleted flag. |
||
| 233 | * |
||
| 234 | * @return int Status: (1) Open, (2) Closed, (3) Deleted. |
||
| 235 | */ |
||
| 236 | function getStatusID() { |
||
| 239 | |||
| 240 | /** |
||
| 241 | * getSubmittedBy - get ID of submitter. |
||
| 242 | * |
||
| 243 | * @return int user_id of submitter. |
||
| 244 | */ |
||
| 245 | function getSubmittedBy() { |
||
| 248 | |||
| 249 | /** |
||
| 250 | * getOpenDate - get unix time of creation. |
||
| 251 | * |
||
| 252 | * @return int unix time. |
||
| 253 | */ |
||
| 254 | function getOpenDate() { |
||
| 257 | |||
| 258 | /** |
||
| 259 | * getLastUpdateDate - get unix time of last artifact update. |
||
| 260 | * |
||
| 261 | * @return int unix time. |
||
| 262 | */ |
||
| 263 | function getLastUpdateDate() { |
||
| 266 | |||
| 267 | /** |
||
| 268 | * getCloseDate - get unix time of closure. |
||
| 269 | * |
||
| 270 | * @return int unix time. |
||
| 271 | */ |
||
| 272 | function getCloseDate() { |
||
| 275 | |||
| 276 | /** |
||
| 277 | * getSummary - get text summary of artifact. |
||
| 278 | * |
||
| 279 | * @return string The summary (subject). |
||
| 280 | */ |
||
| 281 | function getSummary() { |
||
| 284 | |||
| 285 | /** |
||
| 286 | * getDetails - get text body (message) of artifact. |
||
| 287 | * |
||
| 288 | * @return string The body (message). |
||
| 289 | */ |
||
| 290 | function getDetails() { |
||
| 293 | |||
| 294 | /** |
||
| 295 | * getSeverity - get the severity of this artifact |
||
| 296 | * |
||
| 297 | * @return int |
||
| 298 | */ |
||
| 299 | function getSeverity() { |
||
| 302 | |||
| 303 | /** |
||
| 304 | * Insert an entry into the artifact_history |
||
| 305 | * |
||
| 306 | * @param field: the field object |
||
| 307 | * @param old_value: the previous value of the field |
||
| 308 | * @param new_value: the current value of the field |
||
| 309 | * @param type: extra information used to store the 'comment_type_id' field value (for the follow up comments) |
||
| 310 | * @param email: the email is the user is not logged in |
||
| 311 | * |
||
| 312 | * @return int : the artifact_history_id |
||
| 313 | */ |
||
| 314 | function addHistory ($field,$old_value,$new_value,$type=false,$email=false,$ahid=false,$comment_format=self::FORMAT_TEXT) { |
||
| 315 | //MLS: add case where we add CC and file_attachment into history for task #240 |
||
| 316 | if (!is_object($field)) { |
||
| 317 | // "cc", "attachment", "comment", etc |
||
| 318 | $name = $field; |
||
| 319 | } else { |
||
| 320 | // If field is not to be kept in bug change history then do nothing |
||
| 321 | if (!$field->getGlobalKeepHistory()) { return; } |
||
| 322 | $name = $field->getName(); |
||
| 323 | } |
||
| 324 | |||
| 325 | /* |
||
| 326 | handle the insertion of history for these parameters |
||
| 327 | */ |
||
| 328 | if ($email) { |
||
| 329 | // We use the email to identify the user |
||
| 330 | $user=100; |
||
| 331 | } else { |
||
| 332 | if ( user_isloggedin() ) { |
||
| 333 | $user=user_getid(); |
||
| 334 | } else { |
||
| 335 | $user = 100; |
||
| 336 | } |
||
| 337 | $email = ""; |
||
| 338 | } |
||
| 339 | |||
| 340 | // If type has a value add it into the sql statement (this is only for |
||
| 341 | // the follow up comments (comment field)) |
||
| 342 | $fld_type = ''; |
||
| 343 | $val_type = ''; |
||
| 344 | if ($type) { |
||
| 345 | $fld_type = ',type'; $val_type = ",'". db_ei($type) ."'"; |
||
| 346 | } else { |
||
| 347 | // No comment type specified for a followup comment |
||
| 348 | // so force it to None (100) |
||
| 349 | if ($name == 'comment' || (preg_match("/^(lbl_)/",$name) && preg_match("/(_comment)$/",$name))) { |
||
| 350 | $fld_type = ',type'; |
||
| 351 | $val_type = ",'100'"; |
||
| 352 | } |
||
| 353 | } |
||
| 354 | |||
| 355 | // Follow-up comments might have a different format |
||
| 356 | if ($comment_format != self::FORMAT_TEXT && user_isloggedin()) { |
||
| 357 | $fld_type .= ',format'; |
||
| 358 | $val_type .= ','.db_ei($comment_format); |
||
| 359 | } |
||
| 360 | |||
| 361 | $sql="insert into artifact_history(artifact_id,field_name,old_value,new_value,mod_by,email,date $fld_type) ". |
||
| 362 | "VALUES (". db_ei($this->getID()) .",'". db_es($name) ."','". db_es($old_value) ."','". db_es($new_value) ."','". db_ei($user) ."','". db_es($email) ."','".time()."' $val_type)"; |
||
| 363 | //echo $sql; |
||
| 364 | return db_query($sql); |
||
| 365 | } |
||
| 366 | |||
| 367 | |||
| 368 | /** |
||
| 369 | * Create a new artifact (and its values) in the db |
||
| 370 | * |
||
| 371 | * @param array $vfl the value-field-list. Array association pair of field_name => field_value. |
||
| 372 | * If the function is called by the web-site submission form, the $vfl is set to false, and will be filled by the function extractFieldList function retrieving the HTTP parameters. |
||
| 373 | * If $vfl is not false, the fields expected in this array are *all* the fields of this tracker that are allowed to be submited by the user. |
||
| 374 | * @return boolean |
||
| 375 | */ |
||
| 376 | function create($vfl=false,$import=false,$row=0) { |
||
| 609 | |||
| 610 | |||
| 611 | |||
| 612 | /** |
||
| 613 | * Add a followup comment |
||
| 614 | * |
||
| 615 | * @param comment: the comment |
||
| 616 | * @param email: user email if the user is not logged in |
||
| 617 | * @param changes (OUT): array of changes (for notifications) |
||
| 618 | * |
||
| 619 | * @return boolean |
||
| 620 | */ |
||
| 621 | function addComment($comment,$email=false,&$changes,$comment_format=self::FORMAT_TEXT) { |
||
| 622 | |||
| 623 | global $art_field_fact,$Language; |
||
| 624 | |||
| 625 | // Add a new comment if there is one |
||
| 626 | if ($comment != '') { |
||
| 627 | |||
| 628 | // For none project members force the comment type to None (100) |
||
| 629 | if ( !user_isloggedin() ) { |
||
| 630 | if ( $email ) { |
||
| 631 | $this->addHistory('comment', "", htmlspecialchars($comment), 100, $email, null, $comment_format); |
||
| 632 | } else { |
||
| 633 | $GLOBALS['Response']->addFeedback('error', $Language->getText('tracker_common_artifact','enter_email')); |
||
| 634 | return false; |
||
| 635 | } |
||
| 636 | } else { |
||
| 637 | $this->addHistory('comment', "", htmlspecialchars($comment), 100, null, null, $comment_format); |
||
| 638 | } |
||
| 639 | $changes['comment']['add'] = stripslashes($comment); |
||
| 640 | $changes['comment']['type'] = $Language->getText('global','none'); |
||
| 641 | |||
| 642 | $GLOBALS['Response']->addFeedback('info', $Language->getText('tracker_common_artifact','add_comment')); |
||
| 643 | return true; |
||
| 644 | } else { |
||
| 645 | return false; |
||
| 646 | } |
||
| 647 | } |
||
| 648 | |||
| 649 | |||
| 650 | /** |
||
| 651 | * handle a simple follow-up comment |
||
| 652 | * Followup comments are added in the bug history along with the comment type. |
||
| 653 | * |
||
| 654 | * If a canned response is given it overrides anything typed in the followup |
||
| 655 | * comment text area |
||
| 656 | * |
||
| 657 | * @param comment (IN) : the comment that the user typed in |
||
| 658 | * @param canned_response (IN) : the id of the canned response |
||
| 659 | */ |
||
| 660 | function addFollowUpComment($comment,$comment_type_id,$canned_response,&$changes,$comment_format=self::FORMAT_TEXT) { |
||
| 661 | global $art_field_fact,$Language; |
||
| 662 | if ($canned_response && $canned_response != 100) { |
||
| 663 | |||
| 664 | $sql="SELECT * FROM artifact_canned_responses WHERE artifact_canned_id='". db_ei($canned_response) ."'"; |
||
| 665 | $res3=db_query($sql); |
||
| 666 | |||
| 667 | if ($res3 && db_numrows($res3) > 0) { |
||
| 668 | $comment = util_unconvert_htmlspecialchars(db_result($res3,0,'body')); |
||
| 669 | $GLOBALS['Response']->addFeedback('info', $Language->getText('tracker_common_artifact','canned_used')); |
||
| 670 | } else { |
||
| 671 | $GLOBALS['Response']->addFeedback('error', $Language->getText('tracker_common_artifact','unable_canned')); |
||
| 672 | $GLOBALS['Response']->addFeedback('error', db_error()); |
||
| 673 | } |
||
| 674 | } |
||
| 675 | |||
| 676 | if ($comment != '') { |
||
| 677 | $this->addHistory('comment', '', htmlspecialchars($comment), $comment_type_id, false, false, $comment_format); |
||
| 678 | $changes['comment']['add'] = $comment; |
||
| 679 | $changes['comment']['format'] = $comment_format; |
||
| 680 | |||
| 681 | $field = $art_field_fact->getFieldFromName("comment_type_id"); |
||
| 682 | if ( $field && isset($comment_type_id) && $comment_type_id) { |
||
| 683 | $changes['comment']['type'] = |
||
| 684 | $field->getValue($this->ArtifactType->getID(), $comment_type_id); |
||
| 685 | } |
||
| 686 | $reference_manager = $this->getReferenceManager(); |
||
| 687 | $reference_manager->extractCrossRef($comment,$this->getID(), ReferenceManager::REFERENCE_NATURE_ARTIFACT, $this->ArtifactType->getGroupID()); |
||
| 688 | |||
| 689 | return true; |
||
| 690 | } else { |
||
| 691 | return false; |
||
| 692 | } |
||
| 693 | } |
||
| 694 | |||
| 695 | /** |
||
| 696 | * Wrapper for tests |
||
| 697 | * |
||
| 698 | * @return ReferenceManager |
||
| 699 | */ |
||
| 700 | function getReferenceManager() { |
||
| 703 | |||
| 704 | /** |
||
| 705 | * Add a list of follow-up comments coming from the import facility |
||
| 706 | * |
||
| 707 | * @param parsed_comments (IN): an array (#detail => array2), where array2 is of the form |
||
| 708 | * ("date" => date, "by" => user, "type" => comment-type, "comment" => comment-string) |
||
| 709 | * @return boolean |
||
| 710 | */ |
||
| 711 | function addFollowUpComments($parsed_comments) { |
||
| 712 | global $Language; |
||
| 713 | |||
| 714 | $art_field_fact = new ArtifactFieldFactory($this->ArtifactType); |
||
| 715 | $artifact_import = new ArtifactImport($this->ArtifactType, $art_field_fact, $this->ArtifactType->Group); |
||
| 716 | |||
| 717 | while (list(,$arr) = each($parsed_comments)) { |
||
| 718 | $by = $arr['by']; |
||
| 719 | if ($by == "100") { |
||
| 720 | //this case should not exist in new trackers but |
||
| 721 | //can appear if we parse legacy bugs or tasks |
||
| 722 | $email = $Language->getText('global','none'); |
||
| 723 | $user_id = 100; |
||
| 724 | } else if (user_getname($by)) { |
||
| 725 | $user_id = $by; |
||
| 726 | $email = ""; |
||
| 727 | } else { |
||
| 728 | $email = $by; |
||
| 729 | $user_id = 100; |
||
| 730 | } |
||
| 731 | |||
| 732 | if ( ! $artifact_import->checkCommentExist($arr, $this->getID())) { |
||
| 733 | if (!$artifact_import->checkCommentExistInLegacyFormat($arr, $this->getID())) { |
||
| 734 | $comment = htmlspecialchars($arr['comment']); |
||
| 735 | $sql="insert into artifact_history(artifact_id,field_name,old_value,new_value,mod_by,email,date,type) ". |
||
| 736 | "VALUES (". db_ei($this->getID()) .",'comment','','". db_es($comment) ."','". db_ei($user_id) ."','". db_es($email) ."','". db_ei($arr['date']) ."','". db_ei($arr['type']) ."')"; |
||
| 737 | |||
| 738 | db_query($sql); |
||
| 739 | } |
||
| 740 | } |
||
| 741 | |||
| 742 | } |
||
| 743 | |||
| 744 | |||
| 745 | return true; |
||
| 746 | } |
||
| 747 | |||
| 748 | /** |
||
| 749 | * Update a follow-up comment |
||
| 750 | * |
||
| 751 | * @param comment_id: follow-up comment id |
||
| 752 | * @param comment_txt: text of the follow-up comment |
||
| 753 | * |
||
| 754 | * @return boolean |
||
| 755 | */ |
||
| 756 | function updateFollowupComment($comment_id,$comment_txt,&$changes, $comment_format=self::FORMAT_TEXT) { |
||
| 757 | if ($this->userCanEditFollowupComment($comment_id)) { |
||
| 758 | $sql = 'SELECT field_name, new_value, type FROM artifact_history' |
||
| 759 | .' WHERE artifact_id='. db_ei($this->getID()) |
||
| 760 | .' AND artifact_history_id='. db_ei($comment_id) |
||
| 761 | .' AND (field_name="comment" OR field_name LIKE "lbl_%_comment")'; |
||
| 762 | $qry = db_query($sql); |
||
| 763 | $new_value = db_result($qry,0,'new_value'); |
||
| 764 | $comment_type_id = db_result($qry,0,'type'); |
||
| 765 | if ($new_value == $comment_txt) { |
||
| 766 | //comment doesn't change |
||
| 767 | return false; |
||
| 768 | } |
||
| 769 | |||
| 770 | if ($qry) { |
||
| 771 | $fname = db_result($qry,0,'field_name'); |
||
| 772 | if (preg_match("/^(lbl_)/",$fname) && preg_match("/(_comment)$/",$fname)) { |
||
| 773 | $comment_lbl = $fname; |
||
| 774 | } else { |
||
| 775 | $comment_lbl = "lbl_".$comment_id."_comment"; |
||
| 776 | } |
||
| 777 | //now add new comment entry |
||
| 778 | $this->addHistory($comment_lbl,$new_value,htmlspecialchars($comment_txt), $comment_type_id,false,$comment_id,$comment_format); |
||
| 779 | $changes['comment']['del'] = $new_value; |
||
| 780 | $changes['comment']['add'] = $comment_txt; |
||
| 781 | $changes['comment']['format'] = $comment_format; |
||
| 782 | $reference_manager = $this->getReferenceManager(); |
||
| 783 | $reference_manager->extractCrossRef($comment_txt,$this->getID(),ReferenceManager::REFERENCE_NATURE_ARTIFACT,$this->ArtifactType->getGroupID()); |
||
| 784 | |||
| 785 | return true; |
||
| 786 | } else { |
||
| 787 | return false; |
||
| 788 | } |
||
| 789 | } else { |
||
| 790 | $this->setError($GLOBALS['Language']->getText('tracker_common_artifact','err_upd_comment', array($comment_id, $GLOBALS['Language']->getText('include_exit','perm_denied')))); |
||
| 791 | $GLOBALS['Response']->addFeedback('error',$GLOBALS['Language']->getText('tracker_common_artifact','err_upd_comment', array($comment_id, $GLOBALS['Language']->getText('include_exit','perm_denied')))); |
||
| 792 | return false; |
||
| 793 | } |
||
| 794 | |||
| 795 | } |
||
| 796 | |||
| 797 | /** |
||
| 798 | * Update an artifact. Rk: vfl is an variable list of fields, Vary from one project to another |
||
| 799 | * return true if artifact updated, false if nothing changed or DB update failed |
||
| 800 | * |
||
| 801 | * @param artifact_id_dependent: artifact dependencies |
||
| 802 | * @param canned_response: canned responses |
||
| 803 | * @param changes (OUT): array of changes (for notifications) |
||
| 804 | * |
||
| 805 | * @return boolean |
||
| 806 | */ |
||
| 807 | function handleUpdate ($artifact_id_dependent,$canned_response,&$changes,$masschange=false,$vfl=false,$import=false){ |
||
| 1109 | |||
| 1110 | /** |
||
| 1111 | * Set the permissions |
||
| 1112 | */ |
||
| 1113 | function setPermissions($use_artifact_permissions, $ugroups) { |
||
| 1114 | if ($this->ArtifactType->userIsAdmin()) { |
||
| 1115 | if ($use_artifact_permissions) { |
||
| 1116 | $result = permission_process_selection_form($this->ArtifactType->getGroupID(), 'TRACKER_ARTIFACT_ACCESS', $this->getId(), $ugroups); |
||
| 1117 | if (!$result[0]) { |
||
| 1118 | return $GLOBALS['Response']->addFeedback('error', $result[1]); |
||
| 1119 | } |
||
| 1120 | //If the selected ugroup corresponds to the default one (all_user), there is no need to store it |
||
| 1121 | if ($ugroups[0] == $GLOBALS['UGROUP_ANONYMOUS']) { |
||
| 1122 | $use_artifact_permissions = 0; |
||
| 1123 | } |
||
| 1124 | } |
||
| 1125 | $sql = "UPDATE artifact |
||
| 1126 | SET use_artifact_permissions = ". ($use_artifact_permissions ? 1 : 0) ." |
||
| 1127 | WHERE artifact_id=". db_ei($this->getID()); |
||
| 1128 | db_query($sql); |
||
| 1129 | |||
| 1130 | } |
||
| 1131 | } |
||
| 1132 | |||
| 1133 | |||
| 1134 | /** |
||
| 1135 | * Check if an email address already exists |
||
| 1136 | * |
||
| 1137 | * @param cc: the email address |
||
| 1138 | * |
||
| 1139 | * @return boolean |
||
| 1140 | */ |
||
| 1141 | function existCC($cc) { |
||
| 1142 | $sql = "SELECT artifact_cc_id FROM artifact_cc WHERE artifact_id=". db_ei($this->getID()) ." AND email='". db_es($cc) ."'"; |
||
| 1143 | $res = db_query($sql); |
||
| 1144 | return (db_numrows($res) >= 1); |
||
| 1145 | } |
||
| 1146 | |||
| 1147 | /** |
||
| 1148 | * Insert an email address for the CC list |
||
| 1149 | * |
||
| 1150 | * @param cc: the email address |
||
| 1151 | * @param added_by: user who insert this cc list |
||
| 1152 | * @param comment: comment for this cc list |
||
| 1153 | * @param date: date of creation |
||
| 1154 | * |
||
| 1155 | * @return boolean |
||
| 1156 | */ |
||
| 1157 | function insertCC($cc,$added_by,$comment,$date) { |
||
| 1158 | $sql = "INSERT INTO artifact_cc (artifact_id,email,added_by,comment,date) ". |
||
| 1159 | "VALUES (". db_ei($this->getID()) .",'". db_es($cc) ."','". db_ei($added_by) ."','". db_es($comment) ."','". db_ei($date) ."')"; |
||
| 1160 | $res = db_query($sql); |
||
| 1161 | return ($res); |
||
| 1162 | |||
| 1163 | } |
||
| 1164 | |||
| 1165 | /** |
||
| 1166 | * Insert email addresses for CC list |
||
| 1167 | * |
||
| 1168 | * @param email: list of email addresses |
||
| 1169 | * @param comment: comment for these addresses |
||
| 1170 | * @param changes (OUT): list of changes |
||
| 1171 | * @param masschange: if in a masschange, we do not wan't to get feedback when everything ok |
||
| 1172 | * |
||
| 1173 | * @return boolean |
||
| 1174 | */ |
||
| 1175 | function addCC($email,$comment,&$changes,$masschange=false) { |
||
| 1176 | global $Language; |
||
| 1177 | |||
| 1178 | $user_id = (user_isloggedin() ? user_getid(): 100); |
||
| 1179 | |||
| 1180 | $arr_email = util_split_emails($email); |
||
| 1181 | $date = time(); |
||
| 1182 | $ok = true; |
||
| 1183 | $changed = false; |
||
| 1184 | |||
| 1185 | if (! util_validateCCList($arr_email, $message)) { |
||
| 1186 | exit_error($Language->getText('tracker_index','cc_list_invalid'), $message); |
||
| 1187 | } |
||
| 1188 | |||
| 1189 | //calculate old_values to put into artifact_history |
||
| 1190 | $old_value=$this->getCCEmails(); |
||
| 1191 | reset($arr_email); |
||
| 1192 | while (list(,$cc) = each($arr_email)) { |
||
| 1193 | // Add this cc only if not there already |
||
| 1194 | if (!$this->existCC($cc)) { |
||
| 1195 | $changed = true; |
||
| 1196 | $res = $this->insertCC($cc,$user_id,$comment,$date); |
||
| 1197 | if (!$res) { $ok = false; } |
||
| 1198 | } |
||
| 1199 | } |
||
| 1200 | |||
| 1201 | if ($old_value == '') { |
||
| 1202 | $new_value = join(',', $arr_email); |
||
| 1203 | } else { |
||
| 1204 | $new_value = $old_value .",".join(',', $arr_email); |
||
| 1205 | } |
||
| 1206 | |||
| 1207 | if (!$ok) { |
||
| 1208 | $GLOBALS['Response']->addFeedback('error', $Language->getText('tracker_common_artifact','cc_add_fail')); |
||
| 1209 | } else { |
||
| 1210 | $this->addHistory('cc',$old_value,$new_value); |
||
| 1211 | $changes['CC']['add'] = join(',', $arr_email); |
||
| 1212 | } |
||
| 1213 | return $ok; |
||
| 1214 | } |
||
| 1215 | |||
| 1216 | /** |
||
| 1217 | * Delete old cc list and add new email instead |
||
| 1218 | * |
||
| 1219 | * @param email: list of email addresses |
||
| 1220 | * @param comment: comment for these addresses |
||
| 1221 | * |
||
| 1222 | * @return boolean |
||
| 1223 | */ |
||
| 1224 | function updateCC($email,$comment) { |
||
| 1225 | global $Language; |
||
| 1226 | |||
| 1227 | $user_id = (user_isloggedin() ? user_getid(): 100); |
||
| 1228 | |||
| 1229 | $arr_email = util_split_emails($email); |
||
| 1230 | $date = time(); |
||
| 1231 | $ok = true; |
||
| 1232 | $changed = false; |
||
| 1233 | |||
| 1234 | if (! util_validateCCList($arr_email, $message)) { |
||
| 1235 | exit_error($Language->getText('tracker_index','cc_list_invalid'), $message); |
||
| 1236 | } |
||
| 1237 | |||
| 1238 | //calculate old_values to put into artifact_history |
||
| 1239 | $old_value=$this->getCCEmails(); |
||
| 1240 | $new_value = join(',', $arr_email); |
||
| 1241 | |||
| 1242 | //look if there is really something to do or not |
||
| 1243 | list($deleted_values,$added_values) = util_double_diff_array(explode(",",$old_value),$arr_email); |
||
| 1244 | if (count($deleted_values) == 0 && count($added_values) == 0) return true; |
||
| 1245 | |||
| 1246 | if (!$this->deleteAllCC()) { |
||
| 1247 | $GLOBALS['Response']->addFeedback('error', $Language->getText('tracker_common_artifact','prob_cc_list',$this->getID())); |
||
| 1248 | $ok = false; |
||
| 1249 | } |
||
| 1250 | |||
| 1251 | reset($arr_email); |
||
| 1252 | while (list(,$cc) = each($arr_email)) { |
||
| 1253 | $changed = true; |
||
| 1254 | $res = $this->insertCC($cc,$user_id,$comment,$date); |
||
| 1255 | if (!$res) { $ok = false; } |
||
| 1256 | } |
||
| 1257 | |||
| 1258 | if (!$ok) { |
||
| 1259 | $GLOBALS['Response']->addFeedback('error', $Language->getText('tracker_common_artifact','cc_add_fail')); |
||
| 1260 | } else { |
||
| 1261 | $this->addHistory('cc',$old_value,$new_value); |
||
| 1262 | } |
||
| 1263 | return $ok; |
||
| 1264 | } |
||
| 1265 | |||
| 1266 | |||
| 1267 | |||
| 1268 | /** |
||
| 1269 | * Delete an email address in the CC list |
||
| 1270 | * |
||
| 1271 | * @param artifact_cc_id: cc list id |
||
| 1272 | * @param changes (OUT): list of changes |
||
| 1273 | * |
||
| 1274 | * @return boolean |
||
| 1275 | */ |
||
| 1276 | function deleteCC($artifact_cc_id=false,&$changes,$masschange=false) { |
||
| 1277 | global $Language; |
||
| 1278 | |||
| 1279 | // If both bug_id and bug_cc_id are given make sure the cc belongs |
||
| 1280 | // to this bug (it's a bit paranoid but...) |
||
| 1281 | $sql = "SELECT artifact_id,email from artifact_cc WHERE artifact_cc_id='". db_ei($artifact_cc_id) ."'"; |
||
| 1282 | $res1 = db_query($sql); |
||
| 1283 | if ((db_numrows($res1) <= 0) || (db_result($res1,0,'artifact_id') != $this->getID()) ) { |
||
| 1284 | $GLOBALS['Response']->addFeedback('error', $Language->getText('tracker_common_artifact','err_cc_id',$artifact_cc_id)); |
||
| 1285 | return false; |
||
| 1286 | } |
||
| 1287 | |||
| 1288 | //calculate old_values to put into artifact_history |
||
| 1289 | $old_value=$this->getCCEmails(); |
||
| 1290 | |||
| 1291 | // Now delete the CC address |
||
| 1292 | $res2 = db_query("DELETE FROM artifact_cc WHERE artifact_cc_id='". db_ei($artifact_cc_id) ."'"); |
||
| 1293 | if (!$res2) { |
||
| 1294 | $GLOBALS['Response']->addFeedback('error', $Language->getText('tracker_common_artifact','err_del_cc',array($artifact_cc_id,db_error($res2)))); |
||
| 1295 | return false; |
||
| 1296 | } else { |
||
| 1297 | if (!$masschange) $GLOBALS['Response']->addFeedback('info', $Language->getText('tracker_common_artifact','cc_remove')); |
||
| 1298 | $new_value=$this->getCCEmails(); |
||
| 1299 | $this->addHistory('cc',$old_value,$new_value); |
||
| 1300 | $changes['CC']['del'] = db_result($res1,0,'email'); |
||
| 1301 | return true; |
||
| 1302 | } |
||
| 1303 | } |
||
| 1304 | |||
| 1305 | /** |
||
| 1306 | * Check if an artifact depends already from the current one |
||
| 1307 | * |
||
| 1308 | * @param id: the artifact id |
||
| 1309 | * |
||
| 1310 | * @return boolean |
||
| 1311 | */ |
||
| 1312 | function existDependency($id) { |
||
| 1313 | $sql = "SELECT is_dependent_on_artifact_id FROM artifact_dependencies WHERE artifact_id=". db_ei($this->getID()) ." AND is_dependent_on_artifact_id=". db_ei($id); |
||
| 1314 | //echo $sql; |
||
| 1315 | $res = db_query($sql); |
||
| 1316 | return (db_numrows($res) >= 1); |
||
| 1317 | } |
||
| 1318 | |||
| 1319 | /** |
||
| 1320 | * Check if an artifact exists |
||
| 1321 | * |
||
| 1322 | * @param id: the artifact id |
||
| 1323 | * |
||
| 1324 | * @return boolean |
||
| 1325 | */ |
||
| 1326 | function validArtifact($id) { |
||
| 1327 | $sql = "SELECT * FROM artifact a, artifact_group_list agl WHERE ". |
||
| 1328 | "a.group_artifact_id = agl.group_artifact_id AND a.artifact_id=". db_ei($id) ." AND ". |
||
| 1329 | "agl.status = 'A'"; |
||
| 1330 | $res = db_query($sql); |
||
| 1331 | if ( db_numrows($res) >= 1 ) |
||
| 1332 | return true; |
||
| 1333 | else |
||
| 1334 | return false; |
||
| 1335 | } |
||
| 1336 | |||
| 1337 | |||
| 1338 | /** |
||
| 1339 | * Insert a artifact dependency with the current one |
||
| 1340 | * |
||
| 1341 | * @param id: the artifact id |
||
| 1342 | * |
||
| 1343 | * @return boolean |
||
| 1344 | */ |
||
| 1345 | function insertDependency($id) { |
||
| 1346 | $sql = "INSERT INTO artifact_dependencies (artifact_id,is_dependent_on_artifact_id) ". |
||
| 1347 | "VALUES (". db_ei($this->getID()) .",". db_ei($id) .")"; |
||
| 1348 | //echo $sql; |
||
| 1349 | $res = db_query($sql); |
||
| 1350 | return ($res); |
||
| 1351 | |||
| 1352 | } |
||
| 1353 | |||
| 1354 | |||
| 1355 | /** |
||
| 1356 | * Delete all the CC Names of this Artifact |
||
| 1357 | */ |
||
| 1358 | function deleteAllCC() { |
||
| 1359 | $sql = "SELECT artifact_cc_id FROM artifact_cc WHERE artifact_id=". db_ei($this->getID()) ; |
||
| 1360 | $res = db_query($sql); |
||
| 1361 | if (db_numrows($res) > 0) { |
||
| 1362 | for ($i=0;$i<db_numrows($res);$i++) { |
||
| 1363 | if ($i==0) $ccNames = db_result($res,$i,'artifact_cc_id'); |
||
| 1364 | else $ccNames .= ",".db_result($res,$i,'artifact_cc_id'); |
||
| 1365 | } |
||
| 1366 | $sql = "DELETE FROM artifact_cc WHERE artifact_cc_id IN (". db_es($ccNames) .") AND artifact_id=". db_ei($this->getID()) ; |
||
| 1367 | $res_del = db_query($sql); |
||
| 1368 | if (!$res_del) return false; |
||
| 1369 | } |
||
| 1370 | return true; |
||
| 1371 | } |
||
| 1372 | |||
| 1373 | /** |
||
| 1374 | * Delete all the dependencies of this Artifact |
||
| 1375 | */ |
||
| 1376 | function deleteAllDependencies() { |
||
| 1377 | $sql = "SELECT is_dependent_on_artifact_id FROM artifact_dependencies WHERE artifact_id=". db_ei($this->getID()) ; |
||
| 1378 | $res = db_query($sql); |
||
| 1379 | if (db_numrows($res) > 0) { |
||
| 1380 | for ($i=0;$i<db_numrows($res);$i++) { |
||
| 1381 | if ($i==0) $dependencies = db_result($res,$i,'is_dependent_on_artifact_id'); |
||
| 1382 | else $dependencies .= ",".db_result($res,$i,'is_dependent_on_artifact_id'); |
||
| 1383 | } |
||
| 1384 | $sql = "DELETE FROM artifact_dependencies WHERE is_dependent_on_artifact_id IN (". db_es($dependencies) .") AND artifact_id=". db_ei($this->getID()) ; |
||
| 1385 | $res_del = db_query($sql); |
||
| 1386 | if (!$res_del) return false; |
||
| 1387 | } |
||
| 1388 | return true; |
||
| 1389 | } |
||
| 1390 | |||
| 1391 | |||
| 1392 | /** |
||
| 1393 | * Insert artifact dependencies |
||
| 1394 | * |
||
| 1395 | * @param artifact_id_dependent: list of artifact which are depend on (comma sperator) |
||
| 1396 | * @param changes (OUT): list of changes |
||
| 1397 | * |
||
| 1398 | * @return boolean |
||
| 1399 | */ |
||
| 1400 | function addDependencies($artifact_id_dependent,&$changes,$masschange, $import = false) { |
||
| 1401 | if ( !$artifact_id_dependent ) |
||
| 1402 | return true; |
||
| 1403 | |||
| 1404 | $ok = true; |
||
| 1405 | $ids = explode(",",$artifact_id_dependent); |
||
| 1406 | while (list(,$id) = each($ids)) { |
||
| 1407 | // Add this id only if not already exist |
||
| 1408 | //echo "add id=".$id."<br>"; |
||
| 1409 | |||
| 1410 | // Remove potential spaces (if the list of IDs are entered like that : 171, 765, 555) |
||
| 1411 | $id = trim($id); |
||
| 1412 | |||
| 1413 | // Check existance |
||
| 1414 | if (!$this->validArtifact($id)) { |
||
| 1415 | |||
| 1416 | // at import stage, $id can have value "None" or "Aucun" |
||
| 1417 | if ( ! $import || $id != $GLOBALS['Language']->getText('global','none')) { |
||
| 1418 | $ok = false; |
||
| 1419 | $GLOBALS['Response']->addFeedback('error', $GLOBALS['Language']->getText('tracker_common_artifact','invalid_art',$id)); |
||
| 1420 | } |
||
| 1421 | } |
||
| 1422 | if ($ok && ($id != $this->getID()) && !$this->existDependency($id)) { |
||
| 1423 | $res = $this->insertDependency($id); |
||
| 1424 | if (!$res) { $ok = false; } |
||
| 1425 | } |
||
| 1426 | } |
||
| 1427 | |||
| 1428 | if (!$ok) { |
||
| 1429 | $GLOBALS['Response']->addFeedback('error', $GLOBALS['Language']->getText('tracker_common_artifact','depend_add_fail',$this->getID())); |
||
| 1430 | } else { |
||
| 1431 | $changes['Dependencies']['add'] = $artifact_id_dependent; |
||
| 1432 | } |
||
| 1433 | return $ok; |
||
| 1434 | } |
||
| 1435 | |||
| 1436 | /** |
||
| 1437 | * Delete an artifact id from the dependencies list |
||
| 1438 | * |
||
| 1439 | * @param dependent_on_artifact_id: artifact id which is depend on |
||
| 1440 | * @param changes (OUT): list of changes |
||
| 1441 | * |
||
| 1442 | * @return boolean |
||
| 1443 | */ |
||
| 1444 | function deleteDependency($dependent_on_artifact_id,&$changes) { |
||
| 1445 | global $Language; |
||
| 1446 | |||
| 1447 | // Delete the dependency |
||
| 1448 | $sql = "DELETE FROM artifact_dependencies WHERE is_dependent_on_artifact_id=". db_ei($dependent_on_artifact_id) ." AND artifact_id=". db_ei($this->getID()) ; |
||
| 1449 | $res2 = db_query($sql); |
||
| 1450 | if (!$res2) { |
||
| 1451 | $GLOBALS['Response']->addFeedback('error', " - Error deleting dependency $dependent_on_artifact_id: ".db_error($res2)); |
||
| 1452 | return false; |
||
| 1453 | } else { |
||
| 1454 | $GLOBALS['Response']->addFeedback('info', $Language->getText('tracker_common_artifact','depend_removed')); |
||
| 1455 | $changes['Dependencies']['del'] = $dependent_on_artifact_id; |
||
| 1456 | return true; |
||
| 1457 | } |
||
| 1458 | } |
||
| 1459 | |||
| 1460 | /** |
||
| 1461 | * Delete a followup comment from the artifact |
||
| 1462 | * |
||
| 1463 | * @param aid: the artifact id |
||
| 1464 | * @param comment_id: the followup comment id |
||
| 1465 | * |
||
| 1466 | * @return boolean |
||
| 1467 | */ |
||
| 1468 | function deleteFollowupComment($aid,$comment_id) { |
||
| 1469 | if ($this->userCanEditFollowupComment($comment_id)) { |
||
| 1470 | //Delete the followup comment |
||
| 1471 | $sel = 'SELECT field_name, new_value FROM artifact_history' |
||
| 1472 | .' WHERE (field_name = "comment" OR field_name LIKE "lbl_%_comment")' |
||
| 1473 | .' AND artifact_history_id = '. db_ei($comment_id) |
||
| 1474 | .' AND artifact_id = '. db_ei($aid) ; |
||
| 1475 | $res = db_query($sel); |
||
| 1476 | $new_value = db_result($res,0,'new_value'); |
||
| 1477 | if ($res) { |
||
| 1478 | $fname = db_result($res,0,'field_name'); |
||
| 1479 | if (preg_match("/^(lbl_)/",$fname) && preg_match("/(_comment)$/",$fname)) { |
||
| 1480 | $comment_lbl = $fname; |
||
| 1481 | } else { |
||
| 1482 | $comment_lbl = "lbl_".$comment_id."_comment"; |
||
| 1483 | } |
||
| 1484 | //now add a new history entry |
||
| 1485 | $this->addHistory($comment_lbl,$new_value,'',false,false,$comment_id); |
||
| 1486 | $GLOBALS['Response']->addFeedback('info',$GLOBALS['Language']->getText('tracker_common_artifact','comment_removed')); |
||
| 1487 | return true; |
||
| 1488 | } else { |
||
| 1489 | $GLOBALS['Response']->addFeedback('error',$GLOBALS['Language']->getText('tracker_common_artifact','err_del_comment',array($comment_id,db_error($res)))); |
||
| 1490 | return false; |
||
| 1491 | } |
||
| 1492 | } else { |
||
| 1493 | $this->setError($GLOBALS['Language']->getText('tracker_common_artifact','err_del_comment', array($comment_id, $GLOBALS['Language']->getText('include_exit','perm_denied')))); |
||
| 1494 | $GLOBALS['Response']->addFeedback('error',$GLOBALS['Language']->getText('tracker_common_artifact','err_del_comment', array($comment_id, $GLOBALS['Language']->getText('include_exit','perm_denied')))); |
||
| 1495 | return false; |
||
| 1496 | } |
||
| 1497 | |||
| 1498 | } |
||
| 1499 | |||
| 1500 | /** |
||
| 1501 | * Return if the status is closed status |
||
| 1502 | * |
||
| 1503 | * @param status: the status |
||
| 1504 | * |
||
| 1505 | * @return boolean |
||
| 1506 | */ |
||
| 1507 | function isStatusClosed($status) { |
||
| 1510 | |||
| 1511 | |||
| 1512 | /** |
||
| 1513 | * get all the field values for this artifact |
||
| 1514 | * |
||
| 1515 | * @return array |
||
| 1516 | */ |
||
| 1517 | function getFieldsValues() { |
||
| 1518 | |||
| 1519 | // get the artifact data |
||
| 1520 | $this->fetchData($this->getID()); |
||
| 1521 | return $this->data_array; |
||
| 1522 | } |
||
| 1523 | |||
| 1524 | /** |
||
| 1525 | * Return the user (user_id) that have posted follow up (comment_id) |
||
| 1526 | * |
||
| 1527 | * @return int |
||
| 1528 | */ |
||
| 1529 | function getCommenter($comment_id) { |
||
| 1530 | |||
| 1531 | $sql = 'SELECT mod_by FROM artifact_history' |
||
| 1532 | .' WHERE artifact_id='. db_ei($this->getID()) |
||
| 1533 | .' AND field_name="comment"' |
||
| 1534 | .' AND mod_by != 100' |
||
| 1535 | .' AND artifact_history_id='. db_ei($comment_id); |
||
| 1536 | $res = db_query($sql); |
||
| 1537 | return db_result($res,0,'mod_by'); |
||
| 1538 | |||
| 1539 | } |
||
| 1540 | |||
| 1541 | /** |
||
| 1542 | * Return the users that have posted follow ups |
||
| 1543 | * |
||
| 1544 | * @return array |
||
| 1545 | */ |
||
| 1546 | function getCommenters() { |
||
| 1547 | $sql="SELECT DISTINCT mod_by FROM artifact_history ". |
||
| 1548 | "WHERE artifact_id=". db_ei($this->getID()) ." ". |
||
| 1549 | "AND field_name = 'comment' AND mod_by != 100"; |
||
| 1550 | return db_query($sql); |
||
| 1551 | } |
||
| 1552 | |||
| 1553 | /** |
||
| 1554 | * Return the mails of anonymous users that have posted follow ups |
||
| 1555 | * |
||
| 1556 | * @return array |
||
| 1557 | */ |
||
| 1558 | function getAnonymousCommenters() { |
||
| 1559 | $sql="SELECT DISTINCT email FROM artifact_history ". |
||
| 1560 | "WHERE artifact_id=". db_ei($this->getID()) ." ". |
||
| 1561 | "AND field_name = 'comment' ". |
||
| 1562 | "AND mod_by = 100"; |
||
| 1563 | return db_query($sql); |
||
| 1564 | } |
||
| 1565 | |||
| 1566 | /** |
||
| 1567 | * Get follow-up comment text |
||
| 1568 | * |
||
| 1569 | * @param Integer $comment_id |
||
| 1570 | * |
||
| 1571 | * @return String |
||
| 1572 | */ |
||
| 1573 | function getFollowup($comment_id) { |
||
| 1577 | |||
| 1578 | /** |
||
| 1579 | * Get all details of a follow-up comment |
||
| 1580 | * |
||
| 1581 | * @param Integer $comment_id |
||
| 1582 | * |
||
| 1583 | * @return Array |
||
| 1584 | */ |
||
| 1585 | function getFollowUpDetails($comment_id) { |
||
| 1596 | |||
| 1597 | /** |
||
| 1598 | * Return the follow ups |
||
| 1599 | * |
||
| 1600 | * @return array |
||
| 1601 | */ |
||
| 1602 | function getFollowups () { |
||
| 1603 | global $art_field_fact; |
||
| 1604 | |||
| 1605 | $flup_array = array(); |
||
| 1606 | $qry = 'SELECT artifact_history_id, date FROM artifact_history'. |
||
| 1607 | ' WHERE artifact_id = '. db_ei($this->getID()) . |
||
| 1608 | ' AND field_name = "comment"'; |
||
| 1609 | $res = db_query($qry); |
||
| 1610 | while ($row = db_fetch_array($res)) { |
||
| 1611 | $ahid = $row['artifact_history_id']; |
||
| 1612 | $fname = "lbl_".$ahid."_comment"; |
||
| 1613 | $sel = 'SELECT NULL FROM artifact_history'. |
||
| 1614 | ' WHERE field_name = "'. db_es($fname) .'"'. |
||
| 1615 | ' AND artifact_id = '. db_ei($this->getID()) ; |
||
| 1616 | $result = db_query($sel); |
||
| 1617 | if (db_numrows($result) < 1) { |
||
| 1618 | //the followup comment was not edited/removed ==> add it to the list of comments to be displayed |
||
| 1619 | $flup_array[$ahid] = $row['date']; |
||
| 1620 | } else { |
||
| 1621 | //pick the latest |
||
| 1622 | $latest = 'SELECT artifact_history_id , new_value FROM artifact_history'. |
||
| 1623 | ' WHERE field_name = "'. db_es($fname) .'"'. |
||
| 1624 | ' AND artifact_id = '. db_ei($this->getID()) . |
||
| 1625 | ' AND date = (SELECT MAX(date) FROM artifact_history'. |
||
| 1626 | ' WHERE field_name = "'. db_es($fname) .'"'. |
||
| 1627 | ' AND artifact_id = '. db_ei($this->getID()) .')'; |
||
| 1628 | $res_latest = db_query($latest); |
||
| 1629 | $new_value = db_result($res_latest,0,'new_value'); |
||
| 1630 | if ($new_value <> '') { |
||
| 1631 | //if new_value eq '' ==> the followup comment was removed, don't display it |
||
| 1632 | $art_hist_id = db_result($res_latest,0,'artifact_history_id'); |
||
| 1633 | $flup_array[$art_hist_id] = $row['date']; |
||
| 1634 | } |
||
| 1635 | } |
||
| 1636 | } |
||
| 1637 | arsort($flup_array); |
||
| 1638 | $comment_array = array_keys($flup_array); |
||
| 1639 | |||
| 1640 | $field = $art_field_fact->getFieldFromName('comment_type_id'); |
||
| 1641 | if ( $field ) { |
||
| 1642 | // Look for project specific values first |
||
| 1643 | $sql="SELECT DISTINCT artifact_history.artifact_history_id, artifact_history.format, artifact_history.artifact_id,artifact_history.field_name,artifact_history.old_value,artifact_history.new_value,artifact_history.date,user.user_name,artifact_history.mod_by,artifact_history.email,artifact_history.type AS comment_type_id,artifact_field_value_list.value AS comment_type ". |
||
| 1644 | "FROM artifact_history,artifact_field_value_list,artifact_field,user ". |
||
| 1645 | "WHERE artifact_history.artifact_id=". db_ei($this->getID()) ." ". |
||
| 1646 | "AND (artifact_history.field_name = 'comment' OR artifact_history.field_name LIKE 'lbl_%_comment') ". |
||
| 1647 | "AND artifact_history.mod_by=user.user_id ". |
||
| 1648 | "AND artifact_history.type = artifact_field_value_list.value_id ". |
||
| 1649 | "AND artifact_history.artifact_history_id IN (". db_es(implode(',',$comment_array)) .") ". |
||
| 1650 | "AND artifact_field_value_list.field_id = artifact_field.field_id ". |
||
| 1651 | "AND artifact_field_value_list.group_artifact_id = artifact_field.group_artifact_id ". |
||
| 1652 | "AND artifact_field.group_artifact_id =". db_ei($this->ArtifactType->getID()) ." ". |
||
| 1653 | "AND artifact_field.field_name = 'comment_type_id' ". |
||
| 1654 | "ORDER BY FIELD(artifact_history_id, ". db_es(implode(',',$comment_array)) .")"; |
||
| 1655 | $res_value = db_query($sql); |
||
| 1656 | $rows=db_numrows($res_value); |
||
| 1657 | |||
| 1658 | //echo "sql=".$sql." - rows=".$rows."<br>"; |
||
| 1659 | } else { |
||
| 1660 | // Look for project specific values first |
||
| 1661 | $sql="SELECT DISTINCT artifact_history.artifact_history_id, artifact_history.format, artifact_history.artifact_id,artifact_history.field_name,artifact_history.old_value,artifact_history.new_value,artifact_history.date,user.user_name,artifact_history.mod_by,artifact_history.email,artifact_history.type AS comment_type_id,null AS comment_type ". |
||
| 1662 | "FROM artifact_history,user ". |
||
| 1663 | "WHERE artifact_history.artifact_id=".$this->getID()." ". |
||
| 1664 | "AND (artifact_history.field_name = 'comment' OR artifact_history.field_name LIKE 'lbl_%_comment') ". |
||
| 1665 | "AND artifact_history.mod_by=user.user_id ". |
||
| 1666 | "AND artifact_history.artifact_history_id IN (". db_es(implode(',',$comment_array)) .") ". |
||
| 1667 | "ORDER BY FIELD(artifact_history_id, ". db_es(implode(',',$comment_array)) .")"; |
||
| 1668 | $res_value = db_query($sql); |
||
| 1669 | $rows=db_numrows($res_value); |
||
| 1670 | |||
| 1671 | } |
||
| 1672 | return($res_value); |
||
| 1673 | |||
| 1674 | } |
||
| 1675 | |||
| 1676 | /** |
||
| 1677 | * Return the history events for this artifact (excluded comment events - See followups) |
||
| 1678 | * |
||
| 1679 | * @return array |
||
| 1680 | */ |
||
| 1681 | function getHistory () { |
||
| 1682 | |||
| 1683 | //Addition of new followup comments is not recorded in history (update and removal of followups is recorded) |
||
| 1684 | $sql="SELECT artifact_history.field_name,artifact_history.old_value,artifact_history.new_value,artifact_history.date,artifact_history.type,user.user_name ". |
||
| 1685 | "FROM artifact_history,user ". |
||
| 1686 | "WHERE artifact_history.mod_by=user.user_id ". |
||
| 1687 | "AND artifact_id=". db_ei($this->getID()) . |
||
| 1688 | " AND artifact_history.field_name <> 'comment' ". |
||
| 1689 | "ORDER BY artifact_history.date DESC"; |
||
| 1690 | return db_query($sql); |
||
| 1691 | } |
||
| 1692 | |||
| 1693 | /** |
||
| 1694 | * Return the CC list values |
||
| 1695 | * |
||
| 1696 | * @return array |
||
| 1697 | */ |
||
| 1698 | function getCCList() { |
||
| 1699 | |||
| 1700 | $sql="SELECT artifact_cc_id,artifact_cc.email,artifact_cc.added_by,artifact_cc.comment,artifact_cc.date,user.user_name ". |
||
| 1701 | "FROM artifact_cc,user ". |
||
| 1702 | "WHERE added_by=user.user_id ". |
||
| 1703 | "AND artifact_id=". db_ei($this->getID()) ." ORDER BY date DESC"; |
||
| 1704 | return db_query($sql); |
||
| 1705 | } |
||
| 1706 | |||
| 1707 | /** |
||
| 1708 | * Return the user ids of registered users in the CC list |
||
| 1709 | * |
||
| 1710 | * @return array |
||
| 1711 | */ |
||
| 1712 | function getCCIdList() { |
||
| 1713 | |||
| 1714 | $sql="SELECT u.user_id ". |
||
| 1715 | "FROM artifact_cc cc, user u ". |
||
| 1716 | "WHERE cc.email = u.user_name ". |
||
| 1717 | "AND cc.artifact_id=". db_ei($this->getID()) ; |
||
| 1718 | $res = db_query($sql); |
||
| 1719 | |||
| 1720 | return util_result_column_to_array($res); |
||
| 1721 | } |
||
| 1722 | |||
| 1723 | /** |
||
| 1724 | * Return the CC list emails only |
||
| 1725 | * |
||
| 1726 | * @return string |
||
| 1727 | */ |
||
| 1728 | function getCCEmails() { |
||
| 1729 | |||
| 1730 | $sql="SELECT email ". |
||
| 1731 | "FROM artifact_cc ". |
||
| 1732 | "WHERE artifact_id=". db_ei($this->getID()) ." ORDER BY date DESC"; |
||
| 1733 | $result = db_query($sql); |
||
| 1734 | $rows=db_numrows($result); |
||
| 1735 | if ($rows <= 0) { |
||
| 1736 | return ''; |
||
| 1737 | } else { |
||
| 1738 | $email_arr=array(); |
||
| 1739 | for ($i=0; $i < $rows; $i++) { |
||
| 1740 | $email_arr[] = db_result($result, $i, 'email'); |
||
| 1741 | } |
||
| 1742 | $old_value = join(",",$email_arr); |
||
| 1743 | return $old_value; |
||
| 1744 | } |
||
| 1745 | } |
||
| 1746 | |||
| 1747 | /** |
||
| 1748 | * Return a CC list values |
||
| 1749 | * |
||
| 1750 | * @param artifact_cc_id: the artifact cc id |
||
| 1751 | * |
||
| 1752 | * @return array |
||
| 1753 | */ |
||
| 1754 | function getCC($artifact_cc_id) { |
||
| 1755 | |||
| 1756 | $sql="SELECT artifact_cc_id,artifact_cc.email,artifact_cc.added_by,artifact_cc.comment,artifact_cc.date,user.user_name ". |
||
| 1757 | "FROM artifact_cc,user ". |
||
| 1758 | "WHERE artifact_cc_id=". db_ei($artifact_cc_id) ." ". |
||
| 1759 | "AND added_by=user.user_id"; |
||
| 1760 | $res = db_query($sql); |
||
| 1761 | return db_fetch_array($res); |
||
| 1762 | } |
||
| 1763 | |||
| 1764 | /** |
||
| 1765 | * Return the artifact dependencies values |
||
| 1766 | * |
||
| 1767 | * @return array |
||
| 1768 | */ |
||
| 1769 | function getDependencies() { |
||
| 1770 | |||
| 1771 | $sql="SELECT d.artifact_depend_id, d.is_dependent_on_artifact_id, d.artifact_id, a.summary, afvl.value as status, ag.group_artifact_id, ag.name, g.group_id, g.group_name ". |
||
| 1772 | "FROM artifact_dependencies d, artifact_group_list ag, groups g, artifact a, artifact_field_value_list afvl, artifact_field f ". |
||
| 1773 | "WHERE d.is_dependent_on_artifact_id = a.artifact_id AND ". |
||
| 1774 | "afvl.field_id = f.field_id AND ". |
||
| 1775 | "f.group_artifact_id = a.group_artifact_id AND ". |
||
| 1776 | "f.field_name = 'status_id' AND ". |
||
| 1777 | "afvl.value_id = a.status_id AND ". |
||
| 1778 | "afvl.group_artifact_id = a.group_artifact_id AND ". |
||
| 1779 | "a.group_artifact_id = ag.group_artifact_id AND ". |
||
| 1780 | "d.artifact_id = ". db_ei($this->getID()) ." AND ". |
||
| 1781 | "ag.group_id = g.group_id ORDER BY a.artifact_id"; |
||
| 1782 | //echo "sql=$sql<br>"; |
||
| 1783 | return db_query($sql); |
||
| 1784 | } |
||
| 1785 | |||
| 1786 | /** |
||
| 1787 | * Return the artifact inverse dependencies values |
||
| 1788 | * |
||
| 1789 | * @return array |
||
| 1790 | */ |
||
| 1791 | function getInverseDependencies() { |
||
| 1792 | |||
| 1793 | $sql="SELECT d.artifact_depend_id, d.is_dependent_on_artifact_id, d.artifact_id, a.summary, afvl.value as status, ag.group_artifact_id, ag.name, g.group_id, g.group_name ". |
||
| 1794 | "FROM artifact_dependencies d, artifact_group_list ag, groups g, artifact a, artifact_field_value_list afvl, artifact_field f ". |
||
| 1795 | "WHERE d.artifact_id = a.artifact_id AND ". |
||
| 1796 | "afvl.field_id = f.field_id AND ". |
||
| 1797 | "f.group_artifact_id = a.group_artifact_id AND ". |
||
| 1798 | "f.field_name = 'status_id' AND ". |
||
| 1799 | "afvl.value_id = a.status_id AND ". |
||
| 1800 | "afvl.group_artifact_id = a.group_artifact_id AND ". |
||
| 1801 | "a.group_artifact_id = ag.group_artifact_id AND ". |
||
| 1802 | "d.is_dependent_on_artifact_id = ". db_ei($this->getID()) ." AND ". |
||
| 1803 | "ag.group_id = g.group_id ORDER BY a.artifact_id"; |
||
| 1804 | //echo "sql=$sql<br>"; |
||
| 1805 | return db_query($sql); |
||
| 1806 | } |
||
| 1807 | |||
| 1808 | /** |
||
| 1809 | * Return the names of attached files |
||
| 1810 | * |
||
| 1811 | * @return string |
||
| 1812 | */ |
||
| 1813 | function getAttachedFileNames () { |
||
| 1814 | $sql="SELECT filename ". |
||
| 1815 | "FROM artifact_file ". |
||
| 1816 | "WHERE artifact_id=". db_ei($this->getID()) ." ORDER BY adddate DESC"; |
||
| 1817 | $result = db_query($sql); |
||
| 1818 | $rows=db_numrows($result); |
||
| 1819 | if ($rows <= 0) { |
||
| 1820 | return ''; |
||
| 1821 | } else { |
||
| 1822 | $name_arr=array(); |
||
| 1823 | for ($i=0; $i < $rows; $i++) { |
||
| 1824 | $name_arr[] = db_result($result, $i, 'filename'); |
||
| 1825 | } |
||
| 1826 | $old_value = join(',',$name_arr); |
||
| 1827 | return $old_value; |
||
| 1828 | } |
||
| 1829 | } |
||
| 1830 | |||
| 1831 | /** |
||
| 1832 | * Return the attached files |
||
| 1833 | * |
||
| 1834 | * @return array |
||
| 1835 | */ |
||
| 1836 | function getAttachedFiles () { |
||
| 1837 | $sql="SELECT id,artifact_id,filename,filesize,filetype,description,bin_data,adddate,user.user_name ". |
||
| 1838 | "FROM artifact_file,user ". |
||
| 1839 | "WHERE submitted_by=user.user_id ". |
||
| 1840 | "AND artifact_id=". db_ei($this->getID()) ." ORDER BY adddate DESC"; |
||
| 1841 | //echo "sql=$sql<br>"; |
||
| 1842 | return db_query($sql); |
||
| 1843 | } |
||
| 1844 | |||
| 1845 | /** |
||
| 1846 | * Return a attached file |
||
| 1847 | * |
||
| 1848 | * @param id: the file id |
||
| 1849 | * |
||
| 1850 | * @return array |
||
| 1851 | */ |
||
| 1852 | function getAttachedFile ($id) { |
||
| 1853 | $sql="SELECT id,filename,filesize,description,adddate,user.user_name ". |
||
| 1854 | "FROM artifact_file,user ". |
||
| 1855 | "WHERE submitted_by=user.user_id ". |
||
| 1856 | "AND id=". db_ei($id) ; |
||
| 1857 | //echo "sql=$sql<br>"; |
||
| 1858 | $res = db_query($sql); |
||
| 1859 | return db_fetch_array($res); |
||
| 1860 | } |
||
| 1861 | |||
| 1862 | function checkAssignees ($field_name,$result,$art_field_fact,$changes,&$user_ids) { |
||
| 1963 | |||
| 1964 | |||
| 1965 | |||
| 1966 | /** |
||
| 1967 | * userCanView - determine if the user can view this artifact. |
||
| 1968 | * |
||
| 1969 | * @param $my_user_id if not specified, use the current user id.. |
||
| 1970 | * @return boolean user_can_view. |
||
| 1971 | */ |
||
| 1972 | function userCanView($my_user_id=0) { |
||
| 1973 | |||
| 1974 | if (!$my_user_id) { |
||
| 1975 | $u = UserManager::instance()->getCurrentUser(); |
||
| 1976 | $my_user_id = $u->getId(); |
||
| 1977 | } else { |
||
| 1978 | $u = UserManager::instance()->getUserById($my_user_id); |
||
| 1979 | } |
||
| 1980 | // Super-user and Tracker admin have all rights to see even artfact that are restricted to all users |
||
| 1981 | if ($u->isSuperUser() || $u->isTrackerAdmin($this->ArtifactType->getGroupID(),$this->ArtifactType->getID())) { |
||
| 1982 | return true; |
||
| 1983 | } |
||
| 1984 | |||
| 1985 | |||
| 1986 | //Individual artifact permission |
||
| 1987 | $can_access = ! $this->useArtifactPermissions(); |
||
| 1988 | if (!$can_access) { |
||
| 1989 | $res=permission_db_authorized_ugroups('TRACKER_ARTIFACT_ACCESS',$this->getID()); |
||
| 1990 | if (db_numrows($res) > 0) { |
||
| 1991 | while ($row = db_fetch_array($res)) { |
||
| 1992 | if (ugroup_user_is_member($my_user_id, $row['ugroup_id'], $this->ArtifactType->Group->getID(), $this->ArtifactType->getID())) { |
||
| 1993 | $can_access = true; |
||
| 1994 | } |
||
| 1995 | } |
||
| 1996 | } |
||
| 1997 | } |
||
| 1998 | if ($can_access) { |
||
| 1999 | // Full access |
||
| 2000 | $res=permission_db_authorized_ugroups('TRACKER_ACCESS_FULL',$this->ArtifactType->getID()); |
||
| 2001 | if (db_numrows($res) > 0) { |
||
| 2002 | while ($row = db_fetch_array($res)) { |
||
| 2003 | if (ugroup_user_is_member($my_user_id, $row['ugroup_id'], $this->ArtifactType->Group->getID(), $this->ArtifactType->getID())) { |
||
| 2004 | return true; |
||
| 2005 | } |
||
| 2006 | } |
||
| 2007 | } |
||
| 2008 | |||
| 2009 | // 'submitter' access |
||
| 2010 | $res=permission_db_authorized_ugroups('TRACKER_ACCESS_SUBMITTER',$this->ArtifactType->getID()); |
||
| 2011 | if (db_numrows($res) > 0) { |
||
| 2012 | while ($row = db_fetch_array($res)) { |
||
| 2013 | if (ugroup_user_is_member($my_user_id, $row['ugroup_id'], $this->ArtifactType->Group->getID(), $this->ArtifactType->getID())) { |
||
| 2014 | // check that submitter is also a member |
||
| 2015 | if (ugroup_user_is_member($this->getSubmittedBy(), $row['ugroup_id'], $this->ArtifactType->Group->getID(), $this->ArtifactType->getID())) { |
||
| 2016 | return true; |
||
| 2017 | } |
||
| 2018 | } |
||
| 2019 | } |
||
| 2020 | } |
||
| 2021 | // 'assignee' access |
||
| 2022 | $res=permission_db_authorized_ugroups('TRACKER_ACCESS_ASSIGNEE',$this->ArtifactType->getID()); |
||
| 2023 | if (db_numrows($res) > 0) { |
||
| 2024 | while ($row = db_fetch_array($res)) { |
||
| 2025 | if (ugroup_user_is_member($my_user_id, $row['ugroup_id'], $this->ArtifactType->Group->getID(), $this->ArtifactType->getID())) { |
||
| 2026 | // check that one of the assignees is also a member |
||
| 2027 | if (ugroup_user_is_member($this->getValue('assigned_to'), $row['ugroup_id'], $this->ArtifactType->Group->getID(), $this->ArtifactType->getID())) { |
||
| 2028 | return true; |
||
| 2029 | } |
||
| 2030 | |||
| 2031 | // multi-assigned to |
||
| 2032 | $multi_assigned=$this->getMultiAssignedTo(); |
||
| 2033 | if (is_array($multi_assigned)) { |
||
| 2034 | foreach ($multi_assigned as $assigned) { |
||
| 2035 | if (ugroup_user_is_member($assigned, $row['ugroup_id'], $this->ArtifactType->Group->getID(), $this->ArtifactType->getID())) { |
||
| 2036 | return true; |
||
| 2037 | } |
||
| 2038 | } |
||
| 2039 | } |
||
| 2040 | } |
||
| 2041 | } |
||
| 2042 | } |
||
| 2043 | } |
||
| 2044 | return false; |
||
| 2045 | } |
||
| 2046 | |||
| 2047 | /** |
||
| 2048 | * getExtraFieldData - get an array of data for the extra fields associated with this artifact |
||
| 2049 | * |
||
| 2050 | * the array returned looks like |
||
| 2051 | * array( |
||
| 2052 | * [field_id] => fieldvalues |
||
| 2053 | * [field_id] => fieldvalues |
||
| 2054 | * ) |
||
| 2055 | * for multi select boxes, the values are separated by a comma |
||
| 2056 | * |
||
| 2057 | * @return array array of data |
||
| 2058 | */ |
||
| 2059 | function &getExtraFieldData() { |
||
| 2060 | global $art_field_fact; |
||
| 2061 | $extrafielddata = array(); |
||
| 2062 | |||
| 2063 | // now get the values for generic fields if any |
||
| 2064 | $sql = "SELECT * FROM artifact_field_value WHERE artifact_id='". db_ei($this->getID()) ."'"; |
||
| 2065 | $res=db_query($sql); |
||
| 2066 | if (!$res || db_numrows($res) < 1) { |
||
| 2067 | // if no result then it is possible that there isn't any generic fields |
||
| 2068 | return; |
||
| 2069 | } |
||
| 2070 | // Walk the database result (possible to get several values with a same field_id (multi select box)) |
||
| 2071 | while ($row = db_fetch_array($res)) { |
||
| 2072 | $data_fields[$row['field_id']][] = $row; |
||
| 2073 | } |
||
| 2074 | |||
| 2075 | // compute the extrafielddata array by walking the data_fields array |
||
| 2076 | $extrafielddata = array(); |
||
| 2077 | foreach ($data_fields as $field_id => $data_field) { |
||
| 2078 | $current_field = $art_field_fact->getFieldFromId($field_id); |
||
| 2079 | if (isset($current_field) && $current_field && !$current_field->isError()) { |
||
| 2080 | // $values contains the values of the field |
||
| 2081 | $values = array(); |
||
| 2082 | foreach ($data_field as $data_value) { |
||
| 2083 | $values[] = $data_value[$current_field->getValueFieldName()]; |
||
| 2084 | } |
||
| 2085 | // if there is more than one value, we separate them with a comma. |
||
| 2086 | // if not, implode will return the single value. |
||
| 2087 | $extrafielddata[$field_id] = implode(",", $values); |
||
| 2088 | } |
||
| 2089 | } |
||
| 2090 | return $extrafielddata; |
||
| 2091 | } |
||
| 2092 | |||
| 2093 | |||
| 2094 | /** |
||
| 2095 | * Build an array of user_ids using the changes array |
||
| 2096 | * |
||
| 2097 | * @param changes (IN): array of changes |
||
| 2098 | * |
||
| 2099 | * @param concerned_ids (OUT): user_ids of concerned users (attention user_ids are stored as keys) |
||
| 2100 | * @param concerned_addresses (OUT): email addresses of anonymous users (for instance in CC addresses) |
||
| 2101 | * |
||
| 2102 | */ |
||
| 2103 | function buildNotificationArrays($changes,&$concerned_ids,&$concerned_addresses) { |
||
| 2202 | |||
| 2203 | |||
| 2204 | |||
| 2205 | /** group users to be notified of artifact changes |
||
| 2206 | * groups are done with respect to ugroups and |
||
| 2207 | * their permissions on the artifact |
||
| 2208 | * @param user_id an array of user ids |
||
| 2209 | * return $user_sets array of arrays of user ids: |
||
| 2210 | * return $ugroup_sets array of arrays of ugroup_ids. |
||
| 2211 | * the $user_sets keys correspond to the $ugroup_sets keys i.e. |
||
| 2212 | * $ugroup_sets[x] are the ugroups that the users in $user_sets[x] |
||
| 2213 | * belong to |
||
| 2214 | */ |
||
| 2215 | function groupNotificationList($user_ids,&$user_sets,&$ugroup_sets) { |
||
| 2216 | |||
| 2217 | $group_id = $this->ArtifactType->getGroupID(); |
||
| 2218 | $group_artifact_id = $this->ArtifactType->getID(); |
||
| 2219 | |||
| 2220 | $user_sets = array(); |
||
| 2221 | $ugroup_sets = array(); |
||
| 2222 | |||
| 2223 | //go through user_ids array: |
||
| 2224 | //for each user have a look at which ugroups he belongs |
||
| 2225 | |||
| 2226 | |||
| 2227 | foreach ($user_ids as $user_id) { |
||
| 2228 | $specific_ugroups = ugroup_db_list_tracker_ugroups_for_user($group_id,$group_artifact_id,$user_id); |
||
| 2229 | //echo "<br>specific_ugroups for $user_id = "; print_r($specific_ugroups); |
||
| 2230 | $dynamic_ugroups = ugroup_db_list_dynamic_ugroups_for_user($group_id,$group_artifact_id,$user_id); |
||
| 2231 | //echo "<br>dynamic_ugroups for $user_id = "; print_r($dynamic_ugroups); |
||
| 2232 | $all_ugroups = array_merge($dynamic_ugroups, $specific_ugroups); |
||
| 2233 | //echo "<br>all_ugroups for $user_id = "; print_r($all_ugroups); |
||
| 2234 | |||
| 2235 | $found_gr = false; |
||
| 2236 | while (list($x,$ug) = each($ugroup_sets)) { |
||
| 2237 | $diff1 = array_diff($ug,$all_ugroups); |
||
| 2238 | $diff2 = array_diff($all_ugroups,$ug); |
||
| 2239 | if ( empty($diff1) && empty($diff2) ) { |
||
| 2240 | // we found the magic users that are part of exactly the same ugroups as this user |
||
| 2241 | $gr = $user_sets[$x]; |
||
| 2242 | $gr[] = $user_id; |
||
| 2243 | unset($user_sets[$x]); |
||
| 2244 | $user_sets[$x] = $gr; |
||
| 2245 | $found_gr = true; |
||
| 2246 | break; |
||
| 2247 | } |
||
| 2248 | } |
||
| 2249 | // if we didn't find users who have exactly the same permissions we have to add this user separately |
||
| 2250 | if (!$found_gr) { |
||
| 2251 | $user_sets[] = array($user_id); |
||
| 2252 | $ugroup_sets[] = $all_ugroups; |
||
| 2253 | } |
||
| 2254 | } |
||
| 2255 | |||
| 2256 | } |
||
| 2257 | |||
| 2258 | /** |
||
| 2259 | * Checks if a user is allowed to delete and update a follow-up comment |
||
| 2260 | * |
||
| 2261 | * @param user_id |
||
| 2262 | * @param comment_id |
||
| 2263 | * |
||
| 2264 | * @return boolean |
||
| 2265 | */ |
||
| 2266 | function userCanEditFollowupComment($comment_id) { |
||
| 2286 | |||
| 2287 | /** |
||
| 2288 | * Checks if the comment was removed |
||
| 2289 | * |
||
| 2290 | * @params int comment_id |
||
| 2291 | * |
||
| 2292 | * @return boolean |
||
| 2293 | */ |
||
| 2294 | function isFollowupCommentDeleted($comment_id) { |
||
| 2295 | |||
| 2296 | $sql = 'SELECT artifact_id, new_value |
||
| 2297 | FROM artifact_history |
||
| 2298 | WHERE artifact_history_id = '. db_ei($comment_id) ; |
||
| 2299 | $res = db_query($sql); |
||
| 2300 | if (db_result($res,0,'new_value') == "") { |
||
| 2301 | return true; |
||
| 2302 | } |
||
| 2303 | $lbl = "lbl_".$comment_id."_comment"; |
||
| 2304 | $aid = db_result($res,0,'artifact_id'); |
||
| 2305 | $qry = 'SELECT NULL FROM artifact_history' |
||
| 2306 | .' WHERE artifact_id = '. db_ei($aid) |
||
| 2307 | .' AND field_name = "'. db_es($lbl) .'"' |
||
| 2308 | .' AND new_value = ""'; |
||
| 2309 | $result = db_query($qry); |
||
| 2310 | if (db_numrows($result) > 0) { |
||
| 2311 | return true; |
||
| 2312 | } else { |
||
| 2313 | return false; |
||
| 2314 | } |
||
| 2315 | |||
| 2316 | } |
||
| 2317 | |||
| 2318 | /** |
||
| 2319 | * Gets the original submitter of a follow-up comment |
||
| 2320 | * |
||
| 2321 | * @param int comment_id |
||
| 2322 | * |
||
| 2323 | * @return result set |
||
| 2324 | */ |
||
| 2325 | function getOriginalCommentSubmitter($comment_id) { |
||
| 2326 | |||
| 2327 | $sql = 'SELECT field_name, mod_by, email |
||
| 2328 | FROM artifact_history |
||
| 2329 | WHERE artifact_history_id = '. db_ei($comment_id) ; |
||
| 2330 | $res = db_query($sql); |
||
| 2331 | $field_name = db_result($res,0,'field_name'); |
||
| 2332 | if ($field_name == "comment") { |
||
| 2333 | return $res; |
||
| 2334 | } else if (preg_match("/^(lbl_)/",$field_name) && preg_match("/(_comment)$/",$field_name)) { |
||
| 2335 | // extract id of the original comment |
||
| 2336 | $id = (int) substr($field_name,4,-8); |
||
| 2337 | $qry = 'SELECT mod_by, email |
||
| 2338 | FROM artifact_history |
||
| 2339 | WHERE artifact_history_id = '. db_ei($id) .' |
||
| 2340 | AND field_name = "comment"'; |
||
| 2341 | $result = db_query($qry); |
||
| 2342 | return $result; |
||
| 2343 | } |
||
| 2344 | |||
| 2345 | } |
||
| 2346 | |||
| 2347 | /** |
||
| 2348 | * Gets the original submission date of a follow-up comment |
||
| 2349 | * |
||
| 2350 | * @param int comment_id |
||
| 2351 | * |
||
| 2352 | * @return result set |
||
| 2353 | */ |
||
| 2354 | function getOriginalCommentDate($comment_id) { |
||
| 2373 | |||
| 2374 | /** |
||
| 2375 | * Send different messages to persons affected by this artifact with respect |
||
| 2376 | * to their different permissions |
||
| 2377 | * |
||
| 2378 | * @param more_addresses: additional addresses |
||
| 2379 | * @param changes: array of changes |
||
| 2380 | * |
||
| 2381 | * @return void |
||
| 2382 | */ |
||
| 2383 | function mailFollowupWithPermissions($more_addresses=false,$changes=false) { |
||
| 2384 | global $art_field_fact,$Language; |
||
| 2385 | |||
| 2386 | // check if notification is temporarily stopped in this tracker |
||
| 2387 | if (!$this->ArtifactType->getStopNotification()) { |
||
| 2388 | $group = $this->ArtifactType->getGroup(); |
||
| 2389 | $group_artifact_id = $this->ArtifactType->getID(); |
||
| 2390 | $group_id = $group->getGroupId(); |
||
| 2391 | |||
| 2392 | // See who is going to receive the notification. Plus append any other email |
||
| 2393 | // given at the end of the list. |
||
| 2394 | $withoutpermissions_concerned_addresses = array(); |
||
| 2395 | $this->buildNotificationArrays($changes, $concerned_ids, $concerned_addresses); |
||
| 2396 | if ($more_addresses) { |
||
| 2397 | foreach ($more_addresses as $address) { |
||
| 2398 | if ($address['address'] && $address['address'] != '') { |
||
| 2399 | $res_username = user_get_result_set_from_email($address['address'], false); |
||
| 2400 | if ($res_username && (db_numrows($res_username) == 1)) { |
||
| 2401 | $u_id = db_result($res_username,0,'user_id'); |
||
| 2402 | if (!$address['check_permissions']) { |
||
| 2403 | $curr_user = UserManager::instance()->getUserById($u_id); |
||
| 2404 | if ($curr_user->isActive() || $curr_user->isRestricted()) { |
||
| 2405 | $withoutpermissions_concerned_addresses[user_getemail($u_id)] = true; |
||
| 2406 | } |
||
| 2407 | unset($concerned_ids[$u_id]); |
||
| 2408 | } else { |
||
| 2409 | $concerned_ids[$u_id] = true; |
||
| 2410 | } |
||
| 2411 | } else { |
||
| 2412 | if (!$address['check_permissions']) { |
||
| 2413 | $withoutpermissions_concerned_addresses[$address['address']] = true; |
||
| 2414 | unset($concerned_addresses[$address['address']]); |
||
| 2415 | } else { |
||
| 2416 | $concerned_addresses[$address['address']] = true; |
||
| 2417 | } |
||
| 2418 | } |
||
| 2419 | } |
||
| 2420 | } |
||
| 2421 | } |
||
| 2422 | //concerned_ids contains users for wich we have to check permissions |
||
| 2423 | //concerned_addresses contains emails for which there is no existing user. Permissions will be checked (Anonymous users) |
||
| 2424 | //withoutpermissions_concerned_addresses contains emails for which there is no permissions check |
||
| 2425 | |||
| 2426 | //Prepare e-mail |
||
| 2427 | list($host,) = explode(':',$GLOBALS['sys_default_domain']); |
||
| 2428 | |||
| 2429 | |||
| 2430 | //treat anonymous users |
||
| 2431 | $text_mail = $this->createMailForUsers(array($GLOBALS['UGROUP_ANONYMOUS']),$changes,$group_id,$group_artifact_id,$ok,$subject); |
||
| 2432 | $html_mail = $this->createHTMLMailForUsers(array($GLOBALS['UGROUP_ANONYMOUS']),$changes,$group_id,$group_artifact_id,$ok,$subject); |
||
| 2433 | |||
| 2434 | if ($ok) { |
||
| 2435 | $this->sendNotification(array_keys($concerned_addresses), $subject, $text_mail, $html_mail); |
||
| 2436 | } |
||
| 2437 | |||
| 2438 | //treat 'without permissions' emails |
||
| 2439 | if (count($withoutpermissions_concerned_addresses)) { |
||
| 2440 | $text_mail = $this->createMailForUsers(false,$changes,$group_id,$group_artifact_id,$ok,$subject); |
||
| 2441 | $html_mail = $this->createHTMLMailForUsers(false,$changes,$group_id,$group_artifact_id,$ok,$subject); |
||
| 2442 | |||
| 2443 | if ($ok) { |
||
| 2444 | $this->sendNotification(array_keys($withoutpermissions_concerned_addresses), $subject, $text_mail, $html_mail); |
||
| 2445 | } |
||
| 2446 | |||
| 2447 | } |
||
| 2448 | |||
| 2449 | //now group other registered users |
||
| 2450 | |||
| 2451 | //echo "<br>concerned_ids = ".implode(',',array_keys($concerned_ids)); |
||
| 2452 | |||
| 2453 | $this->groupNotificationList(array_keys($concerned_ids),$user_sets,$ugroup_sets); |
||
| 2454 | |||
| 2455 | //echo "<br>user_sets = "; print_r($user_sets); echo ", ugroup_sets = "; print_r($ugroup_sets); |
||
| 2456 | reset($ugroup_sets); |
||
| 2457 | while (list($x,$ugroups) = each($ugroup_sets)) { |
||
| 2458 | unset($arr_addresses); |
||
| 2459 | |||
| 2460 | $user_ids = $user_sets[$x]; |
||
| 2461 | //echo "<br>---> preparing mail $x for ";print_r($user_ids); |
||
| 2462 | $text_mail = $this->createMailForUsers($ugroups,$changes,$group_id,$group_artifact_id,$ok,$subject); |
||
| 2463 | $html_mail = $this->createHTMLMailForUsers($ugroups,$changes,$group_id,$group_artifact_id,$ok,$subject); |
||
| 2464 | if (!$ok) continue; //don't send the mail if nothing permitted for this user group |
||
| 2465 | |||
| 2466 | foreach ($user_ids as $user_id) { |
||
| 2467 | $arr_addresses[] = user_getemail($user_id); |
||
| 2468 | } |
||
| 2469 | |||
| 2470 | if ($arr_addresses) { |
||
| 2471 | $this->sendNotification($arr_addresses, $subject, $text_mail, $html_mail); |
||
| 2472 | } |
||
| 2473 | } |
||
| 2474 | } |
||
| 2475 | } |
||
| 2476 | |||
| 2477 | /** |
||
| 2478 | * Build notification list based on user preferences |
||
| 2479 | * |
||
| 2480 | * @param Array $addresses |
||
| 2481 | * @param String $subject |
||
| 2482 | * @param Codendi_Mail_Interface $text_mail |
||
| 2483 | * @param Codendi_Mail_Interface $html_mail |
||
| 2484 | */ |
||
| 2485 | function sendNotification($addresses, $subject, $text_mail, $html_mail) { |
||
| 2486 | $html_addresses = array(); |
||
| 2487 | $text_addresses = array(); |
||
| 2488 | |||
| 2489 | $mailMgr = new MailManager(); |
||
| 2490 | $mailPrefs = $mailMgr->getMailPreferencesByEmail($addresses); |
||
| 2491 | foreach ($mailPrefs['html'] as $user) { |
||
| 2492 | $html_addresses[] = $user->getEmail(); |
||
| 2493 | } |
||
| 2494 | foreach ($mailPrefs['text'] as $user) { |
||
| 2495 | $text_addresses[] = $user->getEmail(); |
||
| 2496 | } |
||
| 2497 | |||
| 2498 | $mail = null; |
||
| 2499 | if ($text_mail && count($text_addresses)) { |
||
| 2500 | $this->sendMail($text_mail, $subject, $text_addresses); |
||
| 2501 | } |
||
| 2502 | if ($html_mail && count($html_addresses)) { |
||
| 2503 | if ($text_mail) { |
||
| 2504 | $html_mail->setBodyText($text_mail->getBody()); |
||
| 2505 | } |
||
| 2506 | $this->sendMail($html_mail, $subject, $html_addresses); |
||
| 2507 | } |
||
| 2508 | } |
||
| 2509 | |||
| 2510 | /** |
||
| 2511 | * Finalize & send mail to peple |
||
| 2512 | * |
||
| 2513 | * @param Codendi_Mail_Interface $mail |
||
| 2514 | * @param String $subject |
||
| 2515 | * @param Array $to |
||
| 2516 | */ |
||
| 2517 | function sendMail(Codendi_Mail_Interface $mail, $subject, array $to) { |
||
| 2518 | $mail->addAdditionalHeader("X-Codendi-Project", $this->ArtifactType->getGroup()->getUnixName()); |
||
| 2519 | $mail->addAdditionalHeader("X-Codendi-Artifact", $this->ArtifactType->getItemName()); |
||
| 2520 | $mail->addAdditionalHeader("X-Codendi-Artifact-ID", $this->getID()); |
||
| 2521 | $mail->setFrom($GLOBALS['sys_noreply']); |
||
| 2522 | $mail->setTo(join(',', $to)); |
||
| 2523 | $mail->setSubject($subject); |
||
| 2524 | $mail->send(); |
||
| 2525 | } |
||
| 2526 | |||
| 2527 | /** for a certain set of users being part of the same ugroups |
||
| 2528 | * create the mail body containing only fields that they have the permission to read |
||
| 2529 | */ |
||
| 2530 | function createHTMLMailForUsers($ugroups,$changes,$group_id,$group_artifact_id,&$ok,&$subject) { |
||
| 2673 | |||
| 2674 | /** |
||
| 2675 | * @return string html call to action button to include in an html mail |
||
| 2676 | */ |
||
| 2677 | public function fetchHtmlAnswerButton($artifact_href) { |
||
| 2678 | return '<p align="right" class="cta"> |
||
| 2679 | <a href="'. $artifact_href .'" target="_blank">' . |
||
| 2680 | $GLOBALS['Language']->getText('tracker_include_artifact','mail_answer_now') . |
||
| 2681 | '</a> |
||
| 2682 | </p>'; |
||
| 2683 | } |
||
| 2684 | |||
| 2685 | /** |
||
| 2686 | * return a field for the given user. |
||
| 2687 | * |
||
| 2688 | * @protected |
||
| 2689 | **/ |
||
| 2690 | function _getFieldLabelAndValueForHTMLMail($group_id, $group_artifact_id, $field, $field_perm) { |
||
| 2691 | $html = false; |
||
| 2692 | $read_only = true; |
||
| 2693 | $field_name = $field->getName(); |
||
| 2694 | if ($field_perm === false || (isset($field_perm[$field_name]) && $field_perm[$field_name] && permission_can_read_field($field_perm[$field_name]))) { |
||
| 2695 | |||
| 2696 | // For multi select box, we need to retrieve all the values |
||
| 2697 | if ( $field->isMultiSelectBox() ) { |
||
| 2698 | $field_value = $field->getValues($this->getID()); |
||
| 2699 | } else { |
||
| 2700 | $field_value = $this->getValue($field->getName()); |
||
| 2701 | } |
||
| 2702 | |||
| 2703 | $field_html = new ArtifactFieldHtml($field); |
||
| 2704 | $field_html->disableJavascript(); |
||
| 2705 | $label = $field_html->labelDisplay(false,false,false); |
||
| 2706 | |||
| 2707 | if ($field->getName() == 'submitted_by') { |
||
| 2708 | $value = util_user_link(user_getname($field_value)); |
||
| 2709 | } else if ($field->getName() == 'open_date') { |
||
| 2710 | $value = format_date($GLOBALS['Language']->getText('system', 'datefmt'),$field_value); |
||
| 2711 | } else if ($field->getName() == 'last_update_date') { |
||
| 2712 | $value = format_date($GLOBALS['Language']->getText('system', 'datefmt'),$field_value); |
||
| 2713 | } else { |
||
| 2714 | $value = $field_html->display($this->ArtifactType->getID(), $field_value, false, false, $read_only, false, false, 0, false, 0, false, 0, false); |
||
| 2715 | $value = util_make_links($value, $group_id, $group_artifact_id); |
||
| 2716 | } |
||
| 2717 | $html = array('label' => $label, 'value' => $value); |
||
| 2718 | } |
||
| 2719 | return $html; |
||
| 2720 | } |
||
| 2721 | |||
| 2722 | /** for a certain set of users being part of the same ugroups |
||
| 2723 | * create the mail body containing only fields that they have the permission to read |
||
| 2724 | */ |
||
| 2725 | function createMailForUsers($ugroups,$changes,$group_id,$group_artifact_id,&$ok,&$subject) { |
||
| 2883 | |||
| 2884 | /** |
||
| 2885 | * Check whether $field_name is readable according to $field_perm |
||
| 2886 | * |
||
| 2887 | * All permissions are granted when $field_perm is equal to false. |
||
| 2888 | * $field_perm is equal to false when addresses are added in tracker admin to |
||
| 2889 | * "Global Email Notification with "check permission" unchecked. |
||
| 2890 | * |
||
| 2891 | * @param Array $field_perm ... |
||
| 2892 | * |
||
| 2893 | * @return Boolean |
||
| 2894 | */ |
||
| 2895 | public function hasFieldPermission($field_perm, $field_name) { |
||
| 2896 | $hasPerm = false; |
||
| 2897 | if ($field_perm === false) { |
||
| 2898 | $hasPerm = true; |
||
| 2899 | } else { |
||
| 2900 | if (isset($field_perm[$field_name]) && $field_perm[$field_name] && permission_can_read_field($field_perm[$field_name])) { |
||
| 2901 | $hasPerm = true; |
||
| 2902 | } |
||
| 2903 | } |
||
| 2904 | return $hasPerm; |
||
| 2905 | } |
||
| 2906 | |||
| 2907 | /** |
||
| 2908 | * Format the changes |
||
| 2909 | * |
||
| 2910 | * @param changes: array of changes |
||
| 2911 | * @param $field_perm an array with the permission associated to each field. false to no check perms |
||
| 2912 | * @param $visible_change only needed when using permissions. Returns true if there is any change |
||
| 2913 | * that the user has permission to see |
||
| 2914 | * |
||
| 2915 | * @return string |
||
| 2916 | */ |
||
| 2917 | function formatChanges($changes,$field_perm,&$visible_change) { |
||
| 2918 | |||
| 2919 | global $art_field_fact,$Language; |
||
| 2920 | $visible_change = false; |
||
| 2921 | $out_hdr = ''; |
||
| 2922 | $out = ''; |
||
| 2923 | $out_com = ''; |
||
| 2924 | $out_att = ''; |
||
| 2925 | reset($changes); |
||
| 2926 | $fmt = "%20s | %-25s | %s".$GLOBALS['sys_lf']; |
||
| 2927 | |||
| 2928 | |||
| 2929 | if ($this->hasFieldPermission($field_perm, 'assigned_to') || |
||
| 2930 | $this->hasFieldPermission($field_perm, 'multi_assigned_to') || |
||
| 2931 | (!isset($field_perm['assigned_to']) && !isset($field_perm['multi_assigned_to']))) { |
||
| 2932 | if (user_isloggedin()) { |
||
| 2933 | $user_id = user_getid(); |
||
| 2934 | $out_hdr = $Language->getText('tracker_include_artifact','changes_by').' '.user_getrealname($user_id).' <'.user_getemail($user_id).">". $GLOBALS['sys_lf'] .""; |
||
| 2935 | $out_hdr .= $Language->getText('tracker_import_utils','date').': '.format_date($GLOBALS['Language']->getText('system', 'datefmt'),time()).' ('.user_get_timezone().')'; |
||
| 2936 | } else { |
||
| 2937 | $out_hdr = $Language->getText('tracker_include_artifact','changes_by').' '.$Language->getText('tracker_include_artifact','anon_user').' '.$Language->getText('tracker_import_utils','date').': '.format_date($GLOBALS['Language']->getText('system', 'datefmt'),time()); |
||
| 2938 | } |
||
| 2939 | } |
||
| 2940 | //Process special cases first: follow-up comment |
||
| 2941 | if (array_key_exists('comment', $changes) && $changes['comment']) { |
||
| 2942 | $visible_change = true; |
||
| 2943 | $out_com = $GLOBALS['sys_lf'] . $GLOBALS['sys_lf'] ."--------------- ".$Language->getText('tracker_include_artifact','add_flup_comment')." ----------------". $GLOBALS['sys_lf'] .""; |
||
| 2944 | |||
| 2945 | if (isset($changes['comment']['type']) && $changes['comment']['type'] != $Language->getText('global','none') && $changes['comment']['type'] != '') { |
||
| 2946 | $out_com .= "[".$changes['comment']['type']."]".$GLOBALS['sys_lf']; |
||
| 2947 | } |
||
| 2948 | $out_com .= $this->formatFollowUp(null, $changes['comment']['format'], $changes['comment']['add'], self::OUTPUT_MAIL_TEXT); |
||
| 2949 | unset($changes['comment']); |
||
| 2950 | } |
||
| 2951 | |||
| 2952 | //Process special cases first: file attachment |
||
| 2953 | if (array_key_exists('attach', $changes) && $changes['attach']) { |
||
| 2954 | $visible_change = true; |
||
| 2955 | $out_att = "". $GLOBALS['sys_lf'] . $GLOBALS['sys_lf'] ."--------------- ".$Language->getText('tracker_include_artifact','add_attachment')." -----------------". $GLOBALS['sys_lf'] .""; |
||
| 2956 | $out_att .= sprintf($Language->getText('tracker_include_artifact','file_name')." %-30s ".$Language->getText('tracker_include_artifact','size').":%d KB". $GLOBALS['sys_lf'] ."",$changes['attach']['name'], |
||
| 2957 | intval($changes['attach']['size']/1024) ); |
||
| 2958 | $out_att .= $changes['attach']['description'] . $GLOBALS['sys_lf'] . $changes['attach']['href']; |
||
| 2959 | unset($changes['attach']); |
||
| 2960 | } |
||
| 2961 | |||
| 2962 | // All the rest of the fields now |
||
| 2963 | reset($changes); |
||
| 2964 | |||
| 2965 | while ( list($field_name,$h) = each($changes)) { |
||
| 2966 | // If both removed and added items are empty skip - Sanity check |
||
| 2967 | if (((isset($h['del']) && $h['del']) || (isset($h['add']) && $h['add'])) |
||
| 2968 | && $this->hasFieldPermission($field_perm, $field_name)) { |
||
| 2969 | |||
| 2970 | $visible_change = true; |
||
| 2971 | $label = $field_name; |
||
| 2972 | $field = $art_field_fact->getFieldFromName($field_name); |
||
| 2973 | if ( $field ) { |
||
| 2974 | $label = $field->getLabel(); |
||
| 2975 | if (isset($h['del'])) { |
||
| 2976 | $h['del'] = SimpleSanitizer::unsanitize(util_unconvert_htmlspecialchars($h['del'])); |
||
| 2977 | } |
||
| 2978 | if (isset($h['add'])) { |
||
| 2979 | $h['add'] = SimpleSanitizer::unsanitize(util_unconvert_htmlspecialchars($h['add'])); |
||
| 2980 | } |
||
| 2981 | } |
||
| 2982 | $out .= sprintf($fmt, SimpleSanitizer::unsanitize($label), isset($h['del'])?$h['del']:"",isset($h['add'])?$h['add']:""); |
||
| 2983 | } |
||
| 2984 | } // while |
||
| 2985 | |||
| 2986 | if ($out) { |
||
| 2987 | $out = $GLOBALS['sys_lf'] . $GLOBALS['sys_lf'] . sprintf($fmt,$Language->getText('tracker_include_artifact','what').' ',$Language->getText('tracker_include_artifact','removed'),$Language->getText('tracker_include_artifact','added')). |
||
| 2988 | "------------------------------------------------------------------". $GLOBALS['sys_lf'] . $out; |
||
| 2989 | } |
||
| 2990 | |||
| 2991 | return($out_hdr.$out.$out_com.$out_att); |
||
| 2992 | } |
||
| 2993 | |||
| 2994 | /** |
||
| 2995 | * Format the changes |
||
| 2996 | * |
||
| 2997 | * @param changes: array of changes |
||
| 2998 | * @param $field_perm an array with the permission associated to each field. false to no check perms |
||
| 2999 | * @param string $artifact_href The direct link to the artifact |
||
| 3000 | * @param $visible_change only needed when using permissions. Returns true if there is any change |
||
| 3001 | * that the user has permission to see |
||
| 3002 | * |
||
| 3003 | * @return string |
||
| 3004 | */ |
||
| 3005 | function formatChangesHTML($changes, $field_perm, $artifact_href, &$visible_change) { |
||
| 3147 | |||
| 3148 | |||
| 3149 | /** |
||
| 3150 | * Return the string to display the follow ups comments |
||
| 3151 | * |
||
| 3152 | * @param Integer group_id: the group id |
||
| 3153 | * @param Integer output By default set to OUTPUT_BROWSER, the output is displayed on browser |
||
| 3154 | * set to OUTPUT_MAIL_TEXT, the followups will be sent in mail |
||
| 3155 | * else is an export csv/DB |
||
| 3156 | * @return string the follow-up comments to display in HTML or in ascii mode |
||
| 3157 | */ |
||
| 3158 | function showFollowUpComments($group_id, $pv, $output = self::OUTPUT_BROWSER) { |
||
| 3370 | |||
| 3371 | /** |
||
| 3372 | * Display the list of CC addresses |
||
| 3373 | * |
||
| 3374 | * @param group_id: the group id |
||
| 3375 | * @param group_artifact_id: the artifact type ID |
||
| 3376 | * @param ascii: ascii mode |
||
| 3377 | * |
||
| 3378 | * @return void |
||
| 3379 | */ |
||
| 3380 | function showCCList ($group_id, $group_artifact_id, $ascii=false, $pv = 0) { |
||
| 3381 | $hp = Codendi_HTMLPurifier::instance(); |
||
| 3382 | global $Language; |
||
| 3383 | |||
| 3384 | // |
||
| 3385 | // format the CC list for this artifact |
||
| 3386 | // |
||
| 3387 | |||
| 3388 | $result = $this->getCCList(); |
||
| 3389 | $rows = db_numrows($result); |
||
| 3390 | $out = ''; |
||
| 3391 | |||
| 3392 | // Nobody in the CC list -> return now |
||
| 3393 | if ($rows <= 0) { |
||
| 3394 | if ($ascii) |
||
| 3395 | $out = $Language->getText('tracker_include_artifact','cc_empty').$GLOBALS['sys_lf']; |
||
| 3396 | else |
||
| 3397 | $out = '<H4>'.$Language->getText('tracker_include_artifact','cc_empty').'</H4>'; |
||
| 3398 | return $out; |
||
| 3399 | } |
||
| 3400 | |||
| 3401 | // Header first an determine what the print out format is |
||
| 3402 | // based on output type (Ascii, HTML) |
||
| 3403 | if ($ascii) { |
||
| 3404 | $out .= $Language->getText('tracker_include_artifact','cc_list').$GLOBALS['sys_lf'].str_repeat("*",strlen($Language->getText('tracker_include_artifact','cc_list'))).$GLOBALS['sys_lf'].$GLOBALS['sys_lf']; |
||
| 3405 | $fmt = "%-35s | %s".$GLOBALS['sys_lf']; |
||
| 3406 | $out .= sprintf($fmt, $Language->getText('tracker_include_artifact','cc_address'), $Language->getText('tracker_include_artifact','fill_cc_list_cmt')); |
||
| 3407 | $out .= "------------------------------------------------------------------". $GLOBALS['sys_lf']; |
||
| 3408 | } else { |
||
| 3409 | |||
| 3410 | $title_arr=array(); |
||
| 3411 | $title_arr[]=$Language->getText('tracker_include_artifact','cc_address'); |
||
| 3412 | $title_arr[]=$Language->getText('tracker_include_artifact','fill_cc_list_cmt'); |
||
| 3413 | $title_arr[]=$Language->getText('tracker_include_artifact','added_by'); |
||
| 3414 | $title_arr[]=$Language->getText('tracker_include_artifact','posted_on'); |
||
| 3415 | if ($pv == 0) { |
||
| 3416 | $title_arr[]=$Language->getText('tracker_include_canned','delete'); |
||
| 3417 | } |
||
| 3418 | $out .= html_build_list_table_top ($title_arr); |
||
| 3419 | |||
| 3420 | $fmt = "\n".'<TR class="%s"><td>%s</td><td>%s</td><td align="center">%s</td><td align="center">%s</td>'; |
||
| 3421 | if ($pv == 0) { |
||
| 3422 | $fmt .= '<td align="center">%s</td>'; |
||
| 3423 | } |
||
| 3424 | $fmt .= '</tr>'; |
||
| 3425 | } |
||
| 3426 | |||
| 3427 | // Loop through the cc and format them |
||
| 3428 | for ($i=0; $i < $rows; $i++) { |
||
| 3429 | |||
| 3430 | $email = db_result($result, $i, 'email'); |
||
| 3431 | $artifact_cc_id = db_result($result, $i, 'artifact_cc_id'); |
||
| 3432 | |||
| 3433 | // if the CC is a user point to its user page else build a mailto: URL |
||
| 3434 | $res_username = user_get_result_set_from_unix($email); |
||
| 3435 | if ($res_username && (db_numrows($res_username) == 1)) |
||
| 3436 | $href_cc = util_user_link($email); |
||
| 3437 | else |
||
| 3438 | $href_cc = '<a href="mailto:'.util_normalize_email($email).'">'.$email.'</a>'; |
||
| 3439 | |||
| 3440 | if ($ascii) { |
||
| 3441 | $out .= sprintf($fmt, $email, SimpleSanitizer::unsanitize(db_result($result, $i, 'comment'))); |
||
| 3442 | } else { |
||
| 3443 | |||
| 3444 | // show CC delete icon if one of the condition is met: |
||
| 3445 | // (a) current user is a group member |
||
| 3446 | // (b) the CC name is the current user |
||
| 3447 | // (c) the CC email address matches the one of the current user |
||
| 3448 | // (d) the current user is the person who added a gieven name in CC list |
||
| 3449 | if ( user_ismember($this->ArtifactType->getGroupID()) || |
||
| 3450 | (user_getname(user_getid()) == $email) || |
||
| 3451 | (user_getemail(user_getid()) == $email) || |
||
| 3452 | (user_getname(user_getid()) == db_result($result, $i, 'user_name') )) { |
||
| 3453 | $html_delete = '<a href="?func=delete_cc&group_id='.(int)$group_id.'&aid='.(int)$this->getID().'&atid='.(int)$group_artifact_id.'&artifact_cc_id='.(int)$artifact_cc_id.'" '. |
||
| 3454 | ' onClick="return confirm(\''.$Language->getText('tracker_include_artifact','delete_cc').'\')">'. |
||
| 3455 | '<IMG SRC="'.util_get_image_theme("ic/trash.png").'" HEIGHT="16" WIDTH="16" BORDER="0" ALT="'.$Language->getText('global','btn_delete').'"></A>'; |
||
| 3456 | } else { |
||
| 3457 | $html_delete = '-'; |
||
| 3458 | } |
||
| 3459 | |||
| 3460 | $out .= sprintf($fmt, |
||
| 3461 | util_get_alt_row_color($i), |
||
| 3462 | $href_cc, |
||
| 3463 | $hp->purify(SimpleSanitizer::unsanitize(db_result($result, $i, 'comment')), CODENDI_PURIFIER_BASIC, $this->ArtifactType->getGroupId()) , |
||
| 3464 | util_user_link(db_result($result, $i, 'user_name')), |
||
| 3465 | format_date($GLOBALS['Language']->getText('system', 'datefmt'),db_result($result, $i, 'date')), |
||
| 3466 | $html_delete); |
||
| 3467 | |||
| 3468 | } // for |
||
| 3469 | } |
||
| 3470 | |||
| 3471 | // final touch... |
||
| 3472 | $out .= ($ascii ? $GLOBALS['sys_lf'] : "</TABLE>"); |
||
| 3473 | |||
| 3474 | return($out); |
||
| 3475 | |||
| 3476 | } |
||
| 3477 | |||
| 3478 | /** |
||
| 3479 | * Display the artifact dependencies list |
||
| 3480 | * |
||
| 3481 | * @param group_id: the group id |
||
| 3482 | * @param group_artifact_id: the artifact type ID |
||
| 3483 | * @param ascii: ascii mode |
||
| 3484 | * |
||
| 3485 | * @return void |
||
| 3486 | */ |
||
| 3487 | function showDependencies ($group_id, $group_artifact_id, $ascii=false, $pv = 0) { |
||
| 3488 | $hp = Codendi_HTMLPurifier::instance(); |
||
| 3489 | global $Language; |
||
| 3490 | |||
| 3491 | // |
||
| 3492 | // format the dependencies list for this artifact |
||
| 3493 | // |
||
| 3494 | |||
| 3495 | $result=$this->getDependencies(); |
||
| 3496 | $rows=db_numrows($result); |
||
| 3497 | $out = ''; |
||
| 3498 | // Nobody in the dependencies list -> return now |
||
| 3499 | if ($rows <= 0) { |
||
| 3500 | if ($ascii) |
||
| 3501 | $out = $Language->getText('tracker_include_artifact','dep_list_empty').$GLOBALS['sys_lf']; |
||
| 3502 | else |
||
| 3503 | $out = '<H4>'.$Language->getText('tracker_include_artifact','dep_list_empty').'</H4>'; |
||
| 3504 | return $out; |
||
| 3505 | } |
||
| 3506 | |||
| 3507 | // Header first an determine what the print out format is |
||
| 3508 | // based on output type (Ascii, HTML) |
||
| 3509 | if ($ascii) { |
||
| 3510 | $out .= $Language->getText('tracker_include_artifact','dep_list').$GLOBALS['sys_lf'].str_repeat("*",strlen($Language->getText('tracker_include_artifact','dep_list'))). $GLOBALS['sys_lf'] . $GLOBALS['sys_lf']; |
||
| 3511 | $fmt = "%-15s | %s (%s)". $GLOBALS['sys_lf']; |
||
| 3512 | $out .= sprintf($fmt, |
||
| 3513 | $Language->getText('tracker_include_artifact','artifact'), |
||
| 3514 | $Language->getText('tracker_include_artifact','summary'), |
||
| 3515 | $Language->getText('global','status') |
||
| 3516 | ); |
||
| 3517 | $out .= "------------------------------------------------------------------". $GLOBALS['sys_lf']; |
||
| 3518 | } else { |
||
| 3519 | |||
| 3520 | $title_arr=array(); |
||
| 3521 | $title_arr[]=$Language->getText('tracker_include_artifact','artifact'); |
||
| 3522 | $title_arr[]=$Language->getText('tracker_include_artifact','summary'); |
||
| 3523 | $title_arr[]=$Language->getText('global','status'); |
||
| 3524 | $title_arr[]=$Language->getText('tracker_import_admin','tracker'); |
||
| 3525 | $title_arr[]=$Language->getText('tracker_include_artifact','group'); |
||
| 3526 | if ($pv == 0) { |
||
| 3527 | $title_arr[]=$Language->getText('tracker_include_canned','delete'); |
||
| 3528 | } |
||
| 3529 | $out .= html_build_list_table_top ($title_arr); |
||
| 3530 | |||
| 3531 | $fmt = "\n".'<TR class="%s"><td>%s</td><td>%s</td><td align="center">%s</td><td align="center">%s</td><td align="center">%s</td>'; |
||
| 3532 | if ($pv == 0) { |
||
| 3533 | $fmt .= '<td align="center">%s</td>'; |
||
| 3534 | } |
||
| 3535 | $fmt .= '</tr>'; |
||
| 3536 | } |
||
| 3537 | |||
| 3538 | // Loop through the denpendencies and format them |
||
| 3539 | for ($i=0; $i < $rows; $i++) { |
||
| 3540 | |||
| 3541 | $dependent_on_artifact_id = db_result($result, $i, 'is_dependent_on_artifact_id'); |
||
| 3542 | $summary = db_result($result, $i, 'summary'); |
||
| 3543 | $status = db_result($result, $i, 'status'); |
||
| 3544 | $tracker_label = db_result($result, $i, 'name'); |
||
| 3545 | $group_label = db_result($result, $i, 'group_name'); |
||
| 3546 | |||
| 3547 | if ($ascii) { |
||
| 3548 | $out .= sprintf($fmt, $dependent_on_artifact_id, util_unconvert_htmlspecialchars($summary), $status); |
||
| 3549 | } else { |
||
| 3550 | |||
| 3551 | if ( user_ismember($this->ArtifactType->getGroupID()) ) { |
||
| 3552 | $html_delete = '<a href="?func=delete_dependent&group_id='.(int)$group_id.'&aid='.(int)$this->getID().'&atid='.(int)$group_artifact_id.'&dependent_on_artifact_id='.(int)$dependent_on_artifact_id.'" '. |
||
| 3553 | ' onClick="return confirm(\''.$Language->getText('tracker_include_artifact','del_dep').'\')">'. |
||
| 3554 | '<IMG SRC="'.util_get_image_theme("ic/trash.png").'" HEIGHT="16" WIDTH="16" BORDER="0" ALT="'.$Language->getText('global','btn_delete').'"></A>'; |
||
| 3555 | } else { |
||
| 3556 | $html_delete = '-'; |
||
| 3557 | } |
||
| 3558 | |||
| 3559 | $out .= sprintf($fmt, |
||
| 3560 | util_get_alt_row_color($i), |
||
| 3561 | '<a href="/tracker/?func=gotoid&group_id='.(int)$group_id.'&aid='.(int)$dependent_on_artifact_id.'">'.(int)$dependent_on_artifact_id.'</a>', |
||
| 3562 | $hp->purify(util_unconvert_htmlspecialchars($summary), CODENDI_PURIFIER_CONVERT_HTML) , |
||
| 3563 | $hp->purify($status, CODENDI_PURIFIER_CONVERT_HTML) , |
||
| 3564 | $hp->purify(SimpleSanitizer::unsanitize($tracker_label), CODENDI_PURIFIER_CONVERT_HTML) , |
||
| 3565 | $hp->purify(util_unconvert_htmlspecialchars($group_label), CODENDI_PURIFIER_CONVERT_HTML) , |
||
| 3566 | $html_delete); |
||
| 3567 | |||
| 3568 | } // for |
||
| 3569 | } |
||
| 3570 | |||
| 3571 | // final touch... |
||
| 3572 | $out .= ($ascii ? $GLOBALS['sys_lf'] : "</TABLE>"); |
||
| 3573 | |||
| 3574 | return($out); |
||
| 3575 | |||
| 3576 | } |
||
| 3577 | |||
| 3578 | /** |
||
| 3579 | * Display the list of attached files |
||
| 3580 | * |
||
| 3581 | * @param group_id: the group id |
||
| 3582 | * @param group_artifact_id: the artifact type ID |
||
| 3583 | * @param ascii: ascii mode |
||
| 3584 | * |
||
| 3585 | * @return void |
||
| 3586 | */ |
||
| 3587 | function showAttachedFiles ($group_id,$group_artifact_id,$ascii=false, $pv = 0) { |
||
| 3588 | |||
| 3589 | global $Language; |
||
| 3590 | $hp = $this->getHtmlPurifier(); |
||
| 3591 | // |
||
| 3592 | // show the files attached to this artifact |
||
| 3593 | // |
||
| 3594 | |||
| 3595 | $result=$this->getAttachedFiles(); |
||
| 3596 | $rows=db_numrows($result); |
||
| 3597 | |||
| 3598 | // No file attached -> return now |
||
| 3599 | if ($rows <= 0) { |
||
| 3600 | if ($ascii) |
||
| 3601 | $out = $Language->getText('tracker_include_artifact','no_file_attached').$GLOBALS['sys_lf']; |
||
| 3602 | else |
||
| 3603 | $out = '<H4>'.$Language->getText('tracker_include_artifact','no_file_attached').'</H4>'; |
||
| 3604 | return $out; |
||
| 3605 | } |
||
| 3606 | |||
| 3607 | // Header first |
||
| 3608 | if ($ascii) { |
||
| 3609 | $out = $Language->getText('tracker_include_artifact','file_attachment').$GLOBALS['sys_lf'].str_repeat("*",strlen($Language->getText('tracker_include_artifact','file_attachment'))); |
||
| 3610 | } else { |
||
| 3611 | |||
| 3612 | $title_arr=array(); |
||
| 3613 | $title_arr[]=$Language->getText('tracker_include_artifact','name'); |
||
| 3614 | $title_arr[]=$Language->getText('tracker_include_artifact','desc'); |
||
| 3615 | $title_arr[]=$Language->getText('tracker_include_artifact','size_kb'); |
||
| 3616 | $title_arr[]=$Language->getText('global','by'); |
||
| 3617 | $title_arr[]=$Language->getText('tracker_include_artifact','posted_on'); |
||
| 3618 | if ($pv == 0) { |
||
| 3619 | $title_arr[]=$Language->getText('tracker_include_canned','delete'); |
||
| 3620 | } |
||
| 3621 | |||
| 3622 | $out = html_build_list_table_top ($title_arr); |
||
| 3623 | } |
||
| 3624 | |||
| 3625 | // Determine what the print out format is based on output type (Ascii, HTML) |
||
| 3626 | if ($ascii) { |
||
| 3627 | $fmt = $GLOBALS['sys_lf'] . $GLOBALS['sys_lf'] ."------------------------------------------------------------------". $GLOBALS['sys_lf']. |
||
| 3628 | $Language->getText('tracker_import_utils','date').": %s ".$Language->getText('tracker_include_artifact','name').": %s ".$Language->getText('tracker_include_artifact','size').": %dKB ".$Language->getText('global','by').": %s". $GLOBALS['sys_lf'] ."%s". $GLOBALS['sys_lf'] ."%s"; |
||
| 3629 | } else { |
||
| 3630 | $fmt = "". $GLOBALS['sys_lf'] . '<TR class="%s"><td>%s</td><td>%s</td><td align="center">%s</td><td align="center">%s</td><td align="center">%s</td>'; |
||
| 3631 | if ($pv == 0) { |
||
| 3632 | $fmt .= '<td align="center">%s</td>'; |
||
| 3633 | } |
||
| 3634 | $fmt .= '</tr>'; |
||
| 3635 | } |
||
| 3636 | |||
| 3637 | // Determine which protocl to use for embedded URL in ASCII format |
||
| 3638 | $server=get_server_url(); |
||
| 3639 | |||
| 3640 | // Loop throuh the attached files and format them |
||
| 3641 | for ($i=0; $i < $rows; $i++) { |
||
| 3642 | |||
| 3643 | $artifact_file_id = db_result($result, $i, 'id'); |
||
| 3644 | $href = "/tracker/download.php?artifact_id=".(int)$this->getID()."&id=".(int)$artifact_file_id; |
||
| 3645 | |||
| 3646 | if ($ascii) { |
||
| 3647 | $out .= sprintf($fmt, |
||
| 3648 | format_date($GLOBALS['Language']->getText('system', 'datefmt'),db_result($result, $i, 'adddate')), |
||
| 3649 | db_result($result, $i, 'filename') , |
||
| 3650 | intval(db_result($result, $i, 'filesize')/1024), |
||
| 3651 | db_result($result, $i, 'user_name'), |
||
| 3652 | SimpleSanitizer::unsanitize(db_result($result, $i, 'description')), |
||
| 3653 | $server.$href); |
||
| 3654 | } else { |
||
| 3655 | // show CC delete icon if one of the condition is met: |
||
| 3656 | // (a) current user is group member |
||
| 3657 | // (b) the current user is the person who added a gieven name in CC list |
||
| 3658 | if ( user_ismember($this->ArtifactType->getGroupID()) || |
||
| 3659 | (user_getname(user_getid()) == db_result($result, $i, 'user_name') )) { |
||
| 3660 | $html_delete = '<a href="?func=delete_file&group_id='.(int)$group_id."&atid=".(int)$group_artifact_id."&aid=".(int)$this->getID()."&id=".(int)db_result($result, $i, 'id').'" '. |
||
| 3661 | ' onClick="return confirm(\''.$Language->getText('tracker_include_artifact','delete_attachment').'\')">'. |
||
| 3662 | '<IMG SRC="'.util_get_image_theme("ic/trash.png").'" HEIGHT="16" WIDTH="16" BORDER="0" ALT="'.$Language->getText('global','btn_delete').'"></A>'; |
||
| 3663 | } else { |
||
| 3664 | $html_delete = '-'; |
||
| 3665 | } |
||
| 3666 | $out .= sprintf($fmt, |
||
| 3667 | util_get_alt_row_color($i), |
||
| 3668 | '<a href="'.$href.'">'. $hp->purify(db_result($result, $i, 'filename'), CODENDI_PURIFIER_CONVERT_HTML) .'</a>', |
||
| 3669 | $hp->purify(SimpleSanitizer::unsanitize(db_result($result, $i, 'description')), CODENDI_PURIFIER_BASIC, $group_id) , |
||
| 3670 | intval(db_result($result, $i, 'filesize')/1024), |
||
| 3671 | util_user_link(db_result($result, $i, 'user_name')), |
||
| 3672 | format_date($GLOBALS['Language']->getText('system', 'datefmt'),db_result($result, $i, 'adddate')), |
||
| 3673 | $html_delete); |
||
| 3674 | } |
||
| 3675 | } // for |
||
| 3676 | |||
| 3677 | // final touch... |
||
| 3678 | $out .= ($ascii ? "". $GLOBALS['sys_lf'] ."" : "</TABLE>"); |
||
| 3679 | |||
| 3680 | return($out); |
||
| 3681 | |||
| 3682 | } |
||
| 3683 | |||
| 3684 | /** Update the last_update_date field in the Artifact table to 'now' |
||
| 3685 | */ |
||
| 3686 | function update_last_update_date() { |
||
| 3687 | $sql="UPDATE artifact SET last_update_date=".time(). |
||
| 3688 | " WHERE artifact_id=". db_ei($this->getID()) ; |
||
| 3689 | |||
| 3690 | return db_query($sql); |
||
| 3691 | } |
||
| 3692 | |||
| 3693 | /** |
||
| 3694 | * Returns an instance of Codendi_HTMLPurifier |
||
| 3695 | * |
||
| 3696 | * @return Codendi_HTMLPurifier |
||
| 3697 | */ |
||
| 3698 | public function getHTMLPurifier() { |
||
| 3701 | |||
| 3702 | /** |
||
| 3703 | * Format the comment text to a given format according to parameters |
||
| 3704 | * |
||
| 3705 | * @param Integer $groupId Project id |
||
| 3706 | * @param Boolean $commentFormat $value's format |
||
| 3707 | * @param String $value Comment content |
||
| 3708 | * @param Boolean $output Output format |
||
| 3709 | * |
||
| 3710 | * @return String |
||
| 3711 | */ |
||
| 3712 | public function formatFollowUp($groupId, $commentFormat, $value, $output) { |
||
| 3713 | $commentText = ''; |
||
| 3714 | if ($output == self::OUTPUT_EXPORT) { |
||
| 3715 | return util_unconvert_htmlspecialchars($value); |
||
| 3716 | } else { |
||
| 3717 | $hp = $this->getHTMLPurifier(); |
||
| 3718 | if ($output == self::OUTPUT_MAIL_TEXT) { |
||
| 3719 | if ($commentFormat == self::FORMAT_HTML){ |
||
| 3720 | $commentText = $hp->purify(util_unconvert_htmlspecialchars($value), CODENDI_PURIFIER_STRIP_HTML); |
||
| 3721 | } else { |
||
| 3722 | $commentText = $value; |
||
| 3723 | } |
||
| 3724 | $commentText = util_unconvert_htmlspecialchars($commentText); |
||
| 3725 | } else { |
||
| 3726 | if ($commentFormat == self::FORMAT_HTML) { |
||
| 3727 | $level = CODENDI_PURIFIER_LIGHT; |
||
| 3728 | } else { |
||
| 3729 | $level = CODENDI_PURIFIER_BASIC; |
||
| 3730 | } |
||
| 3731 | $commentText = $hp->purify(util_unconvert_htmlspecialchars($value), $level, $groupId); |
||
| 3732 | } |
||
| 3733 | return $commentText; |
||
| 3734 | } |
||
| 3735 | } |
||
| 3736 | |||
| 3737 | } |
||
| 3738 | |||
| 3739 | ?> |
||
| 3740 |
This checks looks for assignemnts to variables using the
list(...)function, where not all assigned variables are subsequently used.Consider the following code example.
Only the variables
$aand$care used. There was no need to assign$b.Instead, the list call could have been.