1<?php 2 3namespace App\Repository; 4 5/** 6 * Repository class for retrieving data from the bugdb_pseudo_packages database 7 * table. 8 */ 9class PackageRepository 10{ 11 /** 12 * Database handler. 13 * @var \PDO 14 */ 15 private $dbh; 16 17 /** 18 * Project types. 19 */ 20 public const PROJECTS = [ 21 'PHP' => 'php', 22 'PECL' => 'pecl', 23 ]; 24 25 /** 26 * Class constructor. 27 */ 28 public function __construct(\PDO $dbh) 29 { 30 $this->dbh = $dbh; 31 } 32 33 /** 34 * Find all packages by project type. 35 */ 36 public function findAll(string $project = ''): array 37 { 38 $sql = 'SELECT * FROM bugdb_pseudo_packages'; 39 $arguments = []; 40 41 $project = strtolower($project); 42 if (in_array($project, self::PROJECTS)) { 43 $sql .= " WHERE project IN ('', ?)"; 44 $arguments[] = $project; 45 } 46 47 $sql .= ' ORDER BY parent, disabled, id'; 48 49 $statement = $this->dbh->prepare($sql); 50 $statement->execute($arguments); 51 $data = $statement->fetchAll(); 52 53 return $this->getNested($data); 54 } 55 56 /** 57 * Find all enabled packages by project type. 58 */ 59 public function findEnabled(string $project = ''): array 60 { 61 $sql = 'SELECT * FROM bugdb_pseudo_packages WHERE disabled = 0'; 62 $arguments = []; 63 64 $project = strtolower($project); 65 if (in_array($project, self::PROJECTS)) { 66 $sql .= " AND project IN ('', ?)"; 67 $arguments[] = $project; 68 } 69 70 $sql .= ' ORDER BY parent, id'; 71 72 $statement = $this->dbh->prepare($sql); 73 $statement->execute($arguments); 74 75 $data = $statement->fetchAll(); 76 77 return $this->getNested($data); 78 } 79 80 /** 81 * Convert flat array to nested structure. 82 */ 83 private function getNested(array $data): array 84 { 85 $packages = []; 86 $nodes = []; 87 $tree = []; 88 89 foreach ($data as &$node) { 90 $node['children'] = []; 91 $id = $node['id']; 92 $parentId = $node['parent']; 93 $nodes[$id] =& $node; 94 95 if (array_key_exists($parentId, $nodes)) { 96 $nodes[$parentId]['children'][] =& $node; 97 } else { 98 $tree[] =& $node; 99 } 100 } 101 102 foreach ($tree as $data) { 103 if (isset($data['children'])) { 104 $packages[$data['name']] = [$data['long_name'], $data['disabled'], []]; 105 $children = &$packages[$data['name']][2]; 106 $longNames = []; 107 108 foreach ($data['children'] as $k => $v) { 109 $longNames[$k] = strtolower($v['long_name']); 110 } 111 112 array_multisort($longNames, SORT_ASC, SORT_STRING, $data['children']); 113 114 foreach ($data['children'] as $child) { 115 $packages[$child['name']] = ["{$child['long_name']}", $child['disabled'], null]; 116 $children[] = $child['name']; 117 } 118 } elseif (!isset($packages[$data['name']])) { 119 $packages[$data['name']] = [$data['long_name'], $data['disabled'], null]; 120 } 121 } 122 123 return $packages; 124 } 125 126 /** 127 * Find all package mailing lists. 128 */ 129 public function findLists(): array 130 { 131 $sql = "SELECT name, list_email 132 FROM bugdb_pseudo_packages 133 WHERE project = 'php' AND LENGTH(list_email) > 0 134 ORDER BY list_email 135 "; 136 137 $statement = $this->dbh->query($sql); 138 139 return $statement->fetchAll(); 140 } 141} 142