@recaptime-dev's working patches + fork for Phorge, a community fork of Phabricator. (Upstream dev and stable branches are at upstream/main and upstream/stable respectively.) hq.recaptime.dev/wiki/Phorge
phorge phabricator
2
fork

Configure Feed

Select the types of activity you want to include in your feed.

at recaptime-dev/main 176 lines 5.0 kB view raw
1<?php 2 3final class PhabricatorProjectsMembershipIndexEngineExtension 4 extends PhabricatorIndexEngineExtension { 5 6 const EXTENSIONKEY = 'project.members'; 7 8 public function getExtensionName() { 9 return pht('Project Members'); 10 } 11 12 public function shouldIndexObject($object) { 13 if (!($object instanceof PhabricatorProject)) { 14 return false; 15 } 16 17 return true; 18 } 19 20 public function indexObject( 21 PhabricatorIndexEngine $engine, 22 $object) { 23 24 $this->rematerialize($object); 25 } 26 27 public function rematerialize(PhabricatorProject $project) { 28 $materialize = $project->getAncestorProjects(); 29 array_unshift($materialize, $project); 30 31 foreach ($materialize as $project) { 32 $this->materializeProject($project); 33 } 34 } 35 36 private function materializeProject(PhabricatorProject $project) { 37 $material_type = PhabricatorProjectMaterializedMemberEdgeType::EDGECONST; 38 $member_type = PhabricatorProjectProjectHasMemberEdgeType::EDGECONST; 39 40 $project_phid = $project->getPHID(); 41 42 if ($project->isMilestone()) { 43 $source_phids = array($project->getParentProjectPHID()); 44 $has_subprojects = false; 45 } else { 46 $descendants = id(new PhabricatorProjectQuery()) 47 ->setViewer($this->getViewer()) 48 ->withAncestorProjectPHIDs(array($project->getPHID())) 49 ->withIsMilestone(false) 50 ->withHasSubprojects(false) 51 ->execute(); 52 $descendant_phids = mpull($descendants, 'getPHID'); 53 54 if ($descendant_phids) { 55 $source_phids = $descendant_phids; 56 $has_subprojects = true; 57 } else { 58 $source_phids = array($project->getPHID()); 59 $has_subprojects = false; 60 } 61 } 62 63 $conn_w = $project->establishConnection('w'); 64 65 $any_milestone = queryfx_one( 66 $conn_w, 67 'SELECT id FROM %T 68 WHERE parentProjectPHID = %s AND milestoneNumber IS NOT NULL 69 LIMIT 1', 70 $project->getTableName(), 71 $project_phid); 72 $has_milestones = (bool)$any_milestone; 73 74 $project->openTransaction(); 75 76 // Copy current member edges to create new materialized edges. 77 78 // See T13596. Avoid executing this as an "INSERT ... SELECT" to reduce 79 // the required level of table locking. Since we're decomposing it into 80 // "SELECT" + "INSERT" anyway, we can also compute exactly which rows 81 // need to be modified. 82 83 $have_rows = queryfx_all( 84 $conn_w, 85 'SELECT dst FROM %T 86 WHERE src = %s AND type = %d', 87 PhabricatorEdgeConfig::TABLE_NAME_EDGE, 88 $project_phid, 89 $material_type); 90 91 $want_rows = queryfx_all( 92 $conn_w, 93 'SELECT dst, dateCreated, seq FROM %T 94 WHERE src IN (%Ls) AND type = %d', 95 PhabricatorEdgeConfig::TABLE_NAME_EDGE, 96 $source_phids, 97 $member_type); 98 99 $have_phids = ipull($have_rows, 'dst', 'dst'); 100 $want_phids = ipull($want_rows, null, 'dst'); 101 102 $rem_phids = array_diff_key($have_phids, $want_phids); 103 $rem_phids = array_keys($rem_phids); 104 105 $add_phids = array_diff_key($want_phids, $have_phids); 106 $add_phids = array_keys($add_phids); 107 108 $rem_sql = array(); 109 foreach ($rem_phids as $rem_phid) { 110 $rem_sql[] = qsprintf( 111 $conn_w, 112 '%s', 113 $rem_phid); 114 } 115 116 $add_sql = array(); 117 foreach ($add_phids as $add_phid) { 118 $add_row = $want_phids[$add_phid]; 119 $add_sql[] = qsprintf( 120 $conn_w, 121 '(%s, %d, %s, %d, %d)', 122 $project_phid, 123 $material_type, 124 $add_row['dst'], 125 $add_row['dateCreated'], 126 $add_row['seq']); 127 } 128 129 // Remove materialized members who are no longer project members. 130 131 if ($rem_sql) { 132 foreach (PhabricatorLiskDAO::chunkSQL($rem_sql) as $sql_chunk) { 133 queryfx( 134 $conn_w, 135 'DELETE FROM %T 136 WHERE src = %s AND type = %s AND dst IN (%LQ)', 137 PhabricatorEdgeConfig::TABLE_NAME_EDGE, 138 $project_phid, 139 $material_type, 140 $sql_chunk); 141 } 142 } 143 144 // Add project members who are not yet materialized members. 145 146 if ($add_sql) { 147 foreach (PhabricatorLiskDAO::chunkSQL($add_sql) as $sql_chunk) { 148 queryfx( 149 $conn_w, 150 'INSERT IGNORE INTO %T (src, type, dst, dateCreated, seq) 151 VALUES %LQ', 152 PhabricatorEdgeConfig::TABLE_NAME_EDGE, 153 $sql_chunk); 154 } 155 } 156 157 // Update the hasSubprojects flag. 158 queryfx( 159 $conn_w, 160 'UPDATE %T SET hasSubprojects = %d WHERE id = %d', 161 $project->getTableName(), 162 (int)$has_subprojects, 163 $project->getID()); 164 165 // Update the hasMilestones flag. 166 queryfx( 167 $conn_w, 168 'UPDATE %T SET hasMilestones = %d WHERE id = %d', 169 $project->getTableName(), 170 (int)$has_milestones, 171 $project->getID()); 172 173 $project->saveTransaction(); 174 } 175 176}