PageRenderTime 35ms CodeModel.GetById 10ms RepoModel.GetById 0ms app.codeStats 0ms

/src/applications/phid/handle/data/PhabricatorObjectHandleData.php

http://github.com/facebook/phabricator
PHP | 493 lines | 424 code | 49 blank | 20 comment | 46 complexity | 4712a3453d8336f2144c312b26b1d4ad MD5 | raw file
Possible License(s): JSON, MPL-2.0-no-copyleft-exception, Apache-2.0, BSD-3-Clause, LGPL-2.0, MIT, LGPL-2.1, LGPL-3.0
  1. <?php
  2. /*
  3. * Copyright 2012 Facebook, Inc.
  4. *
  5. * Licensed under the Apache License, Version 2.0 (the "License");
  6. * you may not use this file except in compliance with the License.
  7. * You may obtain a copy of the License at
  8. *
  9. * http://www.apache.org/licenses/LICENSE-2.0
  10. *
  11. * Unless required by applicable law or agreed to in writing, software
  12. * distributed under the License is distributed on an "AS IS" BASIS,
  13. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14. * See the License for the specific language governing permissions and
  15. * limitations under the License.
  16. */
  17. class PhabricatorObjectHandleData {
  18. private $phids;
  19. public function __construct(array $phids) {
  20. $this->phids = array_unique($phids);
  21. }
  22. public function loadObjects() {
  23. $types = array();
  24. foreach ($this->phids as $phid) {
  25. $type = $this->lookupType($phid);
  26. $types[$type][] = $phid;
  27. }
  28. $objects = array_fill_keys($this->phids, null);
  29. foreach ($types as $type => $phids) {
  30. switch ($type) {
  31. case PhabricatorPHIDConstants::PHID_TYPE_USER:
  32. $user_dao = newv('PhabricatorUser', array());
  33. $users = $user_dao->loadAllWhere(
  34. 'phid in (%Ls)',
  35. $phids);
  36. foreach ($users as $user) {
  37. $objects[$user->getPHID()] = $user;
  38. }
  39. break;
  40. case PhabricatorPHIDConstants::PHID_TYPE_CMIT:
  41. $commit_dao = newv('PhabricatorRepositoryCommit', array());
  42. $commits = $commit_dao->loadAllWhere(
  43. 'phid IN (%Ls)',
  44. $phids);
  45. $commit_data = array();
  46. if ($commits) {
  47. $data_dao = newv('PhabricatorRepositoryCommitData', array());
  48. $commit_data = $data_dao->loadAllWhere(
  49. 'commitID IN (%Ld)',
  50. mpull($commits, 'getID'));
  51. $commit_data = mpull($commit_data, null, 'getCommitID');
  52. }
  53. foreach ($commits as $commit) {
  54. $data = idx($commit_data, $commit->getID());
  55. if ($data) {
  56. $commit->attachCommitData($data);
  57. $objects[$commit->getPHID()] = $commit;
  58. } else {
  59. // If we couldn't load the commit data, just act as though we
  60. // couldn't load the object at all so we don't load half an object.
  61. }
  62. }
  63. break;
  64. case PhabricatorPHIDConstants::PHID_TYPE_TASK:
  65. $task_dao = newv('ManiphestTask', array());
  66. $tasks = $task_dao->loadAllWhere(
  67. 'phid IN (%Ls)',
  68. $phids);
  69. foreach ($tasks as $task) {
  70. $objects[$task->getPHID()] = $task;
  71. }
  72. break;
  73. case PhabricatorPHIDConstants::PHID_TYPE_DREV:
  74. $revision_dao = newv('DifferentialRevision', array());
  75. $revisions = $revision_dao->loadAllWhere(
  76. 'phid IN (%Ls)',
  77. $phids);
  78. foreach ($revisions as $revision) {
  79. $objects[$revision->getPHID()] = $revision;
  80. }
  81. break;
  82. }
  83. }
  84. return $objects;
  85. }
  86. public function loadHandles() {
  87. $types = array();
  88. foreach ($this->phids as $phid) {
  89. $type = $this->lookupType($phid);
  90. $types[$type][] = $phid;
  91. }
  92. $handles = array();
  93. $external_loaders = PhabricatorEnv::getEnvConfig('phid.external-loaders');
  94. foreach ($types as $type => $phids) {
  95. switch ($type) {
  96. case PhabricatorPHIDConstants::PHID_TYPE_MAGIC:
  97. // Black magic!
  98. foreach ($phids as $phid) {
  99. $handle = new PhabricatorObjectHandle();
  100. $handle->setPHID($phid);
  101. $handle->setType($type);
  102. switch ($phid) {
  103. case ManiphestTaskOwner::OWNER_UP_FOR_GRABS:
  104. $handle->setName('Up For Grabs');
  105. $handle->setFullName('upforgrabs (Up For Grabs)');
  106. $handle->setComplete(true);
  107. break;
  108. default:
  109. $handle->setName('Foul Magicks');
  110. break;
  111. }
  112. $handles[$phid] = $handle;
  113. }
  114. break;
  115. case PhabricatorPHIDConstants::PHID_TYPE_USER:
  116. $class = 'PhabricatorUser';
  117. PhutilSymbolLoader::loadClass($class);
  118. $object = newv($class, array());
  119. $users = $object->loadAllWhere('phid IN (%Ls)', $phids);
  120. $users = mpull($users, null, 'getPHID');
  121. $image_phids = mpull($users, 'getProfileImagePHID');
  122. $image_phids = array_unique(array_filter($image_phids));
  123. $images = array();
  124. if ($image_phids) {
  125. $images = id(new PhabricatorFile())->loadAllWhere(
  126. 'phid IN (%Ls)',
  127. $image_phids);
  128. $images = mpull($images, 'getBestURI', 'getPHID');
  129. }
  130. foreach ($phids as $phid) {
  131. $handle = new PhabricatorObjectHandle();
  132. $handle->setPHID($phid);
  133. $handle->setType($type);
  134. if (empty($users[$phid])) {
  135. $handle->setName('Unknown User');
  136. } else {
  137. $user = $users[$phid];
  138. $handle->setName($user->getUsername());
  139. $handle->setURI('/p/'.$user->getUsername().'/');
  140. $handle->setEmail($user->getEmail());
  141. $handle->setFullName(
  142. $user->getUsername().' ('.$user->getRealName().')');
  143. $handle->setAlternateID($user->getID());
  144. $handle->setComplete(true);
  145. $handle->setDisabled($user->getIsDisabled());
  146. $img_uri = idx($images, $user->getProfileImagePHID());
  147. if ($img_uri) {
  148. $handle->setImageURI($img_uri);
  149. }
  150. }
  151. $handles[$phid] = $handle;
  152. }
  153. break;
  154. case PhabricatorPHIDConstants::PHID_TYPE_MLST:
  155. $class = 'PhabricatorMetaMTAMailingList';
  156. PhutilSymbolLoader::loadClass($class);
  157. $object = newv($class, array());
  158. $lists = $object->loadAllWhere('phid IN (%Ls)', $phids);
  159. $lists = mpull($lists, null, 'getPHID');
  160. foreach ($phids as $phid) {
  161. $handle = new PhabricatorObjectHandle();
  162. $handle->setPHID($phid);
  163. $handle->setType($type);
  164. if (empty($lists[$phid])) {
  165. $handle->setName('Unknown Mailing List');
  166. } else {
  167. $list = $lists[$phid];
  168. $handle->setEmail($list->getEmail());
  169. $handle->setName($list->getName());
  170. $handle->setURI($list->getURI());
  171. $handle->setFullName($list->getName());
  172. $handle->setComplete(true);
  173. }
  174. $handles[$phid] = $handle;
  175. }
  176. break;
  177. case PhabricatorPHIDConstants::PHID_TYPE_DREV:
  178. $class = 'DifferentialRevision';
  179. PhutilSymbolLoader::loadClass($class);
  180. $object = newv($class, array());
  181. $revs = $object->loadAllWhere('phid in (%Ls)', $phids);
  182. $revs = mpull($revs, null, 'getPHID');
  183. foreach ($phids as $phid) {
  184. $handle = new PhabricatorObjectHandle();
  185. $handle->setPHID($phid);
  186. $handle->setType($type);
  187. if (empty($revs[$phid])) {
  188. $handle->setName('Unknown Revision');
  189. } else {
  190. $rev = $revs[$phid];
  191. $handle->setName($rev->getTitle());
  192. $handle->setURI('/D'.$rev->getID());
  193. $handle->setFullName('D'.$rev->getID().': '.$rev->getTitle());
  194. $handle->setComplete(true);
  195. $status = $rev->getStatus();
  196. if (($status == ArcanistDifferentialRevisionStatus::COMMITTED) ||
  197. ($status == ArcanistDifferentialRevisionStatus::ABANDONED)) {
  198. $closed = PhabricatorObjectHandleStatus::STATUS_CLOSED;
  199. $handle->setStatus($closed);
  200. }
  201. }
  202. $handles[$phid] = $handle;
  203. }
  204. break;
  205. case PhabricatorPHIDConstants::PHID_TYPE_CMIT:
  206. $class = 'PhabricatorRepositoryCommit';
  207. PhutilSymbolLoader::loadClass($class);
  208. $object = newv($class, array());
  209. $commits = $object->loadAllWhere('phid in (%Ls)', $phids);
  210. $commits = mpull($commits, null, 'getPHID');
  211. $repository_ids = array();
  212. $callsigns = array();
  213. if ($commits) {
  214. $repository_ids = mpull($commits, 'getRepositoryID');
  215. $repositories = id(new PhabricatorRepository())->loadAllWhere(
  216. 'id in (%Ld)', array_unique($repository_ids));
  217. $callsigns = mpull($repositories, 'getCallsign');
  218. }
  219. foreach ($phids as $phid) {
  220. $handle = new PhabricatorObjectHandle();
  221. $handle->setPHID($phid);
  222. $handle->setType($type);
  223. if (empty($commits[$phid]) ||
  224. !isset($callsigns[$repository_ids[$phid]])) {
  225. $handle->setName('Unknown Commit');
  226. } else {
  227. $commit = $commits[$phid];
  228. $callsign = $callsigns[$repository_ids[$phid]];
  229. $repository = $repositories[$repository_ids[$phid]];
  230. $commit_identifier = $commit->getCommitIdentifier();
  231. // In case where the repository for the commit was deleted,
  232. // we don't have have info about the repository anymore.
  233. if ($repository) {
  234. $vcs = $repository->getVersionControlSystem();
  235. if ($vcs == PhabricatorRepositoryType::REPOSITORY_TYPE_GIT) {
  236. $short_identifier = substr($commit_identifier, 0, 16);
  237. } else {
  238. $short_identifier = $commit_identifier;
  239. }
  240. $handle->setName('r'.$callsign.$short_identifier);
  241. } else {
  242. $handle->setName('Commit '.'r'.$callsign.$commit_identifier);
  243. }
  244. $handle->setURI('/r'.$callsign.$commit_identifier);
  245. $handle->setFullName('r'.$callsign.$commit_identifier);
  246. $handle->setTimestamp($commit->getEpoch());
  247. $handle->setComplete(true);
  248. }
  249. $handles[$phid] = $handle;
  250. }
  251. break;
  252. case PhabricatorPHIDConstants::PHID_TYPE_TASK:
  253. $class = 'ManiphestTask';
  254. PhutilSymbolLoader::loadClass($class);
  255. $object = newv($class, array());
  256. $tasks = $object->loadAllWhere('phid in (%Ls)', $phids);
  257. $tasks = mpull($tasks, null, 'getPHID');
  258. foreach ($phids as $phid) {
  259. $handle = new PhabricatorObjectHandle();
  260. $handle->setPHID($phid);
  261. $handle->setType($type);
  262. if (empty($tasks[$phid])) {
  263. $handle->setName('Unknown Revision');
  264. } else {
  265. $task = $tasks[$phid];
  266. $handle->setName($task->getTitle());
  267. $handle->setURI('/T'.$task->getID());
  268. $handle->setFullName('T'.$task->getID().': '.$task->getTitle());
  269. $handle->setComplete(true);
  270. $handle->setAlternateID($task->getID());
  271. if ($task->getStatus() != ManiphestTaskStatus::STATUS_OPEN) {
  272. $closed = PhabricatorObjectHandleStatus::STATUS_CLOSED;
  273. $handle->setStatus($closed);
  274. }
  275. }
  276. $handles[$phid] = $handle;
  277. }
  278. break;
  279. case PhabricatorPHIDConstants::PHID_TYPE_FILE:
  280. $class = 'PhabricatorFile';
  281. PhutilSymbolLoader::loadClass($class);
  282. $object = newv($class, array());
  283. $files = $object->loadAllWhere('phid IN (%Ls)', $phids);
  284. $files = mpull($files, null, 'getPHID');
  285. foreach ($phids as $phid) {
  286. $handle = new PhabricatorObjectHandle();
  287. $handle->setPHID($phid);
  288. $handle->setType($type);
  289. if (empty($files[$phid])) {
  290. $handle->setName('Unknown File');
  291. } else {
  292. $file = $files[$phid];
  293. $handle->setName($file->getName());
  294. $handle->setURI($file->getBestURI());
  295. $handle->setComplete(true);
  296. }
  297. $handles[$phid] = $handle;
  298. }
  299. break;
  300. case PhabricatorPHIDConstants::PHID_TYPE_PROJ:
  301. $class = 'PhabricatorProject';
  302. PhutilSymbolLoader::loadClass($class);
  303. $object = newv($class, array());
  304. $projects = $object->loadAllWhere('phid IN (%Ls)', $phids);
  305. $projects = mpull($projects, null, 'getPHID');
  306. foreach ($phids as $phid) {
  307. $handle = new PhabricatorObjectHandle();
  308. $handle->setPHID($phid);
  309. $handle->setType($type);
  310. if (empty($projects[$phid])) {
  311. $handle->setName('Unknown Project');
  312. } else {
  313. $project = $projects[$phid];
  314. $handle->setName($project->getName());
  315. $handle->setURI('/project/view/'.$project->getID().'/');
  316. $handle->setComplete(true);
  317. }
  318. $handles[$phid] = $handle;
  319. }
  320. break;
  321. case PhabricatorPHIDConstants::PHID_TYPE_REPO:
  322. $class = 'PhabricatorRepository';
  323. PhutilSymbolLoader::loadClass($class);
  324. $object = newv($class, array());
  325. $repositories = $object->loadAllWhere('phid in (%Ls)', $phids);
  326. $repositories = mpull($repositories, null, 'getPHID');
  327. foreach ($phids as $phid) {
  328. $handle = new PhabricatorObjectHandle();
  329. $handle->setPHID($phid);
  330. $handle->setType($type);
  331. if (empty($repositories[$phid])) {
  332. $handle->setName('Unknown Repository');
  333. } else {
  334. $repository = $repositories[$phid];
  335. $handle->setName($repository->getCallsign());
  336. $handle->setURI('/diffusion/'.$repository->getCallsign().'/');
  337. $handle->setComplete(true);
  338. }
  339. $handles[$phid] = $handle;
  340. }
  341. break;
  342. case PhabricatorPHIDConstants::PHID_TYPE_OPKG:
  343. $class = 'PhabricatorOwnersPackage';
  344. PhutilSymbolLoader::loadClass($class);
  345. $object = newv($class, array());
  346. $packages = $object->loadAllWhere('phid in (%Ls)', $phids);
  347. $packages = mpull($packages, null, 'getPHID');
  348. foreach ($phids as $phid) {
  349. $handle = new PhabricatorObjectHandle();
  350. $handle->setPHID($phid);
  351. $handle->setType($type);
  352. if (empty($packages[$phid])) {
  353. $handle->setName('Unknown Package');
  354. } else {
  355. $package = $packages[$phid];
  356. $handle->setName($package->getName());
  357. $handle->setURI('/owners/package/'.$package->getID().'/');
  358. $handle->setComplete(true);
  359. }
  360. $handles[$phid] = $handle;
  361. }
  362. break;
  363. case PhabricatorPHIDConstants::PHID_TYPE_APRJ:
  364. $project_dao = newv('PhabricatorRepositoryArcanistProject', array());
  365. $projects = $project_dao->loadAllWhere(
  366. 'phid IN (%Ls)',
  367. $phids);
  368. $projects = mpull($projects, null, 'getPHID');
  369. foreach ($phids as $phid) {
  370. $handle = new PhabricatorObjectHandle();
  371. $handle->setPHID($phid);
  372. $handle->setType($type);
  373. if (empty($projects[$phid])) {
  374. $handle->setName('Unknown Arcanist Project');
  375. } else {
  376. $project = $projects[$phid];
  377. $handle->setName($project->getName());
  378. $handle->setComplete(true);
  379. }
  380. $handles[$phid] = $handle;
  381. }
  382. break;
  383. case PhabricatorPHIDConstants::PHID_TYPE_WIKI:
  384. $document_dao = newv('PhrictionDocument', array());
  385. $content_dao = newv('PhrictionContent', array());
  386. $conn = $document_dao->establishConnection('r');
  387. $documents = queryfx_all(
  388. $conn,
  389. 'SELECT * FROM %T document JOIN %T content
  390. ON document.contentID = content.id
  391. WHERE document.phid IN (%Ls)',
  392. $document_dao->getTableName(),
  393. $content_dao->getTableName(),
  394. $phids);
  395. $documents = ipull($documents, null, 'phid');
  396. foreach ($phids as $phid) {
  397. $handle = new PhabricatorObjectHandle();
  398. $handle->setPHID($phid);
  399. $handle->setType($type);
  400. if (empty($documents[$phid])) {
  401. $handle->setName('Unknown Document');
  402. } else {
  403. $info = $documents[$phid];
  404. $handle->setName($info['title']);
  405. $handle->setURI(PhrictionDocument::getSlugURI($info['slug']));
  406. $handle->setComplete(true);
  407. }
  408. $handles[$phid] = $handle;
  409. }
  410. break;
  411. default:
  412. $loader = null;
  413. if (isset($external_loaders[$type])) {
  414. $loader = $external_loaders[$type];
  415. } else if (isset($external_loaders['*'])) {
  416. $loader = $external_loaders['*'];
  417. }
  418. if ($loader) {
  419. PhutilSymbolLoader::loadClass($loader);
  420. $object = newv($loader, array());
  421. $handles += $object->loadHandles($phids);
  422. break;
  423. }
  424. foreach ($phids as $phid) {
  425. $handle = new PhabricatorObjectHandle();
  426. $handle->setType($type);
  427. $handle->setPHID($phid);
  428. $handle->setName('Unknown Object');
  429. $handle->setFullName('An Unknown Object');
  430. $handles[$phid] = $handle;
  431. }
  432. break;
  433. }
  434. }
  435. return $handles;
  436. }
  437. private function lookupType($phid) {
  438. $matches = null;
  439. if (preg_match('/^PHID-([^-]{4})-/', $phid, $matches)) {
  440. return $matches[1];
  441. }
  442. return PhabricatorPHIDConstants::PHID_TYPE_UNKNOWN;
  443. }
  444. }