Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/phabricator
Path: blob/master/src/applications/owners/storage/PhabricatorOwnersPath.php
12256 views
1
<?php
2
3
final class PhabricatorOwnersPath extends PhabricatorOwnersDAO {
4
5
protected $packageID;
6
protected $repositoryPHID;
7
protected $pathIndex;
8
protected $path;
9
protected $pathDisplay;
10
protected $excluded;
11
12
private $fragments;
13
private $fragmentCount;
14
15
protected function getConfiguration() {
16
return array(
17
self::CONFIG_TIMESTAMPS => false,
18
self::CONFIG_COLUMN_SCHEMA => array(
19
'path' => 'text',
20
'pathDisplay' => 'text',
21
'pathIndex' => 'bytes12',
22
'excluded' => 'bool',
23
),
24
self::CONFIG_KEY_SCHEMA => array(
25
'key_path' => array(
26
'columns' => array('packageID', 'repositoryPHID', 'pathIndex'),
27
'unique' => true,
28
),
29
'key_repository' => array(
30
'columns' => array('repositoryPHID', 'pathIndex'),
31
),
32
),
33
) + parent::getConfiguration();
34
}
35
36
public static function newFromRef(array $ref) {
37
$path = new PhabricatorOwnersPath();
38
$path->repositoryPHID = $ref['repositoryPHID'];
39
40
$raw_path = $ref['path'];
41
42
$path->pathIndex = PhabricatorHash::digestForIndex($raw_path);
43
$path->path = $raw_path;
44
$path->pathDisplay = $raw_path;
45
46
$path->excluded = $ref['excluded'];
47
48
return $path;
49
}
50
51
public function getRef() {
52
return array(
53
'repositoryPHID' => $this->getRepositoryPHID(),
54
'path' => $this->getPath(),
55
'display' => $this->getPathDisplay(),
56
'excluded' => (int)$this->getExcluded(),
57
);
58
}
59
60
public static function getTransactionValueChanges(array $old, array $new) {
61
return array(
62
self::getTransactionValueDiff($old, $new),
63
self::getTransactionValueDiff($new, $old),
64
);
65
}
66
67
private static function getTransactionValueDiff(array $u, array $v) {
68
$set = self::getSetFromTransactionValue($v);
69
70
foreach ($u as $key => $ref) {
71
if (self::isRefInSet($ref, $set)) {
72
unset($u[$key]);
73
}
74
}
75
76
return $u;
77
}
78
79
public static function getSetFromTransactionValue(array $v) {
80
$set = array();
81
foreach ($v as $ref) {
82
$key = self::getScalarKeyForRef($ref);
83
$set[$key] = true;
84
}
85
return $set;
86
}
87
88
public static function isRefInSet(array $ref, array $set) {
89
$key = self::getScalarKeyForRef($ref);
90
return isset($set[$key]);
91
}
92
93
private static function getScalarKeyForRef(array $ref) {
94
// See T13464. When building refs from raw transactions, the path has
95
// not been normalized yet and doesn't have a separate "display" path.
96
// If the "display" path isn't populated, just use the actual path to
97
// build the ref key.
98
99
if (isset($ref['display'])) {
100
$display = $ref['display'];
101
} else {
102
$display = $ref['path'];
103
}
104
105
return sprintf(
106
'repository=%s path=%s display=%s excluded=%d',
107
$ref['repositoryPHID'],
108
$ref['path'],
109
$display,
110
$ref['excluded']);
111
}
112
113
114
/**
115
* Get the number of directory matches between this path specification and
116
* some real path.
117
*/
118
public function getPathMatchStrength($path_fragments, $path_count) {
119
$this_path = $this->path;
120
121
if ($this_path === '/') {
122
// The root path "/" just matches everything with strength 1.
123
return 1;
124
}
125
126
if ($this->fragments === null) {
127
$this->fragments = PhabricatorOwnersPackage::splitPath($this_path);
128
$this->fragmentCount = count($this->fragments);
129
}
130
131
$self_fragments = $this->fragments;
132
$self_count = $this->fragmentCount;
133
if ($self_count > $path_count) {
134
// If this path is longer (and therefore more specific) than the target
135
// path, we don't match it at all.
136
return 0;
137
}
138
139
for ($ii = 0; $ii < $self_count; $ii++) {
140
if ($self_fragments[$ii] != $path_fragments[$ii]) {
141
return 0;
142
}
143
}
144
145
return $self_count;
146
}
147
148
}
149
150