@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
1<?php
2
3/**
4 * Configuration source which reads from a stack of other configuration
5 * sources.
6 *
7 * This source is writable if any source in the stack is writable. Writes happen
8 * to the first writable source only.
9 */
10final class PhabricatorConfigStackSource
11 extends PhabricatorConfigSource {
12
13 private $stack = array();
14
15 public function pushSource(PhabricatorConfigSource $source) {
16 array_unshift($this->stack, $source);
17 return $this;
18 }
19
20 public function popSource() {
21 if (empty($this->stack)) {
22 throw new Exception(pht('Popping an empty %s!', self::class));
23 }
24 return array_shift($this->stack);
25 }
26
27 public function getStack() {
28 return $this->stack;
29 }
30
31 public function getKeys(array $keys) {
32 $result = array();
33 foreach ($this->stack as $source) {
34 $result = $result + $source->getKeys($keys);
35 }
36 return $result;
37 }
38
39 public function getAllKeys() {
40 $result = array();
41 foreach ($this->stack as $source) {
42 $result = $result + $source->getAllKeys();
43 }
44 return $result;
45 }
46
47 public function canWrite() {
48 foreach ($this->stack as $source) {
49 if ($source->canWrite()) {
50 return true;
51 }
52 }
53 return false;
54 }
55
56 public function setKeys(array $keys) {
57 foreach ($this->stack as $source) {
58 if ($source->canWrite()) {
59 $source->setKeys($keys);
60 return;
61 }
62 }
63
64 // We can't write; this will throw an appropriate exception.
65 parent::setKeys($keys);
66 }
67
68 public function deleteKeys(array $keys) {
69 foreach ($this->stack as $source) {
70 if ($source->canWrite()) {
71 $source->deleteKeys($keys);
72 return;
73 }
74 }
75
76 // We can't write; this will throw an appropriate exception.
77 parent::deleteKeys($keys);
78 }
79
80}