1<?php 2/*========================================================================= 3 4 Program: CDash - Cross-Platform Dashboard System 5 Module: $Id$ 6 Language: PHP 7 Date: $Date$ 8 Version: $Revision$ 9 10 Copyright (c) 2002 Kitware, Inc. All rights reserved. 11 See Copyright.txt or http://www.cmake.org/HTML/Copyright.html for details. 12 13 This software is distributed WITHOUT ANY WARRANTY; without even 14 the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR 15 PURPOSE. See the above copyright notices for more information. 16 17=========================================================================*/ 18require_once("cdash/cdashmail.php"); 19 20 21/** Check the email preferences for errors */ 22function checkEmailPreferences($emailcategory,$errors,$fixes=false) 23{ 24 include_once("cdash/common.php"); 25 26 if($fixes) 27 { 28 $updates = 0; // for fixes we don't use update 29 $configures=$errors['fixes']['configure_fixes']; 30 $builderrors=$errors['fixes']['builderror_fixes']; 31 $buildwarnings=$errors['fixes']['buildwarning_fixes']; 32 $tests=$errors['fixes']['test_fixes']; 33 } 34 else 35 { 36 $updates=$errors['update_errors']; 37 $configures=$errors['configure_errors']; 38 $builderrors=$errors['build_errors']; 39 $buildwarnings=$errors['build_warnings']; 40 $tests=$errors['test_errors']; 41 $dynamicanalysis=$errors['dynamicanalysis_errors']; 42 } 43 44 if($configures>0 && check_email_category("configure",$emailcategory)) 45 { 46 return true; 47 } 48 if($buildwarnings>0 && check_email_category("warning",$emailcategory)) 49 { 50 return true; 51 } 52 if($builderrors>0 && check_email_category("error",$emailcategory)) 53 { 54 return true; 55 } 56 if($tests>0 && check_email_category("test",$emailcategory)) 57 { 58 return true; 59 } 60 if($dynamicanalysis>0 && check_email_category("dynamicanalysis",$emailcategory)) 61 { 62 return true; 63 } 64 return false; 65} 66 67/** Given a user check if we should send an email based on labels */ 68function checkEmailLabel($projectid, $userid, $buildid, $emailcategory=62) 69{ 70 include_once("models/labelemail.php"); 71 include_once("models/build.php"); 72 $LabelEmail = new LabelEmail(); 73 $LabelEmail->UserId = $userid; 74 $LabelEmail->ProjectId = $projectid; 75 76 $labels = $LabelEmail->GetLabels(); 77 if(count($labels)==0) // if the number of subscribed labels is zero we send the email 78 { 79 return true; 80 } 81 82 $Build = new Build(); 83 $Build->Id = $buildid; 84 85 $labelarray = array(); 86 87 if(check_email_category("update",$emailcategory)) 88 { 89 $labelarray['update']['errors']=1; 90 } 91 if(check_email_category("configure",$emailcategory)) 92 { 93 $labelarray['configure']['errors']=1; 94 } 95 if(check_email_category("warning",$emailcategory)) 96 { 97 $labelarray['build']['warnings']=1; 98 } 99 if(check_email_category("error",$emailcategory)) 100 { 101 $labelarray['build']['errors']=1; 102 } 103 if(check_email_category("test",$emailcategory)) 104 { 105 $labelarray['test']['errors']=1; 106 } 107 108 $buildlabels = $Build->GetLabels($labelarray); 109 if(count(array_intersect($labels, $buildlabels))>0) 110 { 111 return true; 112 } 113 return false; 114} // end checkEmailLabel 115 116/** Check for errors for a given build. Return false if no errors */ 117function check_email_errors($buildid,$checktesttimeingchanged,$testtimemaxstatus,$checkpreviouserrors) 118{ 119 // Includes 120 require_once("models/buildupdate.php"); 121 require_once("models/buildconfigure.php"); 122 require_once("models/build.php"); 123 require_once("models/buildtest.php"); 124 require_once("models/dynamicanalysis.php"); 125 126 $errors = array(); 127 $errors['errors'] = true; 128 $errors['hasfixes'] = false; 129 130 // Update errors 131 $BuildUpdate = new BuildUpdate(); 132 $BuildUpdate->BuildId = $buildid; 133 $errors['update_errors'] = $BuildUpdate->GetNumberOfErrors(); 134 135 // Configure errors 136 $BuildConfigure = new BuildConfigure(); 137 $BuildConfigure->BuildId = $buildid; 138 $errors['configure_errors'] = $BuildConfigure->GetNumberOfErrors(); 139 140 // Build errors and warnings 141 $Build = new Build(); 142 $Build->Id = $buildid; 143 $Build->FillFromId($buildid); 144 $errors['build_errors'] = $Build->GetNumberOfErrors(); 145 $errors['build_warnings'] = $Build->GetNumberOfWarnings(); 146 147 // Test errors 148 $BuildTest = new BuildTest(); 149 $BuildTest->BuildId = $buildid; 150 $errors['test_errors'] = $BuildTest->GetNumberOfFailures($checktesttimeingchanged,$testtimemaxstatus); 151 152 // Dynamic analysis errors 153 $DynamicAnalysis = new DynamicAnalysis(); 154 $DynamicAnalysis->BuildId = $buildid; 155 $errors['dynamicanalysis_errors'] = $DynamicAnalysis->GetNumberOfErrors(); 156 157 // Green build we return 158 if( $errors['update_errors'] == 0 159 && $errors['configure_errors'] == 0 160 && $errors['build_errors'] == 0 161 && $errors['build_warnings'] ==0 162 && $errors['test_errors'] ==0 163 && $errors['dynamicanalysis_errors'] == 0) 164 { 165 $errors['errors'] = false; 166 } 167 168 169 // look for the previous build 170 $previousbuildid = $Build->GetPreviousBuildId(); 171 if($previousbuildid > 0) 172 { 173 $error_differences = $Build->GetErrorDifferences($buildid); 174 if($errors['errors'] && $checkpreviouserrors && $errors['dynamicanalysis_errors'] == 0) 175 { 176 // If the builderroddiff positive and configureerrordiff and testdiff positive are zero we don't send an email 177 // we don't send any emails 178 if($error_differences['buildwarningspositive']<=0 179 && $error_differences['builderrorspositive']<=0 180 && $error_differences['configurewarnings']<=0 181 && $error_differences['configureerrors']<=0 182 && $error_differences['testfailedpositive']<=0 183 && $error_differences['testnotrunpositive']<=0 184 ) 185 { 186 $errors['errors'] = false; 187 } 188 } // end checking previous errors 189 190 if($error_differences['buildwarningsnegative']>0 191 || $error_differences['builderrorsnegative']>0 192 || $error_differences['configurewarnings']<0 193 || $error_differences['configureerrors']<0 194 || $error_differences['testfailednegative']>0 195 || $error_differences['testnotrunnegative']>0 196 ) 197 { 198 $errors['hasfixes'] = true; 199 $errors['fixes']['configure_fixes'] = $error_differences['configurewarnings']+$error_differences['configureerrors']; 200 $errors['fixes']['builderror_fixes'] = $error_differences['builderrorsnegative']; 201 $errors['fixes']['buildwarning_fixes'] = $error_differences['buildwarningsnegative']; 202 $errors['fixes']['test_fixes'] = $error_differences['testfailednegative']+$error_differences['testnotrunnegative']; 203 } 204 } // end has previous build 205 206 return $errors; 207} 208 209/** Check for update errors for a given build. */ 210function check_email_update_errors($buildid) 211{ 212 // Includes 213 require_once("models/buildupdate.php"); 214 require_once("models/build.php"); 215 216 $errors = array(); 217 $errors['errors'] = true; 218 $errors['hasfixes'] = false; 219 220 // Update errors 221 $BuildUpdate = new BuildUpdate(); 222 $BuildUpdate->BuildId = $buildid; 223 $errors['update_errors'] = $BuildUpdate->GetNumberOfErrors(); 224 225 // Green build we return 226 if( $errors['update_errors'] == 0 ) 227 { 228 $errors['errors'] = false; 229 } 230 231 return $errors; 232} 233 234 235/** Return the list of user id and committer emails who should get emails */ 236function lookup_emails_to_send($errors, $buildid, $projectid, $buildtype, $fixes=false, $collectUnregisteredCommitters=false) 237{ 238 require_once("models/userproject.php"); 239 240 $userids = array(); 241 $committeremails = array(); 242 243 // Check if we know to whom we should send the email 244 $updatefiles = pdo_query("SELECT author,email,committeremail FROM updatefile AS uf,build2update AS b2u 245 WHERE b2u.updateid=uf.updateid AND b2u.buildid=".qnum($buildid)); 246 add_last_sql_error("sendmail",$projectid,$buildid); 247 while($updatefiles_array = pdo_fetch_array($updatefiles)) 248 { 249 $author = $updatefiles_array["author"]; 250 251 // Skip the Local User, old CVS/SVN issue 252 if($author=="Local User") 253 { 254 continue; 255 } 256 257 $emails = array(); 258 $authorEmail = $updatefiles_array["email"]; 259 $emails[] = $authorEmail; 260 $committerEmail = $updatefiles_array["committeremail"]; 261 if($committerEmail != '' && $committerEmail != $authorEmail) 262 { 263 $emails[] = $committerEmail; 264 } 265 266 foreach($emails as $email) 267 { 268 $UserProject = new UserProject(); 269 $UserProject->RepositoryCredential = $author; 270 $UserProject->ProjectId = $projectid; 271 272 $filled = false; 273 if($email != '') 274 { 275 $result = pdo_query("SELECT id FROM ".qid("user")." WHERE email='$email'"); 276 277 if(pdo_num_rows($result) != 0) 278 { 279 $user_array = pdo_fetch_array($result); 280 $id = $user_array['id']; 281 $UserProject->UserId = $id; 282 $filled = $UserProject->FillFromUserId(); 283 } 284 } 285 286 if(!$filled && !$UserProject->FillFromRepositoryCredential()) 287 { 288 global $CDASH_WARN_ABOUT_UNREGISTERED_COMMITTERS; 289 global $CDASH_TESTING_MODE; 290 if (!$CDASH_TESTING_MODE && $CDASH_WARN_ABOUT_UNREGISTERED_COMMITTERS) 291 { 292 $name = $email == '' ? $author : $email; 293 // Daily updates send an email to tell adminsitrator that the user 294 // is not registered but we log anyway 295 add_log("User: ".$name." is not registered (or has no email) for the project ".$projectid, 296 "SendEmail", LOG_WARNING, $projectid, $buildid); 297 } 298 if ($collectUnregisteredCommitters && $email != '' && 299 !in_array($email, $committeremails)) 300 { 301 $committeremails[] = $email; 302 } 303 continue; 304 } 305 306 // If we already have this user in the array, don't bother checking 307 // user preferences again... (avoid below calls to checkEmail* 308 // functions) 309 if(in_array($UserProject->UserId, $userids)) 310 { 311 continue; 312 } 313 314 // If the user doesn't want to receive email 315 if($fixes && !$UserProject->EmailSuccess) 316 { 317 continue; 318 } 319 320 // Check the categories 321 if(!checkEmailPreferences($UserProject->EmailCategory,$errors,$fixes)) 322 { 323 continue; 324 } 325 326 // Check if the labels are defined for this user 327 if(!checkEmailLabel($projectid,$UserProject->UserId, $buildid, $UserProject->EmailCategory)) 328 { 329 continue; 330 } 331 332 $userids[] = $UserProject->UserId; 333 } 334 } 335 336 // If it's fixes only concerned users should get the email 337 if($fixes) 338 { 339 $result = array(); 340 $result['userids'] = $userids; 341 $result['committeremails'] = $committeremails; 342 return $result; 343 } 344 345 // Select the users who want to receive all emails 346 $user = pdo_query("SELECT emailtype,emailcategory,userid FROM user2project WHERE user2project.projectid=".qnum($projectid)." AND user2project.emailtype>1"); 347 add_last_sql_error("sendmail"); 348 while($user_array = pdo_fetch_array($user)) 349 { 350 if(in_array($user_array["userid"],$userids)) 351 { 352 continue; 353 } 354 355 // If the user doesn't want to receive email 356 if(!checkEmailPreferences($user_array["emailcategory"],$errors)) 357 { 358 continue; 359 } 360 361 // Check if the labels are defined for this user 362 if(!checkEmailLabel($projectid,$user_array['userid'],$buildid, $user_array["emailcategory"])) 363 { 364 continue; 365 } 366 367 // Nightly build notification 368 if($user_array["emailtype"] == 2 && $buildtype=="Nightly") 369 { 370 $userids[] = $user_array["userid"]; 371 } 372 else if($user_array["emailtype"] == 3) // want to receive all emails 373 { 374 $userids[] = $user_array["userid"]; 375 } 376 } 377 378 $result = array(); 379 $result['userids'] = $userids; 380 $result['committeremails'] = $committeremails; 381 return $result; 382 383} // end lookup_emails_to_send 384 385 386/** Return a summary for a category of error */ 387function get_email_summary($buildid,$errors,$errorkey,$maxitems,$maxchars,$testtimemaxstatus,$emailtesttimingchanged) 388{ 389 include("cdash/config.php"); 390 391 $serverURI = get_server_URI(); 392 // In the case of asynchronous submission, the serverURI contains /cdash 393 // we need to remove it 394 if($CDASH_BASE_URL=='' && $CDASH_ASYNCHRONOUS_SUBMISSION) 395 { 396 $serverURI = substr($serverURI,0,strrpos($serverURI,"/")); 397 } 398 399 $information = ""; 400 401 // Update information 402 if($errorkey == 'update_errors') 403 { 404 $information = "\n\n*Update*\n"; 405 406 $update = pdo_query("SELECT command,status FROM buildupdate AS u,build2update AS b2u 407 WHERE b2u.updateid=u.id AND b2u.buildid=".qnum($buildid)); 408 $update_array = pdo_fetch_array($update); 409 410 $information .= "Status: ".$update_array["status"]." (".$serverURI."/viewUpdate.php?buildid=".$buildid.")\n"; 411 $information .= "Command: "; 412 $information .= substr($update_array["command"],0,$maxchars); 413 $information .= "\n"; 414 } // endconfigure 415 else if($errorkey == 'configure_errors') // Configure information 416 { 417 $information = "\n\n*Configure*\n"; 418 419 $configure = pdo_query("SELECT status,log FROM configure WHERE buildid=".qnum($buildid)); 420 $configure_array = pdo_fetch_array($configure); 421 422 $information .= "Status: ".$configure_array["status"]." (".$serverURI."/viewConfigure.php?buildid=".$buildid.")\n"; 423 $information .= "Output: "; 424 $information .= substr($configure_array["log"],0,$maxchars); 425 $information .= "\n"; 426 } // endconfigure 427 else if($errorkey == 'build_errors') 428 { 429 $information .= "\n\n*Error*"; 430 431 // Old error format 432 $error_query = pdo_query("SELECT sourcefile,text,sourceline,postcontext FROM builderror WHERE buildid=".qnum($buildid)." AND type=0 LIMIT $maxitems"); 433 add_last_sql_error("sendmail"); 434 435 if(pdo_num_rows($error_query) == $maxitems) 436 { 437 $information .= " (first ".$maxitems.")"; 438 } 439 $information .= "\n"; 440 441 while($error_array = pdo_fetch_array($error_query)) 442 { 443 $info = ""; 444 if(strlen($error_array["sourcefile"])>0) 445 { 446 $info .= $error_array["sourcefile"]." line ".$error_array["sourceline"]." (".$serverURI."/viewBuildError.php?type=0&buildid=".$buildid.")\n"; 447 $info .= $error_array["text"]."\n"; 448 } 449 else 450 { 451 $info .= $error_array["text"]."\n".$error_array["postcontext"]."\n"; 452 } 453 $information .= substr($info,0,$maxchars); 454 } 455 456 // New error format 457 $error_query = pdo_query("SELECT sourcefile,stdoutput,stderror FROM buildfailure WHERE buildid=".qnum($buildid)." AND type=0 LIMIT $maxitems"); 458 add_last_sql_error("sendmail"); 459 while($error_array = pdo_fetch_array($error_query)) 460 { 461 $info = ""; 462 if(strlen($error_array["sourcefile"])>0) 463 { 464 $info .= $error_array["sourcefile"]." (".$serverURI."/viewBuildError.php?type=0&buildid=".$buildid.")\n"; 465 } 466 if(strlen($error_array["stdoutput"])>0) 467 { 468 $info .= $error_array["stdoutput"]."\n"; 469 } 470 if(strlen($error_array["stderror"])>0) 471 { 472 $info .= $error_array["stderror"]."\n"; 473 } 474 $information .= substr($info,0,$maxchars); 475 } 476 $information .= "\n"; 477 } 478 else if($errorkey == 'build_warnings') 479 { 480 $information .= "\n\n*Warnings*"; 481 482 $error_query = pdo_query("SELECT sourcefile,text,sourceline,postcontext FROM builderror 483 WHERE buildid=".qnum($buildid)." AND type=1 ORDER BY logline LIMIT $maxitems"); 484 add_last_sql_error("sendmail"); 485 486 if(pdo_num_rows($error_query) == $maxitems) 487 { 488 $information .= " (first ".$maxitems.")"; 489 } 490 $information .= "\n"; 491 492 while($error_array = pdo_fetch_array($error_query)) 493 { 494 $info = ""; 495 if(strlen($error_array["sourcefile"])>0) 496 { 497 $info .= $error_array["sourcefile"]." line ".$error_array["sourceline"]." (".$serverURI."/viewBuildError.php?type=1&buildid=".$buildid.")\n"; 498 $info .= $error_array["text"]."\n"; 499 } 500 else 501 { 502 $info .= $error_array["text"]."\n".$error_array["postcontext"]."\n"; 503 } 504 $information .= substr($info,0,$maxchars); 505 } 506 507 // New error format 508 $error_query = pdo_query("SELECT sourcefile,stdoutput,stderror FROM buildfailure WHERE buildid=".qnum($buildid). 509 " AND type=1 ORDER BY id LIMIT $maxitems"); 510 add_last_sql_error("sendmail"); 511 while($error_array = pdo_fetch_array($error_query)) 512 { 513 $info = ""; 514 if(strlen($error_array["sourcefile"])>0) 515 { 516 $info .= $error_array["sourcefile"]." (".$serverURI."/viewBuildError.php?type=1&buildid=".$buildid.")\n"; 517 } 518 if(strlen($error_array["stdoutput"])>0) 519 { 520 $info .= $error_array["stdoutput"]."\n"; 521 } 522 if(strlen($error_array["stderror"])>0) 523 { 524 $info .= $error_array["stderror"]."\n"; 525 } 526 $information .= substr($info,0,$maxchars)."\n"; 527 } 528 $information .= "\n"; 529 } 530 else if($errorkey == 'test_errors') 531 { 532 $sql = ""; 533 if($emailtesttimingchanged) 534 { 535 $sql = "OR timestatus>".qnum($testtimemaxstatus); 536 } 537 $test_query = pdo_query("SELECT test.name,test.id FROM build2test,test WHERE build2test.buildid=".qnum($buildid). 538 " AND test.id=build2test.testid AND (build2test.status='failed'".$sql.") ORDER BY test.id LIMIT $maxitems"); 539 add_last_sql_error("sendmail"); 540 $numrows = pdo_num_rows($test_query); 541 542 if($numrows>0) 543 { 544 $information .= "\n\n*Tests failing*"; 545 if(pdo_num_rows($test_query) == $maxitems) 546 { 547 $information .= " (first ".$maxitems.")"; 548 } 549 $information .= "\n"; 550 551 while($test_array = pdo_fetch_array($test_query)) 552 { 553 $info = $test_array["name"]." (".$serverURI."/testDetails.php?test=".$test_array["id"]."&build=".$buildid.")\n"; 554 $information .= substr($info,0,$maxchars); 555 } 556 $information .= "\n"; 557 } // end test failing > 0 558 559 // Add the tests not run 560 $test_query = pdo_query("SELECT test.name,test.id FROM build2test,test WHERE build2test.buildid=".qnum($buildid). 561 " AND test.id=build2test.testid AND (build2test.status='notrun'".$sql.") ORDER BY test.id LIMIT $maxitems"); 562 add_last_sql_error("sendmail"); 563 $numrows = pdo_num_rows($test_query); 564 565 if($numrows>0) 566 { 567 $information .= "\n\n*Tests not run*"; 568 if(pdo_num_rows($test_query) == $maxitems) 569 { 570 $information .= " (first ".$maxitems.")"; 571 } 572 $information .= "\n"; 573 574 while($test_array = pdo_fetch_array($test_query)) 575 { 576 $info = $test_array["name"]." (".$serverURI."/testDetails.php?test=".$test_array["id"]."&build=".$buildid.")\n"; 577 $information .= substr($info,0,$maxchars); 578 } 579 $information .= "\n"; 580 } // end test not run > 0 581 } 582 else if($errorkey == "dynamicanalysis_errors") 583 { 584 $da_query = pdo_query("SELECT name,id FROM dynamicanalysis WHERE status IN ('failed','notrun') AND buildid=" 585 .qnum($buildid)." ORDER BY name LIMIT $maxitems"); 586 add_last_sql_error("sendmail"); 587 $numrows = pdo_num_rows($da_query); 588 589 if($numrows>0) 590 { 591 $information .= "\n\n*Dynamic analysis tests failing or not run*"; 592 if($numrows == $maxitems) 593 { 594 $information .= " (first ".$maxitems.")"; 595 } 596 $information .= "\n"; 597 598 while($test_array = pdo_fetch_array($da_query)) 599 { 600 $info = $test_array["name"]." (".$serverURI."/viewDynamicAnalysisFile.php?id=".$test_array["id"].")\n"; 601 $information .= substr($info,0,$maxchars); 602 } 603 $information .= "\n"; 604 } // end test failing > 0 605 } 606 607 return $information; 608} // end get_email_summary 609 610 611/** Send a summary email */ 612function sendsummaryemail($projectid,$groupid,$errors,$buildid) 613{ 614 include("cdash/config.php"); 615 require_once("models/userproject.php"); 616 require_once("models/user.php"); 617 require_once("models/project.php"); 618 619 $Project = new Project(); 620 $Project->Id = $projectid; 621 $Project->Fill(); 622 623 // Check if the email has been sent 624 $date = ""; // now 625 list ($previousdate, $currentstarttime, $nextdate, $today) = get_dates($date,$Project->NightlyTime); 626 $dashboarddate = gmdate(FMT_DATE, $currentstarttime); 627 628 // If we already have it we return 629 if(pdo_num_rows(pdo_query("SELECT buildid FROM summaryemail WHERE date='$dashboarddate' AND groupid=".qnum($groupid)))==1) 630 { 631 return; 632 } 633 634 // Update the summaryemail table to specify that we have send the email 635 // We also delete any previous rows from that groupid 636 pdo_query("DELETE FROM summaryemail WHERE groupid=$groupid"); 637 pdo_query("INSERT INTO summaryemail (buildid,date,groupid) VALUES ($buildid,'$dashboarddate',$groupid)"); 638 add_last_sql_error("sendmail"); 639 640 // If the trigger for SVN/CVS diff is not done yet we specify that the asynchronous trigger should 641 // send an email 642 $dailyupdatequery = pdo_query("SELECT status FROM dailyupdate WHERE projectid=".qnum($projectid)." AND date='$dashboarddate'"); 643 add_last_sql_error("sendmail"); 644 645 if(pdo_num_rows($dailyupdatequery) == 0) 646 { 647 return; 648 } 649 650 $dailyupdate_array = pdo_fetch_array($dailyupdatequery); 651 $dailyupdate_status = $dailyupdate_array['status']; 652 if($dailyupdate_status == 0) 653 { 654 pdo_query("UPDATE dailyupdate SET status='2' WHERE projectid=".qnum($projectid)." AND date='$dashboarddate'"); 655 return; 656 } 657 658 // Find the current updaters from the night using the dailyupdatefile table 659 $summaryEmail = ""; 660 $query = "SELECT ".qid("user").".email,up.emailcategory,".qid("user").".id 661 FROM ".qid("user").",user2project AS up,user2repository AS ur, 662 dailyupdate,dailyupdatefile WHERE 663 up.projectid=".qnum($projectid)." 664 AND up.userid=".qid("user").".id 665 AND ur.userid=up.userid 666 AND (ur.projectid=0 OR ur.projectid=".qnum($projectid).") 667 AND ur.credential=dailyupdatefile.author 668 AND dailyupdatefile.dailyupdateid=dailyupdate.id 669 AND dailyupdate.date='$dashboarddate' 670 AND dailyupdate.projectid=".qnum($projectid)." 671 AND up.emailtype>0 672 "; 673 $user = pdo_query($query); 674 add_last_sql_error("sendmail"); 675 676 // Loop through the users and add them to the email array 677 while($user_array = pdo_fetch_array($user)) 678 { 679 // If the user is already in the list we quit 680 if(strpos($summaryEmail,$user_array["email"]) !== false) 681 { 682 continue; 683 } 684 685 // If the user doesn't want to receive email 686 if(!checkEmailPreferences($user_array["emailcategory"],$errors)) 687 { 688 continue; 689 } 690 691 // Check if the labels are defined for this user 692 if(!checkEmailLabel($projectid, $user_array["id"], $buildid, $user_array["emailcategory"])) 693 { 694 continue; 695 } 696 697 if($summaryEmail != "") 698 { 699 $summaryEmail .= ", "; 700 } 701 $summaryEmail .= $user_array["email"]; 702 } 703 704 // Select the users that are part of this build 705 $authors = pdo_query("SELECT author FROM updatefile AS uf,build2update AS b2u 706 WHERE b2u.updateid=uf.updateid AND b2u.buildid=".qnum($buildid)); 707 add_last_sql_error("sendmail"); 708 while($authors_array = pdo_fetch_array($authors)) 709 { 710 $author = $authors_array["author"]; 711 if($author=="Local User") 712 { 713 continue; 714 } 715 716 $UserProject = new UserProject(); 717 $UserProject->RepositoryCredential = $author; 718 $UserProject->ProjectId = $projectid; 719 720 if(!$UserProject->FillFromRepositoryCredential()) 721 { 722 continue; 723 } 724 725 // If the user doesn't want to receive email 726 if(!checkEmailPreferences($UserProject->EmailCategory,$errors)) 727 { 728 continue; 729 } 730 731 // Check if the labels are defined for this user 732 if(!checkEmailLabel($projectid,$UserProject->UserId, $buildid, $UserProject->EmailCategory)) 733 { 734 continue; 735 } 736 737 // Find the email 738 $User = new User(); 739 $User->Id = $UserProject->UserId; 740 $useremail = $User->GetEmail(); 741 742 // If the user is already in the list we quit 743 if(strpos($summaryEmail,$useremail) !== false) 744 { 745 continue; 746 } 747 748 if($summaryEmail != "") 749 { 750 $summaryEmail .= ", "; 751 } 752 $summaryEmail .= $useremail; 753 } 754 755 // In the case of asynchronous submission, the serverURI contains /cdash 756 // we need to remove it 757 $currentURI = get_server_URI(); 758 if($CDASH_BASE_URL=='' && $CDASH_ASYNCHRONOUS_SUBMISSION) 759 { 760 $currentURI = substr($currentURI,0,strrpos($currentURI,"/")); 761 } 762 763 // Select the users who want to receive all emails 764 $user = pdo_query("SELECT ".qid("user").".email,user2project.emailtype,".qid("user").".id FROM ".qid("user").",user2project 765 WHERE user2project.projectid=".qnum($projectid)." 766 AND user2project.userid=".qid("user").".id AND user2project.emailtype>1"); 767 add_last_sql_error("sendsummaryemail"); 768 while($user_array = pdo_fetch_array($user)) 769 { 770 // If the user is already in the list we quit 771 if(strpos($summaryEmail,$user_array["email"]) !== false) 772 { 773 continue; 774 } 775 776 // Check if the labels are defined for this user 777 if(!checkEmailLabel($projectid, $user_array["id"], $buildid)) 778 { 779 continue; 780 } 781 782 if($summaryEmail != "") 783 { 784 $summaryEmail .= ", "; 785 } 786 $summaryEmail .= $user_array["email"]; 787 } 788 789 // Send the email 790 if($summaryEmail != "") 791 { 792 $summaryemail_array = pdo_fetch_array(pdo_query("SELECT name FROM buildgroup WHERE id=$groupid")); 793 add_last_sql_error("sendsummaryemail"); 794 795 $title = "CDash [".$Project->Name."] - ".$summaryemail_array["name"]." Failures"; 796 797 $messagePlainText = "The \"".$summaryemail_array["name"]."\" group has either errors, warnings or test failures.\n"; 798 $messagePlainText .= "You have been identified as one of the authors who have checked in changes that are part of this submission "; 799 $messagePlainText .= "or you are listed in the default contact list.\n\n"; 800 801 $messagePlainText .= "To see this dashboard:\n"; 802 $messagePlainText .= $currentURI; 803 $messagePlainText .= "/index.php?project=".urlencode($Project->Name)."&date=".$today; 804 $messagePlainText .= "\n\n"; 805 806 $messagePlainText .= "Summary of the first build failure:\n"; 807 // Check if an email has been sent already for this user 808 foreach($errors as $errorkey => $nerrors) 809 { 810 $messagePlainText .= get_email_summary($buildid,$errors,$errorkey,$Project->EmailMaxItems, 811 $Project->EmailMaxChars,$Project->TestTimeMaxStatus, 812 $Project->EmailTestTimingChanged); 813 } 814 $messagePlainText .= "\n\n"; 815 816 $serverName = $CDASH_SERVER_NAME; 817 if(strlen($serverName) == 0) 818 { 819 $serverName = $_SERVER['SERVER_NAME']; 820 } 821 822 $messagePlainText .= "\n-CDash on ".$serverName."\n"; 823 824 // If this is the testing 825 if($CDASH_TESTING_MODE) 826 { 827 add_log($summaryEmail,"TESTING: EMAIL",LOG_TESTING); 828 add_log($title,"TESTING: EMAILTITLE",LOG_TESTING); 829 add_log($messagePlainText,"TESTING: EMAILBODY",LOG_TESTING); 830 } 831 else 832 { 833 // Send the email 834 if(cdashmail("$summaryEmail", $title, $messagePlainText, 835 "From: CDash <".$CDASH_EMAIL_FROM.">\nReply-To: ".$CDASH_EMAIL_REPLY."\nContent-type: text/plain; charset=utf-8\nX-Mailer: PHP/" . phpversion()."\nMIME-Version: 1.0" )) 836 { 837 add_log("summary email sent to: ".$summaryEmail,"sendemail ".$Project->Name,LOG_INFO); 838 return; 839 } 840 else 841 { 842 add_log("cannot send summary email to: ".$summaryEmail,"sendemail ".$Project->Name,LOG_ERR); 843 } 844 } 845 } // end $summaryEmail!="" 846} 847 848/** Check if the email has already been sent for that category */ 849function set_email_sent($userid,$buildid,$emailtext) 850{ 851 foreach($emailtext['category'] as $key=>$value) 852 { 853 $category = 0; 854 switch($key) 855 { 856 case 'update_errors': $category=1; break; 857 case 'configure_errors': $category=2; break; 858 case 'build_warnings': $category=3; break; 859 case 'build_errors': $category=4; break; 860 case 'test_errors': $category=5; break; 861 case 'update_fixes': $category=6; break; 862 case 'configure_fixes': $category=7; break; 863 case 'buildwarning_fixes': $category=8; break; 864 case 'builderror_fixes': $category=9; break; 865 case 'test_fixes': $category=10; break; 866 case 'dynamicanalysis_errors': $category=11; break; 867 } 868 869 if($category>0) 870 { 871 $today = date(FMT_DATETIME); 872 pdo_query("INSERT INTO buildemail (userid,buildid,category,time) VALUES (".qnum($userid).",".qnum($buildid).",".qnum($category).",'".$today."')"); 873 add_last_sql_error("sendmail"); 874 } 875 } 876} 877 878/** Check if the email has already been sent for that category */ 879function check_email_sent($userid,$buildid,$errorkey) 880{ 881 if($userid == 0) 882 { 883 return false; 884 } 885 886 $category = 0; 887 switch($errorkey) 888 { 889 case 'update_errors': $category=1; break; 890 case 'configure_errors': $category=2; break; 891 case 'build_warnings': $category=3; break; 892 case 'build_errors': $category=4; break; 893 case 'test_errors': $category=5; break; 894 case 'update_fixes': $category=6; break; 895 case 'configure_fixes': $category=7; break; 896 case 'buildwarning_fixes': $category=8; break; 897 case 'builderror_fixes': $category=9; break; 898 case 'test_fixes': $category=10; break; 899 case 'dynamicanalysis_errors': $category=11; break; 900 } 901 902 if($category == 0) 903 { 904 return false; 905 } 906 907 $query = pdo_query("SELECT count(*) FROM buildemail WHERE userid=".qnum($userid)." AND buildid=".qnum($buildid)." AND category=".qnum($category)); 908 $query_array = pdo_fetch_array($query); 909 if($query_array[0]>0) 910 { 911 return true; 912 } 913 914 return false; 915} 916 917/** Send the email to the user when he fixed something */ 918function send_email_fix_to_user($userid,$emailtext,$Build,$Project) 919{ 920 include("cdash/config.php"); 921 include_once("cdash/common.php"); 922 require_once("models/site.php"); 923 require_once("models/user.php"); 924 925 $serverURI = get_server_URI(); 926 // In the case of asynchronous submission, the serverURI contains /cdash 927 // we need to remove it 928 if($CDASH_BASE_URL=='' && $CDASH_ASYNCHRONOUS_SUBMISSION) 929 { 930 $serverURI = substr($serverURI,0,strrpos($serverURI,"/")); 931 } 932 933 $messagePlainText = "Congratulations, a submission to CDash for the project ".$Project->Name." has "; 934 $titleerrors = "("; 935 936 $i=0; 937 foreach($emailtext['category'] as $key=>$value) 938 { 939 if($i>0) 940 { 941 $messagePlainText .= " and "; 942 $titleerrors.=", "; 943 } 944 945 switch($key) 946 { 947 case 'update_fixes': $messagePlainText .= "fixed update errors";$titleerrors.="u=".$value; break; 948 case 'configure_fixes': $messagePlainText .= "fixed configure errors";$titleerrors.="c=".$value; break; 949 case 'buildwarning_fixes': $messagePlainText .= "fixed build warnings";$titleerrors.="w=".$value; break; 950 case 'builderror_fixes': $messagePlainText .= "fixed build errors";$titleerrors.="b=".$value; break; 951 case 'test_fixes': $messagePlainText .= "fixed failing tests";$titleerrors.="t=".$value; break; 952 } 953 954 $i++; 955 } 956 957 // Title 958 $titleerrors .= "):"; 959 $title = "PASSED ".$titleerrors." ".$Project->Name; 960 961 if($Build->GetSubProjectName()) 962 { 963 $title .= "/".$Build->GetSubProjectName(); 964 } 965 $title .= " - ".$Build->Name." - ".$Build->Type; 966 967 $messagePlainText .= ".\n"; 968 $messagePlainText .= "You have been identified as one of the authors who have checked in changes that are part of this submission "; 969 $messagePlainText .= "or you are listed in the default contact list.\n\n"; 970 $messagePlainText .= "Details on the submission can be found at "; 971 972 $messagePlainText .= $serverURI; 973 $messagePlainText .= "/buildSummary.php?buildid=".$Build->Id; 974 $messagePlainText .= "\n\n"; 975 976 $messagePlainText .= "Project: ".$Project->Name."\n"; 977 if($Build->GetSubProjectName()) 978 { 979 $messagePlainText .= "SubProject: ".$Build->GetSubProjectName()."\n"; 980 } 981 982 $Site = new Site(); 983 $Site->Id = $Build->SiteId; 984 985 $messagePlainText .= "Site: ".$Site->GetName()."\n"; 986 $messagePlainText .= "Build Name: ".$Build->Name."\n"; 987 $messagePlainText .= "Build Time: ".date(FMT_DATETIMETZ,strtotime($Build->StartTime." UTC"))."\n"; 988 $messagePlainText .= "Type: ".$Build->Type."\n"; 989 990 foreach($emailtext['category'] as $key=>$value) 991 { 992 switch($key) 993 { 994 case 'update_fixes': $messagePlainText .= "Update error fixed: ".$value."\n"; break; 995 case 'configure_fixes': $messagePlainText .= "Configure error fixed: ".$value."\n"; break; 996 case 'buildwarning_fixes': $messagePlainText .= "Warning fixed: ".$value."\n"; break; 997 case 'builderror_fixes': $messagePlainText .= "Error fixed: ".$value."\n"; break; 998 case 'test_fixes': $messagePlainText .= "Tests fixed: ".$value."\n"; break; 999 } 1000 } 1001 1002 $serverName = $CDASH_SERVER_NAME; 1003 if(strlen($serverName) == 0) 1004 { 1005 $serverName = $_SERVER['SERVER_NAME']; 1006 } 1007 $messagePlainText .= "\n-CDash on ".$serverName."\n"; 1008 1009 // Find the email 1010 $User = new User(); 1011 $User->Id = $userid; 1012 $email = $User->GetEmail(); 1013 1014 // If this is the testing 1015 if($CDASH_TESTING_MODE) 1016 { 1017 add_log($email,"TESTING: EMAIL",LOG_TESTING); 1018 add_log($title,"TESTING: EMAILTITLE",LOG_TESTING); 1019 add_log($messagePlainText,"TESTING: EMAILBODY",LOG_TESTING); 1020 // Record that we have send the email 1021 set_email_sent($userid,$Build->Id,$emailtext); 1022 } 1023 else 1024 { 1025 // Send the email 1026 if(cdashmail("$email", $title, $messagePlainText, 1027 "From: CDash <".$CDASH_EMAIL_FROM.">\nReply-To: ".$CDASH_EMAIL_REPLY."\nContent-type: text/plain; charset=utf-8\nX-Mailer: PHP/" . phpversion()."\nMIME-Version: 1.0" )) 1028 { 1029 add_log("email sent to: ".$email." with fixes ".$titleerrors." for build ".$Build->Id,"sendemail ".$Project->Name,LOG_INFO); 1030 1031 // Record that we have send the email 1032 set_email_sent($userid,$Build->Id,$emailtext); 1033 } 1034 else 1035 { 1036 add_log("cannot send email to: ".$email,"sendemail ".$Project->Name,LOG_ERR); 1037 } 1038 } // end if testing 1039} // end send_email_fix_to_user 1040 1041 1042// Send one broken submission email to one email address 1043// 1044function send_email_to_address($emailaddress, $emailtext, $Build, $Project) 1045{ 1046 include("cdash/config.php"); 1047 include_once("cdash/common.php"); 1048 require_once("models/site.php"); 1049 1050 $serverURI = get_server_URI(); 1051 // In the case of asynchronous submission, the serverURI contains /cdash 1052 // we need to remove it 1053 if($CDASH_BASE_URL=='' && $CDASH_ASYNCHRONOUS_SUBMISSION) 1054 { 1055 $serverURI = substr($serverURI,0,strrpos($serverURI,"/")); 1056 } 1057 1058 $messagePlainText = "A submission to CDash for the project ".$Project->Name." has "; 1059 $titleerrors = "("; 1060 1061 $i=0; 1062 foreach($emailtext['category'] as $key=>$value) 1063 { 1064 if($key != 'update_errors' 1065 && $key != 'configure_errors' 1066 && $key != 'build_warnings' 1067 && $key != 'build_errors' 1068 && $key != 'test_errors' 1069 && $key != 'dynamicanalysis_errors') 1070 { 1071 continue; 1072 } 1073 1074 if($i>0) 1075 { 1076 $messagePlainText .= " and "; 1077 $titleerrors.=", "; 1078 } 1079 1080 switch($key) 1081 { 1082 case 'update_errors': $messagePlainText .= "update errors";$titleerrors.="u=".$value; break; 1083 case 'configure_errors': $messagePlainText .= "configure errors";$titleerrors.="c=".$value; break; 1084 case 'build_warnings': $messagePlainText .= "build warnings";$titleerrors.="w=".$value; break; 1085 case 'build_errors': $messagePlainText .= "build errors";$titleerrors.="b=".$value; break; 1086 case 'test_errors': $messagePlainText .= "failing tests";$titleerrors.="t=".$value; break; 1087 case 'dynamicanalysis_errors': $messagePlainText .= "failing dynamic analysis tests";$titleerrors.="d=".$value; break; 1088 } 1089 $i++; 1090 } 1091 1092 // Nothing to send we stop 1093 if($i==0) 1094 { 1095 return; 1096 } 1097 1098 // Title 1099 $titleerrors .= "):"; 1100 $title = "FAILED ".$titleerrors." ".$Project->Name; 1101 1102 if($Build->GetSubProjectName()) 1103 { 1104 $title .= "/".$Build->GetSubProjectName(); 1105 } 1106 $title .= " - ".$Build->Name." - ".$Build->Type; 1107 1108 //$title = "CDash [".$project_array["name"]."] - ".$site_array["name"]; 1109 //$title .= " - ".$buildname." - ".$buildtype." - ".date(FMT_DATETIMETZ,strtotime($starttime." UTC")); 1110 1111 $messagePlainText .= ".\n"; 1112 $messagePlainText .= "You have been identified as one of the authors who "; 1113 $messagePlainText .= "have checked in changes that are part of this submission "; 1114 $messagePlainText .= "or you are listed in the default contact list.\n\n"; 1115 $messagePlainText .= "Details on the submission can be found at "; 1116 1117 $messagePlainText .= $serverURI; 1118 $messagePlainText .= "/buildSummary.php?buildid=".$Build->Id; 1119 $messagePlainText .= "\n\n"; 1120 1121 $messagePlainText .= "Project: ".$Project->Name."\n"; 1122 if($Build->GetSubProjectName()) 1123 { 1124 $messagePlainText .= "SubProject: ".$Build->GetSubProjectName()."\n"; 1125 } 1126 1127 $Site = new Site(); 1128 $Site->Id = $Build->SiteId; 1129 1130 $messagePlainText .= "Site: ".$Site->GetName()."\n"; 1131 $messagePlainText .= "Build Name: ".$Build->Name."\n"; 1132 $messagePlainText .= "Build Time: ".date(FMT_DATETIMETZ,strtotime($Build->StartTime." UTC"))."\n"; 1133 $messagePlainText .= "Type: ".$Build->Type."\n"; 1134 1135 foreach($emailtext['category'] as $key=>$value) 1136 { 1137 switch($key) 1138 { 1139 case 'update_errors': $messagePlainText .= "Update errors: $value\n"; break; 1140 case 'configure_errors': $messagePlainText .= "Configure errors: $value\n"; break; 1141 case 'build_warnings': $messagePlainText .= "Warnings: $value\n"; break; 1142 case 'build_errors': $messagePlainText .= "Errors: $value\n"; break; 1143 case 'test_errors': $messagePlainText .= "Tests failing: $value\n"; break; 1144 case 'dynamicanalysis_errors': $messagePlainText .= "Dynamic analysis tests failing: $value\n"; break; 1145 } 1146 } 1147 1148 foreach($emailtext['summary'] as $summary) 1149 { 1150 $messagePlainText .= $summary; 1151 } 1152 1153 $serverName = $CDASH_SERVER_NAME; 1154 if(strlen($serverName) == 0) 1155 { 1156 $serverName = $_SERVER['SERVER_NAME']; 1157 } 1158 $messagePlainText .= "\n-CDash on ".$serverName."\n"; 1159 1160 $sent = false; 1161 1162 // If this is the testing 1163 if($CDASH_TESTING_MODE) 1164 { 1165 add_log($emailaddress,"TESTING: EMAIL",LOG_TESTING); 1166 add_log($title,"TESTING: EMAILTITLE",LOG_TESTING); 1167 add_log($messagePlainText,"TESTING: EMAILBODY",LOG_TESTING); 1168 $sent = true; 1169 } 1170 else 1171 { 1172 // Send the email 1173 if(cdashmail("$emailaddress", $title, $messagePlainText, 1174 "From: CDash <".$CDASH_EMAIL_FROM.">\nReply-To: ".$CDASH_EMAIL_REPLY."\nContent-type: text/plain; charset=utf-8\nX-Mailer: PHP/" . phpversion()."\nMIME-Version: 1.0" )) 1175 { 1176 add_log("email sent to: ".$emailaddress." with errors ".$titleerrors." for build ".$Build->Id,"sendemail ".$Project->Name,LOG_INFO); 1177 $sent = true; 1178 } 1179 else 1180 { 1181 add_log("cannot send email to: ".$emailaddress,"sendemail ".$Project->Name,LOG_ERR); 1182 } 1183 } // end if testing 1184 1185 return $sent; 1186} // end send_email_to_address 1187 1188 1189function send_email_to_user($userid, $emailtext, $Build, $Project) 1190{ 1191 require_once("models/user.php"); 1192 1193 $User = new User(); 1194 $User->Id = $userid; 1195 $email = $User->GetEmail(); 1196 1197 $sent = send_email_to_address($email, $emailtext, $Build, $Project); 1198 if ($sent) 1199 { 1200 // Record that we have sent the email 1201 set_email_sent($userid, $Build->Id, $emailtext); 1202 } 1203 1204} // end send_email_to_user 1205 1206 1207function send_error_email($userid, $emailaddress, $sendEmail, $errors, 1208 $Build, $Project, $prefix = 'none') 1209{ 1210 include("cdash/config.php"); 1211 $emailtext = array(); 1212 $emailtext['nerror'] = 0; 1213 1214 if ($userid != 0) 1215 { 1216 // For registered users, tune the error array based on user preferences 1217 // to make sure he doesn't get emails that are unwanted/unnecessary 1218 $UserProject = new UserProject(); 1219 $UserProject->UserId = $userid; 1220 $UserProject->ProjectId = $Project->Id; 1221 $useremailcategory = $UserProject->GetEmailCategory(); 1222 } 1223 1224 // Check if an email has been sent already for this user 1225 foreach($errors as $errorkey => $nerrors) 1226 { 1227 if($nerrors == 0 || $errorkey=='errors') 1228 { 1229 continue; 1230 } 1231 1232 $stop = false; 1233 1234 if($userid != 0) 1235 { 1236 // If the user doesn't want to get the email 1237 switch($errorkey) 1238 { 1239 case 'update_errors': if(!check_email_category("update",$useremailcategory)) {$stop=true;} break; 1240 case 'configure_errors': if(!check_email_category("configure",$useremailcategory)) {$stop=true;} break; 1241 case 'build_errors': if(!check_email_category("error",$useremailcategory)) {$stop=true;} break; 1242 case 'build_warnings': if(!check_email_category("warning",$useremailcategory)) {$stop=true;} break; 1243 case 'test_errors': if(!check_email_category("test",$useremailcategory)) {$stop=true;} break; 1244 case 'dynamicanalysis_errors': if(!check_email_category("dynamicanalysis",$useremailcategory)) {$stop=true;} break; 1245 } 1246 } 1247 else 1248 { 1249 // For committers, only send emails when the errorkey starts with the 1250 // prefix associated with the current handler calling us. 1251 // (So stop if the errorkey does not begin with the prefix...) 1252 // This minimizes sending out possibly near-duplicate emails to the 1253 // same committers... 1254 // 1255 if (0 !== strpos($errorkey, $prefix)) 1256 { 1257 $stop = true; 1258 } 1259 } 1260 1261 if($stop) 1262 { 1263 continue; 1264 } 1265 1266 if(0 == $userid || !check_email_sent($userid, $Build->Id, $errorkey)) 1267 { 1268 $emailtext['summary'][$errorkey] = get_email_summary($Build->Id,$errors,$errorkey,$Project->EmailMaxItems, 1269 $Project->EmailMaxChars,$Project->TestTimeMaxStatus, 1270 $Project->EmailTestTimingChanged); 1271 $emailtext['category'][$errorkey] = $nerrors; 1272 $emailtext['nerror'] = 1; 1273 } 1274 } 1275 1276 // Send the email 1277 if($emailtext['nerror'] == 1) 1278 { 1279 if($userid != 0) 1280 { 1281 send_email_to_user($userid, $emailtext, $Build, $Project); 1282 1283 if($CDASH_USE_LOCAL_DIRECTORY&&file_exists("local/sendemail.php")) 1284 { 1285 $sendEmail->UserId = $userid; 1286 $sendEmail->Text = $emailtext; 1287 $sendEmail->SendToUser(); 1288 } 1289 } 1290 else 1291 { 1292 send_email_to_address($emailaddress, $emailtext, $Build, $Project); 1293 // 1294 // Do we still need a "$sendEmail->" call here even if 1295 // there is no UserId...? 1296 // 1297 } 1298 } 1299} 1300 1301 1302function getHandlerErrorKeyPrefix($handler) 1303{ 1304 if($handler instanceof UpdateHandler) 1305 { 1306 return "update_"; 1307 } 1308 1309 if($handler instanceof TestingHandler) 1310 { 1311 return "test_"; 1312 } 1313 1314 if($handler instanceof BuildHandler) 1315 { 1316 return "build_"; 1317 } 1318 1319 if($handler instanceof ConfigureHandler) 1320 { 1321 return "configure_"; 1322 } 1323 1324 if($handler instanceof DynamicAnalysisHandler) 1325 { 1326 return "dynamicanalysis_"; 1327 } 1328 1329 return "none"; 1330} 1331 1332/** function to send email to site maintainers when the update 1333 * step fails */ 1334function send_update_email($handler,$projectid) 1335{ 1336 include("cdash/config.php"); 1337 include_once("cdash/common.php"); 1338 require_once("cdash/pdo.php"); 1339 require_once("models/build.php"); 1340 require_once("models/project.php"); 1341 require_once("models/buildgroup.php"); 1342 1343 $Project = new Project(); 1344 $Project->Id = $projectid; 1345 $Project->Fill(); 1346 1347 // If we shouldn't sent any emails we stop 1348 if($Project->EmailBrokenSubmission == 0) 1349 { 1350 return; 1351 } 1352 1353 // If the handler has a buildid (it should), we use it 1354 if(isset($handler->BuildId) && $handler->BuildId>0) 1355 { 1356 $buildid = $handler->BuildId; 1357 } 1358 else 1359 { 1360 // Get the build id 1361 $name = $handler->getBuildName(); 1362 $stamp = $handler->getBuildStamp(); 1363 $sitename = $handler->getSiteName(); 1364 $buildid = get_build_id($name,$stamp,$projectid,$sitename); 1365 } 1366 1367 if($buildid<0) 1368 { 1369 return; 1370 } 1371 1372 // Check if the group as no email 1373 $Build = new Build(); 1374 $Build->Id = $buildid; 1375 $groupid = $Build->GetGroup(); 1376 1377 $BuildGroup = new BuildGroup(); 1378 $BuildGroup->Id = $groupid; 1379 1380 // If we specified no email we stop here 1381 if($BuildGroup->GetSummaryEmail()==2) 1382 { 1383 return; 1384 } 1385 1386 // Send out update errors to site maintainers 1387 $update_errors = check_email_update_errors($buildid); 1388 if($update_errors['errors']) 1389 { 1390 // Find the site maintainer(s) 1391 $sitename = $handler->getSiteName(); 1392 $siteid = $handler->getSiteId(); 1393 $to_address = ""; 1394 $email_addresses = 1395 pdo_query("SELECT email FROM ".qid("user").",site2user WHERE ".qid("user").".id=site2user.userid AND site2user.siteid='$siteid'"); 1396 while($email_addresses_array = pdo_fetch_array($email_addresses)) 1397 { 1398 if($to_address != "") 1399 { 1400 $to_address .= ", "; 1401 } 1402 $to_address .= $email_addresses_array["email"]; 1403 } 1404 1405 if($to_address != "") 1406 { 1407 $serverURI = get_server_URI(); 1408 // In the case of asynchronous submission, the serverURI contains /cdash 1409 // we need to remove it 1410 if($CDASH_BASE_URL=='' && $CDASH_ASYNCHRONOUS_SUBMISSION) 1411 { 1412 $serverURI = substr($serverURI,0,strrpos($serverURI,"/")); 1413 } 1414 1415 // Generate the email to send 1416 $subject = "CDash [".$Project->Name."] - Update Errors for ".$sitename; 1417 1418 $update_info = pdo_query("SELECT command,status FROM buildupdate AS u,build2update AS b2u 1419 WHERE b2u.updateid=u.id AND b2u.buildid=".qnum($buildid)); 1420 $update_array = pdo_fetch_array($update_info); 1421 1422 $body = "$sitename has encountered errors during the Update step and you have been identified as the maintainer of this site.\n\n"; 1423 $body .= "*Update Errors*\n"; 1424 $body .= "Status: ".$update_array["status"]." (".$serverURI."/viewUpdate.php?buildid=".$buildid.")\n"; 1425 1426 $header = 1427 "From: CDash <".$CDASH_EMAIL_FROM.">\nReply-To: ".$CDASH_EMAIL_REPLY."\nContent-type: text/plain; charset=utf-8\nX-Mailer: PHP/" . phpversion()."\nMIME-Version: 1.0"; 1428 1429 if($CDASH_TESTING_MODE) 1430 { 1431 add_log($to_address, "TESTING: EMAIL",LOG_TESTING); 1432 add_log($subject, "TESTING: EMAILTITLE",LOG_TESTING); 1433 add_log($body, "TESTING: EMAILBODY",LOG_TESTING); 1434 } 1435 else 1436 { 1437 if(cdashmail("$to_address", $subject, $body, $header)) 1438 { 1439 add_log("email sent to: ".$to_address,"sendEmailExpectedBuilds"); 1440 return; 1441 } 1442 else 1443 { 1444 add_log("cannot send email to: ".$to_address,"sendEmailExpectedBuilds"); 1445 } 1446 } 1447 } 1448 } 1449} 1450 1451/** Main function to send email if necessary */ 1452function sendemail($handler,$projectid) 1453{ 1454 include("cdash/config.php"); 1455 include_once("cdash/common.php"); 1456 require_once("cdash/pdo.php"); 1457 require_once("models/build.php"); 1458 require_once("models/project.php"); 1459 require_once("models/buildgroup.php"); 1460 1461 $Project = new Project(); 1462 $Project->Id = $projectid; 1463 $Project->Fill(); 1464 1465 $sendEmail = NULL; 1466 1467 if($CDASH_USE_LOCAL_DIRECTORY&&file_exists("local/sendemail.php")) 1468 { 1469 include_once("local/sendemail.php"); 1470 $sendEmail = new SendEmail(); 1471 $sendEmail->SetProjectId($projectid); 1472 } 1473 1474 // If we shouldn't sent any emails we stop 1475 if($Project->EmailBrokenSubmission == 0) 1476 { 1477 return; 1478 } 1479 1480 // If the handler has a buildid (it should), we use it 1481 if(isset($handler->BuildId) && $handler->BuildId>0) 1482 { 1483 $buildid = $handler->BuildId; 1484 } 1485 else 1486 { 1487 // Get the build id 1488 $name = $handler->getBuildName(); 1489 $stamp = $handler->getBuildStamp(); 1490 $sitename = $handler->getSiteName(); 1491 $buildid = get_build_id($name,$stamp,$projectid,$sitename); 1492 } 1493 1494 if($buildid<0) 1495 { 1496 return; 1497 } 1498 1499 //add_log("Buildid ".$buildid,"sendemail ".$Project->Name,LOG_INFO); 1500 1501 // Check if the group as no email 1502 $Build = new Build(); 1503 $Build->Id = $buildid; 1504 $groupid = $Build->GetGroup(); 1505 1506 $BuildGroup = new BuildGroup(); 1507 $BuildGroup->Id = $groupid; 1508 1509 // If we specified no email we stop here 1510 if($BuildGroup->GetSummaryEmail()==2) 1511 { 1512 return; 1513 } 1514 1515 $emailCommitters = $BuildGroup->GetEmailCommitters(); 1516 1517 $errors = check_email_errors($buildid,$Project->EmailTestTimingChanged, 1518 $Project->TestTimeMaxStatus,!$Project->EmailRedundantFailures); 1519 1520 // We have some fixes 1521 if($errors['hasfixes']) 1522 { 1523 $Build->FillFromId($Build->Id); 1524 // Get the list of person who should get the email 1525 $lookup_result = lookup_emails_to_send($errors, $buildid, $projectid, 1526 $Build->Type, true, $emailCommitters); 1527 $userids = $lookup_result['userids']; 1528 foreach($userids as $userid) 1529 { 1530 $emailtext = array(); 1531 $emailtext['nfixes'] = 0; 1532 1533 // Check if an email has been sent already for this user 1534 foreach($errors['fixes'] as $fixkey => $nfixes) 1535 { 1536 if($nfixes == 0) 1537 { 1538 continue; 1539 } 1540 1541 if(!check_email_sent($userid,$buildid,$fixkey)) 1542 { 1543 $emailtext['category'][$fixkey] = $nfixes; 1544 $emailtext['nfixes'] = 1; 1545 } 1546 } 1547 1548 // Send the email 1549 if($emailtext['nfixes'] == 1) 1550 { 1551 send_email_fix_to_user($userid,$emailtext,$Build,$Project); 1552 } 1553 } 1554 } 1555 1556 // No error we return 1557 if(!$errors['errors']) 1558 { 1559 return; 1560 } 1561 1562 if($CDASH_USE_LOCAL_DIRECTORY&&file_exists("local/sendemail.php")) 1563 { 1564 $sendEmail->BuildId = $Build->Id; 1565 $sendEmail->Errors = $errors; 1566 } 1567 1568 // If we should send a summary email 1569 if($BuildGroup->GetSummaryEmail()==1) 1570 { 1571 // Send the summary email 1572 sendsummaryemail($projectid,$groupid,$errors,$buildid); 1573 1574 if($CDASH_USE_LOCAL_DIRECTORY&&file_exists("local/sendemail.php")) 1575 { 1576 $sendEmail->SendSummary(); 1577 } 1578 1579 return; 1580 } // end summary email 1581 1582 $Build->FillFromId($Build->Id); 1583 1584 // Send build error 1585 if($CDASH_USE_LOCAL_DIRECTORY&&file_exists("local/sendemail.php")) 1586 { 1587 $sendEmail->SendBuildError(); 1588 } 1589 1590 // Lookup the list of people who should get the email, both registered 1591 // users *and* committers: 1592 // 1593 $lookup_result = lookup_emails_to_send($errors, $buildid, $projectid, 1594 $Build->Type, false, $emailCommitters); 1595 1596 // Loop through the *registered* users: 1597 // 1598 $userids = $lookup_result['userids']; 1599 foreach($userids as $userid) 1600 { 1601 send_error_email($userid, '', $sendEmail, $errors, 1602 $Build, $Project); 1603 } 1604 1605 // Loop through "other" users, if necessary: 1606 // 1607 // ...people who committed code, but are *not* registered CDash users, but 1608 // only if the 'emailcommitters' field is on for this build group. 1609 // 1610 if($emailCommitters) 1611 { 1612 $committeremails = $lookup_result['committeremails']; 1613 foreach($committeremails as $committeremail) 1614 { 1615 send_error_email(0, $committeremail, $sendEmail, $errors, 1616 $Build, $Project, getHandlerErrorKeyPrefix($handler)); 1617 } 1618 } 1619} 1620?> 1621