1<?php 2 3namespace App\Repository; 4 5/** 6 * Repository class for fetching data from the database table bugdb. 7 */ 8class BugRepository 9{ 10 /** 11 * Database handler. 12 * @var \PDO 13 */ 14 private $dbh; 15 16 /** 17 * Days when bugs with no feedback get closed. 18 */ 19 private const FEEDBACK_PERIOD = 7; 20 21 /** 22 * Class constructor. 23 */ 24 public function __construct(\PDO $dbh) 25 { 26 $this->dbh = $dbh; 27 } 28 29 /** 30 * Fetch bug data by bug id. 31 */ 32 public function findOneById(int $id): array 33 { 34 $sql = 'SELECT b.id, b.package_name, b.bug_type, b.email, b.reporter_name, 35 b.sdesc, b.ldesc, b.php_version, b.php_os, 36 b.status, b.ts1, b.ts2, b.assign, b.block_user_comment, 37 b.private, b.cve_id, 38 UNIX_TIMESTAMP(b.ts1) AS submitted, 39 UNIX_TIMESTAMP(b.ts2) AS modified, 40 COUNT(bug=b.id) AS votes, 41 IFNULL((SELECT z.project FROM bugdb_pseudo_packages z WHERE z.name = b.package_name LIMIT 1), "php") project, 42 SUM(reproduced) AS reproduced, SUM(tried) AS tried, 43 SUM(sameos) AS sameos, SUM(samever) AS samever, 44 AVG(score)+3 AS average, STD(score) AS deviation 45 FROM bugdb b 46 LEFT JOIN bugdb_votes ON b.id = bug 47 WHERE b.id = ? 48 GROUP BY b.id 49 '; 50 51 $statement = $this->dbh->prepare($sql); 52 $statement->execute([$id]); 53 54 $result = $statement->fetch(); 55 56 return $result === false ? [] : $result; 57 } 58 59 /** 60 * Find random bug to resolve for a contributor. 61 */ 62 public function findRandom(): array 63 { 64 $sql = "SELECT id 65 FROM bugdb 66 WHERE status NOT IN('Closed', 'Not a bug', 'Duplicate', 'Spam', 'Wont fix', 'No Feedback', 'Suspended') 67 AND private = 'N' 68 ORDER BY RAND() LIMIT 1 69 "; 70 71 $statement = $this->dbh->prepare($sql); 72 $statement->execute(); 73 74 return $statement->fetch(\PDO::FETCH_NUM); 75 } 76 77 /** 78 * Find all bugs that have someone assigned to them. 79 */ 80 public function findAllAssigned(): array 81 { 82 $sql = "SELECT id, package_name, bug_type, sdesc, status, assign, UNIX_TIMESTAMP(ts1) AS ts_opened, UNIX_TIMESTAMP(ts2) AS ts_changed 83 FROM `bugdb` 84 WHERE length(assign) > 1 85 AND status IN ('Assigned', 'Open', 'Re-Opened', 'Feedback', 'Analyzed', 'Verified', 'Critical', 'Suspended') 86 ORDER BY id 87 "; 88 89 $statement = $this->dbh->query($sql); 90 91 $data = []; 92 93 // Populate data with assign field as array key 94 while ($row = $statement->fetch()) { 95 $data[$row['assign']][] = $row; 96 } 97 98 return $data; 99 } 100 101 /** 102 * Find all bugs without feedback by given period time. 103 */ 104 public function findAllWithoutFeedback(int $feedbackPeriod = self::FEEDBACK_PERIOD): array 105 { 106 $sql = "SELECT id, package_name, bug_type, email, passwd, sdesc, ldesc, 107 php_version, php_os, status, ts1, ts2, assign, 108 UNIX_TIMESTAMP(ts1) AS submitted, private, reporter_name, 109 UNIX_TIMESTAMP(ts2) AS modified 110 FROM bugdb 111 WHERE status = 'Feedback' AND ts2 < DATE_SUB(NOW(), INTERVAL ? DAY) 112 "; 113 114 $statement = $this->dbh->prepare($sql); 115 $statement->execute([$feedbackPeriod]); 116 117 return $statement->fetchAll(); 118 } 119 120 /** 121 * Find all bugs by given bug type. 122 */ 123 public function findAllByBugType(string $type = 'All'): array 124 { 125 $sql = 'SELECT b.package_name, b.status, COUNT(*) AS quant FROM bugdb AS b'; 126 127 $arguments = []; 128 129 if ($type !== 'All') { 130 $sql .= ' WHERE bug_type = ? '; 131 $arguments[] = $type; 132 } 133 134 $sql .= ' GROUP BY b.package_name, b.status ORDER BY b.package_name, b.status'; 135 136 $statement = $this->dbh->prepare($sql); 137 $statement->execute($arguments); 138 139 return $statement->fetchAll(); 140 } 141 142 /** 143 * Find bugs for grouping into PHP versions by given bug type. 144 */ 145 public function findPhpVersions(string $type = 'All'): array 146 { 147 $sql = "SELECT DATE_FORMAT(ts1, '%Y-%m') as d, 148 IF(b.php_version LIKE '%Git%', LEFT(b.php_version, LOCATE('Git', b.php_version)+2), b.php_version) AS formatted_version, 149 COUNT(*) AS quant 150 FROM bugdb AS b 151 WHERE ts1 >= CONCAT(YEAR(NOW())-1, '-', MONTH(NOW()), '-01 00:00:00') 152 "; 153 154 $arguments = []; 155 156 if ($type !== 'All') { 157 $sql .= ' AND bug_type = ? '; 158 $arguments[] = $type; 159 } 160 161 $sql .= ' GROUP BY d, formatted_version ORDER BY d, quant'; 162 163 $statement = $this->dbh->prepare($sql); 164 $statement->execute($arguments); 165 166 return $statement->fetchAll(); 167 } 168 169 /** 170 * Check if bug with given id exists. 171 */ 172 public function exists(int $id): bool 173 { 174 $statement = $this->dbh->prepare('SELECT 1 FROM bugdb WHERE id = ?'); 175 $statement->execute([$id]); 176 177 return (bool)$statement->fetchColumn(); 178 } 179} 180