Compare commits
389 Commits
Author | SHA1 | Date | |
---|---|---|---|
83bb30c02e | |||
7209e70eee | |||
21c4d6c988 | |||
c898053829 | |||
5906c4a7e9 | |||
9584c480ac | |||
dbb9853e4c | |||
a924b09c84 | |||
21d145c9dd | |||
8eaab28e2e | |||
d026dfa72b | |||
3dab3e6ffb | |||
f9d454431a | |||
d1037ee999 | |||
2ae41b71ce | |||
ee2cdc66a3 | |||
8c725e1f30 | |||
af28ab583d | |||
36c5a9da1e | |||
63443cef58 | |||
4d0bbd65c2 | |||
ab636281d4 | |||
ae771df2af | |||
e76e6e14c0 | |||
b43fabc696 | |||
be6ca4dc7d | |||
06ff69a03c | |||
f28236b2cc | |||
895ebed023 | |||
c06a59147c | |||
2d960622d3 | |||
d50ac79793 | |||
f5633edf97 | |||
2ac637aa24 | |||
092c2411d2 | |||
b967dd64fa | |||
affd4cfd0d | |||
8a882018b9 | |||
![]() |
436e69f1d0 | ||
5db4b6f01a | |||
5aabb434b1 | |||
eced78a591 | |||
fb3e6ba493 | |||
284204e6bb | |||
1df20d771c | |||
6fa976f749 | |||
8808cf8e8c | |||
f72b9824f3 | |||
ac94643ac7 | |||
ce3c14919d | |||
c9fb4c2945 | |||
57099f29d1 | |||
acfdc33789 | |||
a5efb1e8cd | |||
e0bd65be95 | |||
1bcc201b0a | |||
b2d7879162 | |||
775a1c2eef | |||
bd07cea6a6 | |||
6139ce1841 | |||
c38766c17f | |||
f9637502ee | |||
![]() |
0ddfe6fcfb | ||
![]() |
dc57652085 | ||
5ba0687123 | |||
fef207bf00 | |||
5ef3552549 | |||
0f6ca4be21 | |||
4653348b13 | |||
6826284108 | |||
c93fdca80d | |||
432b6d61a6 | |||
4c2b7d7573 | |||
d8e25a6226 | |||
db6f4eaab1 | |||
4555f18c41 | |||
788d8a8b98 | |||
55f22f74f5 | |||
de2f7e857d | |||
7c869ab033 | |||
f9c680ddc0 | |||
8efe191897 | |||
8d6f1a6128 | |||
81bae35d2f | |||
fc5744c7f0 | |||
7aea82d526 | |||
cb29054e66 | |||
0416648b39 | |||
01fea69352 | |||
c7a2133639 | |||
a162f188c2 | |||
2b54804c7b | |||
a8fef30871 | |||
9dc4d903c7 | |||
b8b18995c5 | |||
971b397133 | |||
aee7dc94bc | |||
feb8db1212 | |||
f9f7f005f2 | |||
2321a886ae | |||
72858c6746 | |||
79ca5a3026 | |||
3d37998174 | |||
ce29e40b57 | |||
ef26d6afdc | |||
dc84bc9391 | |||
321eb18cd7 | |||
6936b8c4f3 | |||
26f43ee9b8 | |||
e19d318af9 | |||
dfc7f764de | |||
331b4cc42c | |||
674d537f91 | |||
a442a019d9 | |||
774a554405 | |||
90f56e07ff | |||
4b428ffb8a | |||
bcd0caecd1 | |||
78c32afa4e | |||
f3302fe1b9 | |||
7eba06c43d | |||
713f8e2c6a | |||
ea0100310b | |||
4332bfe537 | |||
25ce2bdd92 | |||
dc17ef4f7c | |||
8097508909 | |||
8addc33734 | |||
990136a337 | |||
d14b204aae | |||
4067829d2c | |||
8bc4c8c485 | |||
bf8aec2a14 | |||
ace2787868 | |||
08dde1da13 | |||
4cde7a4b06 | |||
42ce8a82af | |||
6d6e446f6f | |||
26bf667fec | |||
18b9c9b0b1 | |||
f78ca8833b | |||
19337de8f0 | |||
c2a4fbc98c | |||
87c0e13efd | |||
3442097b31 | |||
c7764ed1d0 | |||
6e39022af9 | |||
d88716feba | |||
678347d836 | |||
890ccea846 | |||
405525357d | |||
3eee2a3311 | |||
55d1f0081d | |||
ea73d9bf86 | |||
3eab15180c | |||
2210be45fe | |||
5bdc3dfad8 | |||
c22440fe30 | |||
b41844290b | |||
32a3440156 | |||
630eb3c143 | |||
534b628ad2 | |||
8a463524b4 | |||
b50eefbd5b | |||
3a2ebeca11 | |||
95f7da61a9 | |||
0d04beb777 | |||
7ab26ff7af | |||
6800fc6103 | |||
9077c1f24f | |||
2327f2af6f | |||
41fff9c930 | |||
cfcef40c65 | |||
29d158a3bc | |||
411cf324dd | |||
52230a803f | |||
ddf6f275db | |||
8c65ee54d0 | |||
d07d44fcc7 | |||
772d59f0ab | |||
f7da3f88f9 | |||
e4f6cf9993 | |||
dd34c93656 | |||
320ffa2308 | |||
b5e7136f68 | |||
e2b7664451 | |||
725ad07e6f | |||
75cbd69d85 | |||
a9a71ef011 | |||
362ba36695 | |||
38d687ede2 | |||
78cd1cf494 | |||
0b990d42cd | |||
74571de5b6 | |||
01ce61f6e2 | |||
09c9aa078d | |||
73441d690e | |||
afdc21ee04 | |||
fc317b7f28 | |||
b3f2b7faf4 | |||
7ea70dcb53 | |||
d0b90fdef7 | |||
3c05d31d2e | |||
11f5eb21af | |||
c90665645e | |||
fb3c71820b | |||
e533774ac0 | |||
647f8de9bb | |||
599bf57cd8 | |||
50c506ea2d | |||
4cc7990b1a | |||
4ef5fdefb2 | |||
a018837214 | |||
e74f0e1558 | |||
fd882b5167 | |||
15bda62b89 | |||
5e4ce96266 | |||
dbd2f0d06f | |||
c87e657412 | |||
6275e3f08f | |||
bc2e4a2452 | |||
ba7d9fb724 | |||
c50ab96abb | |||
fa68c6a0fa | |||
d1b60fec48 | |||
99a839605c | |||
08f5b3e920 | |||
87e0a26d24 | |||
91c07e9f99 | |||
9b2b75e4b4 | |||
77c913c70a | |||
1a1bea527c | |||
46f8f6d90d | |||
dbad3b6489 | |||
1821cedbc4 | |||
1448eafd64 | |||
8f4047b36a | |||
2683fde42a | |||
02522d877d | |||
769ffa2982 | |||
33eed14141 | |||
a0bd47a012 | |||
8c14ef97bf | |||
5bdfbe8250 | |||
f2319c9689 | |||
c3138c6497 | |||
56e8308621 | |||
cb6a8756b6 | |||
e7242143a0 | |||
c12898b63a | |||
9453f29deb | |||
9093816113 | |||
3471c1b87e | |||
30f0de9427 | |||
5278e94566 | |||
08b1e9d764 | |||
30427e0626 | |||
752a5b9bc3 | |||
a5390d5461 | |||
a02fa19d5a | |||
f88bdcd4ff | |||
b98f8a570c | |||
644070340d | |||
93fecfe7e9 | |||
53bb3ac361 | |||
137df8c6d3 | |||
9863285bf0 | |||
a392b4a14f | |||
d03569e908 | |||
b1097e9c61 | |||
5bda6bf48b | |||
a03cdacd9e | |||
c3fe33f5a0 | |||
5d823ff1a7 | |||
63df9dd1f4 | |||
0c80c9fead | |||
b8d42a7cc6 | |||
4e7dc30fea | |||
99c68b1091 | |||
d48979091e | |||
785caa5b6c | |||
261d7331f4 | |||
28bd8409df | |||
47008a157c | |||
fc1e8681ef | |||
17085b4379 | |||
dd6eefcd9c | |||
ae2b0e63d6 | |||
bcbae097de | |||
b59dca4eeb | |||
8098798fa9 | |||
d8d0e2c99f | |||
214233f82f | |||
eebe82c990 | |||
5b73071d64 | |||
cd04de7f72 | |||
cf4b1317e1 | |||
10e353b090 | |||
81bd756ec6 | |||
9527d8aafd | |||
e35bc58e0e | |||
bd0f9fd913 | |||
44957f7806 | |||
7ff26eb95d | |||
1f2471fa67 | |||
7a5588a408 | |||
ac03ae737f | |||
f9db95f555 | |||
2bc045a997 | |||
531b0fa529 | |||
6b1ed4fb9b | |||
645a6a9f54 | |||
88cd291b0f | |||
76e4aaf429 | |||
365f8ad981 | |||
0af08f9469 | |||
23ce658af7 | |||
0a54474f98 | |||
93ca9ed3a8 | |||
d110fdccc2 | |||
4197d983bf | |||
d23883b799 | |||
675d2ac374 | |||
5c86735ab7 | |||
566274dcac | |||
de2814545b | |||
4ea26f22c4 | |||
458bc7f921 | |||
3839698e4a | |||
b403863e62 | |||
246b73f922 | |||
6da7f462a9 | |||
90874b8b00 | |||
7e874a33fb | |||
bbe357e5c0 | |||
428cdae3cf | |||
1c689a6b24 | |||
55972ef2c1 | |||
966687d1ab | |||
6a86144adf | |||
57765e88c0 | |||
60cddad047 | |||
a77a33dc50 | |||
405a07e638 | |||
75f9ce9d77 | |||
259588e747 | |||
0e8b746fb0 | |||
753917c10c | |||
39f7364f25 | |||
8d7de5fcb6 | |||
01398f762b | |||
e12d2efe81 | |||
5c7055d840 | |||
562c7aa126 | |||
5994088e50 | |||
9edbe22e19 | |||
7fabfff397 | |||
356a2fe0e8 | |||
54193ebb15 | |||
2b4bb9cddd | |||
2758907517 | |||
a7f641eee2 | |||
9799ceff80 | |||
26e86c2171 | |||
f6c293fb4d | |||
5abc5cf9f8 | |||
41a820fdf0 | |||
2c8b09da21 | |||
a7ff526360 | |||
1a8148be97 | |||
199dd85140 | |||
f6c44fdb03 | |||
1aade72cb1 | |||
121c9d308b | |||
d60a47ab5b | |||
8af9b8796f | |||
7dd7673fb3 | |||
aeaf0902e1 | |||
498842475c | |||
755177508e | |||
5b49fd93e2 | |||
968ea35b03 | |||
97ed90b82a | |||
ba34aa535a | |||
e56041da3b | |||
b19fbc39af | |||
1036d419fa | |||
0011789443 | |||
ff7d71fb87 |
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"phabricator.uri": "https://secure.phabricator.com/",
|
||||
"phabricator.uri": "https://developer.blender.org/",
|
||||
"load": ["src/"],
|
||||
"history.immutable": false
|
||||
}
|
||||
|
3
.gitignore
vendored
@@ -40,3 +40,6 @@
|
||||
# Places for users to add custom resources.
|
||||
/resources/cows/custom/*
|
||||
/resources/figlet/custom/*
|
||||
|
||||
# blender migration files
|
||||
migration/dump/
|
||||
|
610
migration/dedup.php
Normal file
@@ -0,0 +1,610 @@
|
||||
<?php
|
||||
|
||||
$migrate_dedup_users = array();
|
||||
|
||||
$migrate_dedup_users["midiclub"] = "midclub";
|
||||
$migrate_dedup_users["trip"] = "car";
|
||||
$migrate_dedup_users["thunderbolt"] = "thunderbolt16";
|
||||
$migrate_dedup_users["avirnig"] = "beav";
|
||||
$migrate_dedup_users["jeaninmontreal"] = "jeanm";
|
||||
$migrate_dedup_users["nneo"] = "nneonneo";
|
||||
$migrate_dedup_users["ebonyj"] = "jim";
|
||||
$migrate_dedup_users["tnr"] = "ichem";
|
||||
$migrate_dedup_users["archus"] = "rstehwien";
|
||||
$migrate_dedup_users["kalysto"] = "kalar";
|
||||
$migrate_dedup_users["eloe"] = "mouvanteloe";
|
||||
$migrate_dedup_users["erdling"] = "eitj";
|
||||
$migrate_dedup_users["cwinebrinner"] = "chuck_1027";
|
||||
$migrate_dedup_users["foo"] = "mfranz";
|
||||
$migrate_dedup_users["f00fbug"] = "viviowns";
|
||||
$migrate_dedup_users["olavbalm"] = "olav";
|
||||
$migrate_dedup_users["kapong"] = "el_kapong";
|
||||
$migrate_dedup_users["thorax"] = "rofthorax";
|
||||
$migrate_dedup_users["kramer3d"] = "asdfghytrewq";
|
||||
$migrate_dedup_users["reevee"] = "vee";
|
||||
$migrate_dedup_users["matzeb"] = "matzebraun";
|
||||
$migrate_dedup_users["jmsoler"] = "jms";
|
||||
$migrate_dedup_users["aqa"] = "angelito";
|
||||
$migrate_dedup_users["blendorphin"] = "blenergetic";
|
||||
$migrate_dedup_users["paolo"] = "jody";
|
||||
$migrate_dedup_users["blendedidea"] = "chubango";
|
||||
$migrate_dedup_users["ruiramos"] = "p3ctu5";
|
||||
$migrate_dedup_users["head_chees"] = "vassilizaitsaf";
|
||||
$migrate_dedup_users["kiernan"] = "rofthorax";
|
||||
$migrate_dedup_users["olaf_arnold"] = "olafarnold";
|
||||
$migrate_dedup_users["joseyanesaltos"] = "joseyanes";
|
||||
$migrate_dedup_users["nicholasfrancis"] = "nicholas";
|
||||
$migrate_dedup_users["briancary"] = "brinux";
|
||||
$migrate_dedup_users["piotrek"] = "ccpiotr";
|
||||
$migrate_dedup_users["slashdev"] = "colonel_panic";
|
||||
$migrate_dedup_users["rj2004"] = "rjblender";
|
||||
$migrate_dedup_users["jeffreymcgrew"] = "toast";
|
||||
$migrate_dedup_users["hendersj"] = "jhenderson";
|
||||
$migrate_dedup_users["pierpy"] = "pier";
|
||||
$migrate_dedup_users["buschhardt"] = "ishtar";
|
||||
$migrate_dedup_users["timlesher"] = "tim";
|
||||
$migrate_dedup_users["tizmo"] = "timlucas";
|
||||
$migrate_dedup_users["pprandin"] = "pashaweb";
|
||||
$migrate_dedup_users["servivo"] = "taz";
|
||||
$migrate_dedup_users["stabby"] = "xingo";
|
||||
$migrate_dedup_users["jimmydietulpe"] = "jimmadietulpe";
|
||||
$migrate_dedup_users["palmnet"] = "palmer";
|
||||
$migrate_dedup_users["graphique-chti"] = "gcprod";
|
||||
$migrate_dedup_users["dreamkatana1"] = "dreamkatana";
|
||||
$migrate_dedup_users["wolverine"] = "shane";
|
||||
$migrate_dedup_users["schwarz"] = "wene";
|
||||
$migrate_dedup_users["justtesting"] = "levon";
|
||||
$migrate_dedup_users["erwin_xnan"] = "erwin";
|
||||
$migrate_dedup_users["zack"] = "krystof";
|
||||
$migrate_dedup_users["fabinator31"] = "fab31";
|
||||
$migrate_dedup_users["themilkman"] = "cliftonium";
|
||||
$migrate_dedup_users["etiennel"] = "choupi";
|
||||
$migrate_dedup_users["m_i_c_h_e_l"] = "michaels";
|
||||
$migrate_dedup_users["techrolla"] = "muffinpeddler";
|
||||
$migrate_dedup_users["fireflymantis"] = "twilight";
|
||||
$migrate_dedup_users["pinucset0"] = "pinucset";
|
||||
$migrate_dedup_users["franzrogar"] = "blender-i18n-po";
|
||||
$migrate_dedup_users["pinucset1"] = "pinucset";
|
||||
$migrate_dedup_users["pinucset3"] = "pinucset";
|
||||
$migrate_dedup_users["threeddream"] = "x-axis";
|
||||
$migrate_dedup_users["mudbot"] = "laurence";
|
||||
$migrate_dedup_users["ligeyx"] = "ligey";
|
||||
$migrate_dedup_users["dreas"] = "dre";
|
||||
$migrate_dedup_users["joorvapl"] = "joorva";
|
||||
$migrate_dedup_users["voyage"] = "xenithi";
|
||||
$migrate_dedup_users["azter"] = "azterix";
|
||||
$migrate_dedup_users["lapinbleu"] = "simeon";
|
||||
$migrate_dedup_users["emmanuel_t"] = "emmanuel";
|
||||
$migrate_dedup_users["cricket"] = "gku";
|
||||
$migrate_dedup_users["justanumber"] = "mad4linux";
|
||||
$migrate_dedup_users["johnnyen"] = "johnny";
|
||||
$migrate_dedup_users["leiota"] = "marcopolo";
|
||||
$migrate_dedup_users["blackstorm"] = "ikbendirk";
|
||||
$migrate_dedup_users["richie"] = "ligey";
|
||||
$migrate_dedup_users["mrcarnivore2"] = "mrcarnivore";
|
||||
$migrate_dedup_users["muddym1nd"] = "muddymind";
|
||||
$migrate_dedup_users["eumesmo"] = "vasco_da_gama";
|
||||
$migrate_dedup_users["ph-kby"] = "olav";
|
||||
$migrate_dedup_users["piotrek_"] = "ccpiotr";
|
||||
$migrate_dedup_users["joaquin"] = "prospero";
|
||||
$migrate_dedup_users["konrad_haenel"] = "konrad8ha";
|
||||
$migrate_dedup_users["benstabler"] = "lightning";
|
||||
$migrate_dedup_users["gustav"] = "draknoid";
|
||||
$migrate_dedup_users["slikdigit"] = "bassamk";
|
||||
$migrate_dedup_users["karlerlandsen"] = "lethalsidep";
|
||||
$migrate_dedup_users["djwillmsoh"] = "djw1";
|
||||
$migrate_dedup_users["aschmitz"] = "root_42";
|
||||
$migrate_dedup_users["malfunc"] = "mcq";
|
||||
$migrate_dedup_users["m_jack"] = "jack";
|
||||
$migrate_dedup_users["davey"] = "madcow";
|
||||
$migrate_dedup_users["iraytrace"] = "butler";
|
||||
$migrate_dedup_users["duser"] = "mslechols";
|
||||
$migrate_dedup_users["akito"] = "ton";
|
||||
$migrate_dedup_users["jochenschmitt"] = "s4504kr";
|
||||
$migrate_dedup_users["digikiller"] = "ace1";
|
||||
$migrate_dedup_users["shzhc"] = "zzzz";
|
||||
$migrate_dedup_users["cyrilbrulebois"] = "kibi";
|
||||
$migrate_dedup_users["themushroom"] = "draknoid";
|
||||
$migrate_dedup_users["zinkmaster"] = "mariolink";
|
||||
$migrate_dedup_users["ashsid"] = "ash";
|
||||
$migrate_dedup_users["novato"] = "jimenez";
|
||||
$migrate_dedup_users["jadie_p"] = "jadie";
|
||||
$migrate_dedup_users["neshshah007"] = "neshrai";
|
||||
$migrate_dedup_users["ryanshow"] = "tankcoder";
|
||||
$migrate_dedup_users["squarelinesq"] = "squareline";
|
||||
$migrate_dedup_users["virginijus"] = "ernestas1994";
|
||||
$migrate_dedup_users["renderdemon"] = "pnio";
|
||||
$migrate_dedup_users["kwab"] = "kobi";
|
||||
$migrate_dedup_users["peterjonckheere"] = "jonckheerep";
|
||||
$migrate_dedup_users["vidar"] = "vidarino";
|
||||
$migrate_dedup_users["sapjohannes"] = "johannesje";
|
||||
$migrate_dedup_users["youri"] = "ayers";
|
||||
$migrate_dedup_users["theamiman"] = "amiman";
|
||||
$migrate_dedup_users["chrisg_ksi"] = "red_planet";
|
||||
$migrate_dedup_users["blenderorgfan"] = "franciscosilva";
|
||||
$migrate_dedup_users["ericd"] = "ericdrayer";
|
||||
$migrate_dedup_users["asdfghjkl2"] = "asdfghjkl";
|
||||
$migrate_dedup_users["quorn"] = "alienit";
|
||||
$migrate_dedup_users["daan221"] = "phoenix221";
|
||||
$migrate_dedup_users["user"] = "mslechols";
|
||||
$migrate_dedup_users["pyb"] = "lomperillo";
|
||||
$migrate_dedup_users["g56"] = "gwald";
|
||||
$migrate_dedup_users["ausland"] = "vots";
|
||||
$migrate_dedup_users["quillinan"] = "orinoco";
|
||||
$migrate_dedup_users["t3tsuj1n"] = "bootsheoz";
|
||||
$migrate_dedup_users["molflesh"] = "melflash";
|
||||
$migrate_dedup_users["rickta59"] = "aerobicsboy";
|
||||
$migrate_dedup_users["nolopoly"] = "lopoly";
|
||||
$migrate_dedup_users["jeel"] = "jl57";
|
||||
$migrate_dedup_users["brianmccumber2"] = "brianmccumber";
|
||||
$migrate_dedup_users["mouette"] = "moutte";
|
||||
$migrate_dedup_users["wout"] = "wonderingwout";
|
||||
$migrate_dedup_users["fatfinger"] = "mattyc";
|
||||
$migrate_dedup_users["nathangull"] = "nateg";
|
||||
$migrate_dedup_users["tampadave"] = "dkmweeks";
|
||||
$migrate_dedup_users["sausages"] = "lethargic";
|
||||
$migrate_dedup_users["chris3d"] = "chrisbd";
|
||||
$migrate_dedup_users["kaito"] = "ton";
|
||||
$migrate_dedup_users["akirasan"] = "akira_b";
|
||||
$migrate_dedup_users["fiddle"] = "rayf";
|
||||
$migrate_dedup_users["bald"] = "manu";
|
||||
$migrate_dedup_users["mistermelquin"] = "melquin";
|
||||
$migrate_dedup_users["kofish"] = "kingdomoffish";
|
||||
$migrate_dedup_users["onanj"] = "orangee";
|
||||
$migrate_dedup_users["jasoncarrier"] = "jason";
|
||||
$migrate_dedup_users["joelgodin"] = "jenniferblender";
|
||||
$migrate_dedup_users["oranj"] = "orangee";
|
||||
$migrate_dedup_users["schdeb"] = "schmidtcristian";
|
||||
$migrate_dedup_users["bastian"] = "angerb";
|
||||
$migrate_dedup_users["patko"] = "patco";
|
||||
$migrate_dedup_users["arakyd666"] = "arakyd";
|
||||
$migrate_dedup_users["karimf"] = "rim-k";
|
||||
$migrate_dedup_users["nletwory"] = "jestertestest";
|
||||
$migrate_dedup_users["mansoorhyder"] = "mansoor";
|
||||
$migrate_dedup_users["rocketmagnet"] = "steventr";
|
||||
$migrate_dedup_users["thekernal"] = "kernal";
|
||||
$migrate_dedup_users["satom"] = "satriatomat";
|
||||
$migrate_dedup_users["a624"] = "a623";
|
||||
$migrate_dedup_users["jldavilacasares"] = "muki";
|
||||
$migrate_dedup_users["segersj"] = "segers";
|
||||
$migrate_dedup_users["hoisan49"] = "hoisan";
|
||||
$migrate_dedup_users["j_bessette"] = "linuxpimp20";
|
||||
$migrate_dedup_users["andreas999"] = "andreas";
|
||||
$migrate_dedup_users["dusan"] = "dsc512";
|
||||
$migrate_dedup_users["dx-mon"] = "mantr100";
|
||||
$migrate_dedup_users["ilislab"] = "ids";
|
||||
$migrate_dedup_users["rben"] = "raybenjamin";
|
||||
$migrate_dedup_users["sphere"] = "dysonsphere";
|
||||
$migrate_dedup_users["highlife22"] = "highlife";
|
||||
$migrate_dedup_users["yonarw"] = "yona";
|
||||
$migrate_dedup_users["kryptic89"] = "kryptic";
|
||||
$migrate_dedup_users["axelp"] = "axel";
|
||||
$migrate_dedup_users["perebalsach"] = "fog22";
|
||||
$migrate_dedup_users["alogerson"] = "gerson";
|
||||
$migrate_dedup_users["cotejrp"] = "cotejrp1";
|
||||
$migrate_dedup_users["tak"] = "carlosjamesr";
|
||||
$migrate_dedup_users["ziddy"] = "anishchandran";
|
||||
$migrate_dedup_users["asdgz"] = "blenderiseur";
|
||||
$migrate_dedup_users["cdated"] = "cdated257";
|
||||
$migrate_dedup_users["jayrkalugin"] = "jayr";
|
||||
$migrate_dedup_users["zeemzoet"] = "johannesje";
|
||||
$migrate_dedup_users["duo"] = "ambyra";
|
||||
$migrate_dedup_users["philb"] = "chewbacca";
|
||||
$migrate_dedup_users["tzi"] = "izt";
|
||||
$migrate_dedup_users["squirrelthetire"] = "squirrel-tire";
|
||||
$migrate_dedup_users["anwyn"] = "sugarshark";
|
||||
$migrate_dedup_users["a2z"] = "a2zaa";
|
||||
$migrate_dedup_users["fxrex"] = "femi";
|
||||
$migrate_dedup_users["alethewiz"] = "mfaso68";
|
||||
$migrate_dedup_users["noseferrit"] = "billybong";
|
||||
$migrate_dedup_users["fcali"] = "fabz";
|
||||
$migrate_dedup_users["bbirchler"] = "bblender";
|
||||
$migrate_dedup_users["oslosewers"] = "oslo";
|
||||
$migrate_dedup_users["wtrsltnk"] = "wtr";
|
||||
$migrate_dedup_users["cspohst"] = "spohst";
|
||||
$migrate_dedup_users["warhawk08"] = "warhawk1990";
|
||||
$migrate_dedup_users["magick_crow"] = "magickcrow";
|
||||
$migrate_dedup_users["guillaumem"] = "guillaume";
|
||||
$migrate_dedup_users["jwitthuhn"] = "rahu";
|
||||
$migrate_dedup_users["fmehigan"] = "frank_me";
|
||||
$migrate_dedup_users["ilissys"] = "ids";
|
||||
$migrate_dedup_users["supermoaaa"] = "moaaa";
|
||||
$migrate_dedup_users["nwmatt"] = "mhenley";
|
||||
$migrate_dedup_users["bezel"] = "xshell";
|
||||
$migrate_dedup_users["rebuss"] = "studioa";
|
||||
$migrate_dedup_users["geonom"] = "geoadel";
|
||||
$migrate_dedup_users["seldan"] = "farakon";
|
||||
$migrate_dedup_users["kuru76"] = "kcorbin";
|
||||
$migrate_dedup_users["kapil"] = "kapilbedarkar";
|
||||
$migrate_dedup_users["henryiii"] = "henryschreiner";
|
||||
$migrate_dedup_users["pateamcarl"] = "carlhuth";
|
||||
$migrate_dedup_users["kamen"] = "bigbob1993";
|
||||
$migrate_dedup_users["olddemon"] = "old_demon";
|
||||
$migrate_dedup_users["draklaw2"] = "draklaw";
|
||||
$migrate_dedup_users["ksdlee"] = "kdlee";
|
||||
$migrate_dedup_users["xource"] = "admix";
|
||||
$migrate_dedup_users["invertednormal"] = "smokebox46and2";
|
||||
$migrate_dedup_users["feelgoodcomics"] = "onlygoodwin";
|
||||
$migrate_dedup_users["glorund"] = "undolaure";
|
||||
$migrate_dedup_users["soulofsound"] = "johnnym";
|
||||
$migrate_dedup_users["ghigi123"] = "ghigi";
|
||||
$migrate_dedup_users["stefanvoigthpi"] = "derstefan";
|
||||
$migrate_dedup_users["dblenderv"] = "default";
|
||||
$migrate_dedup_users["ophiocus"] = "oneliner";
|
||||
$migrate_dedup_users["colleywrks"] = "colley";
|
||||
$migrate_dedup_users["fogy"] = "fog22";
|
||||
$migrate_dedup_users["vidarn"] = "bida70";
|
||||
$migrate_dedup_users["kevin"] = "goblender2541";
|
||||
$migrate_dedup_users["tisachris"] = "warflight";
|
||||
$migrate_dedup_users["personalex2"] = "personalex";
|
||||
$migrate_dedup_users["polypa"] = "lile";
|
||||
$migrate_dedup_users["i4dnf"] = "emilian";
|
||||
$migrate_dedup_users["nitalleb"] = "singleman";
|
||||
$migrate_dedup_users["tcgodoy"] = "godoy";
|
||||
$migrate_dedup_users["joorva_pl"] = "joorva";
|
||||
$migrate_dedup_users["sex"] = "xest";
|
||||
$migrate_dedup_users["chipmunk"] = "ignatz";
|
||||
$migrate_dedup_users["schalmagne"] = "chalmagne";
|
||||
$migrate_dedup_users["michalziulek"] = "eneida";
|
||||
$migrate_dedup_users["jeeps"] = "jeepster";
|
||||
$migrate_dedup_users["yain"] = "chaos";
|
||||
$migrate_dedup_users["amadio"] = "marble";
|
||||
$migrate_dedup_users["javiere"] = "javierchavez";
|
||||
$migrate_dedup_users["drmzperx"] = "mzperx";
|
||||
$migrate_dedup_users["sebastianreaser"] = "sebastian0";
|
||||
$migrate_dedup_users["idolon"] = "spadija";
|
||||
$migrate_dedup_users["alanhzhcn"] = "alanhzh";
|
||||
$migrate_dedup_users["jeanc"] = "jean";
|
||||
$migrate_dedup_users["transblue2"] = "transblue";
|
||||
$migrate_dedup_users["cesarwilfredo"] = "cesar";
|
||||
$migrate_dedup_users["nspyr"] = "spiderfire";
|
||||
$migrate_dedup_users["supermegamoaaa"] = "moaaa";
|
||||
$migrate_dedup_users["firetiger"] = "opensolution";
|
||||
$migrate_dedup_users["skarg"] = "cados";
|
||||
$migrate_dedup_users["realheadcrusher"] = "danigr";
|
||||
$migrate_dedup_users["kpg"] = "nihylius";
|
||||
$migrate_dedup_users["tft"] = "tft67";
|
||||
$migrate_dedup_users["storabbarn"] = "morre";
|
||||
$migrate_dedup_users["bacurau"] = "roger_roo";
|
||||
$migrate_dedup_users["alisari"] = "parasoley";
|
||||
$migrate_dedup_users["skiski"] = "superrom";
|
||||
$migrate_dedup_users["halfninja"] = "nickh";
|
||||
$migrate_dedup_users["drell_develop"] = "drellex";
|
||||
$migrate_dedup_users["highlif3"] = "highlife";
|
||||
$migrate_dedup_users["broggsim1"] = "broggsim";
|
||||
$migrate_dedup_users["blendermanuci"] = "yunior88";
|
||||
$migrate_dedup_users["jpt9"] = "jtuttle";
|
||||
$migrate_dedup_users["farrer"] = "farpro";
|
||||
$migrate_dedup_users["badcheez"] = "randall";
|
||||
$migrate_dedup_users["leewj_"] = "lohns";
|
||||
$migrate_dedup_users["martin107"] = "martinfrances";
|
||||
$migrate_dedup_users["dedpan"] = "tberghuis";
|
||||
$migrate_dedup_users["whiterabbit"] = "dreamscapearts";
|
||||
$migrate_dedup_users["shuvro"] = "shuvro05";
|
||||
$migrate_dedup_users["anichandru"] = "anishchandran";
|
||||
$migrate_dedup_users["ncaralph"] = "ralphdoctorow";
|
||||
$migrate_dedup_users["nlongchamps"] = "nlong";
|
||||
$migrate_dedup_users["mawi37"] = "mawi";
|
||||
$migrate_dedup_users["rizla"] = "jay";
|
||||
$migrate_dedup_users["jeh"] = "mirkril";
|
||||
$migrate_dedup_users["b-fighter"] = "fanatic";
|
||||
$migrate_dedup_users["wasamonkey"] = "wasa";
|
||||
$migrate_dedup_users["nicola"] = "martin45";
|
||||
$migrate_dedup_users["method-es"] = "method";
|
||||
$migrate_dedup_users["pablow"] = "warhole";
|
||||
$migrate_dedup_users["alanishzh"] = "alanhzh";
|
||||
$migrate_dedup_users["thunder947"] = "thunder";
|
||||
$migrate_dedup_users["yijimi"] = "roler";
|
||||
$migrate_dedup_users["jaydenb"] = "logidude";
|
||||
$migrate_dedup_users["leandropolus"] = "leandrosz";
|
||||
$migrate_dedup_users["ibi002"] = "ibi001";
|
||||
$migrate_dedup_users["hakanortasoz"] = "tayfax";
|
||||
$migrate_dedup_users["enur"] = "rune";
|
||||
$migrate_dedup_users["dsuesse"] = "qiip";
|
||||
$migrate_dedup_users["bipedlaboratory"] = "redmetal";
|
||||
$migrate_dedup_users["codeyhanson"] = "codey";
|
||||
$migrate_dedup_users["alphonso_b"] = "alfonso_b";
|
||||
$migrate_dedup_users["surreal6"] = "carlospadial";
|
||||
$migrate_dedup_users["kralizek"] = "kral";
|
||||
$migrate_dedup_users["kfrechet"] = "keithfr";
|
||||
$migrate_dedup_users["jwedlake"] = "joshwedlake";
|
||||
$migrate_dedup_users["westie630"] = "bully";
|
||||
$migrate_dedup_users["fictional"] = "icefire";
|
||||
$migrate_dedup_users["zelozelos"] = "zelozelos1";
|
||||
$migrate_dedup_users["dragonlord"] = "acuena";
|
||||
$migrate_dedup_users["mrcheese"] = "jpeg";
|
||||
$migrate_dedup_users["willemverwey"] = "dandandan";
|
||||
$migrate_dedup_users["jhed"] = "anton_foy";
|
||||
$migrate_dedup_users["treacy1077"] = "briant";
|
||||
$migrate_dedup_users["xest"] = "xembie";
|
||||
$migrate_dedup_users["cyphl25"] = "jmsfreezer";
|
||||
$migrate_dedup_users["wynk"] = "wynn";
|
||||
$migrate_dedup_users["trock2957"] = "trock";
|
||||
$migrate_dedup_users["mr_bomb"] = "carter24";
|
||||
$migrate_dedup_users["nikolaus"] = "tortellini";
|
||||
$migrate_dedup_users["pegasus_001"] = "pegasus001";
|
||||
$migrate_dedup_users["fayte"] = "fayte220";
|
||||
$migrate_dedup_users["jagang_8"] = "jagang";
|
||||
$migrate_dedup_users["thetwom"] = "moe";
|
||||
$migrate_dedup_users["kevlareditor"] = "klthomas";
|
||||
$migrate_dedup_users["damien_deom"] = "dams";
|
||||
$migrate_dedup_users["reynantem"] = "reynante";
|
||||
$migrate_dedup_users["hiralm01"] = "hiralm";
|
||||
$migrate_dedup_users["radix7"] = "wyldethang";
|
||||
$migrate_dedup_users["puppetm"] = "puppetmaster";
|
||||
$migrate_dedup_users["vimax"] = "vimaxus";
|
||||
$migrate_dedup_users["mozzy69"] = "lyndon";
|
||||
$migrate_dedup_users["vitranaccad"] = "thestorm74";
|
||||
$migrate_dedup_users["kj12345"] = "kevinjames";
|
||||
$migrate_dedup_users["foinix"] = "mrnoodle";
|
||||
$migrate_dedup_users["shizu"] = "sntulix";
|
||||
$migrate_dedup_users["kukulcangod23"] = "kukulcangod";
|
||||
$migrate_dedup_users["piliq"] = "qpblendpolis";
|
||||
$migrate_dedup_users["benvad"] = "vbenny";
|
||||
$migrate_dedup_users["fgribben"] = "sharkey";
|
||||
$migrate_dedup_users["makospince"] = "mako_spince";
|
||||
$migrate_dedup_users["ablenderuser"] = "pancakeface";
|
||||
$migrate_dedup_users["axelphi"] = "axel";
|
||||
$migrate_dedup_users["josiasbh"] = "josias";
|
||||
$migrate_dedup_users["mattsix"] = "majawe";
|
||||
$migrate_dedup_users["duarte_ramos"] = "dphantom";
|
||||
$migrate_dedup_users["killogge"] = "muraj";
|
||||
$migrate_dedup_users["luka"] = "omgwtfbbq";
|
||||
$migrate_dedup_users["chromemonkey"] = "brian651msp";
|
||||
$migrate_dedup_users["e_d_i"] = "ide";
|
||||
$migrate_dedup_users["mrhaynesy"] = "haynesy";
|
||||
$migrate_dedup_users["imagineering"] = "imagineer";
|
||||
$migrate_dedup_users["virgiliovasconc"] = "virgilio";
|
||||
$migrate_dedup_users["blenderlb57"] = "louigi";
|
||||
$migrate_dedup_users["nick65"] = "dgnicola";
|
||||
$migrate_dedup_users["mmatthews"] = "mamatthews";
|
||||
$migrate_dedup_users["gerwood"] = "arilian";
|
||||
$migrate_dedup_users["xsidmax"] = "xsi";
|
||||
$migrate_dedup_users["mix-yag"] = "aynahsim";
|
||||
$migrate_dedup_users["wpthomas"] = "tallguy";
|
||||
$migrate_dedup_users["bp007"] = "bender007";
|
||||
$migrate_dedup_users["emach"] = "eon4blender";
|
||||
$migrate_dedup_users["alfclement"] = "alfc";
|
||||
$migrate_dedup_users["blenderwell"] = "goplexian";
|
||||
$migrate_dedup_users["asebastianr"] = "sebastian0";
|
||||
$migrate_dedup_users["joepal1976"] = "joepal";
|
||||
$migrate_dedup_users["chertov"] = "lestat";
|
||||
$migrate_dedup_users["djela63"] = "jerominovich";
|
||||
$migrate_dedup_users["lppinto"] = "lpciper";
|
||||
$migrate_dedup_users["prana"] = "nomath";
|
||||
$migrate_dedup_users["sarubadoru"] = "salvador";
|
||||
$migrate_dedup_users["rarebit"] = "rawstar7";
|
||||
$migrate_dedup_users["hikikamori"] = "hikkikamori";
|
||||
$migrate_dedup_users["mrduke"] = "drop";
|
||||
$migrate_dedup_users["deetee"] = "dertee";
|
||||
$migrate_dedup_users["woooooah"] = "noxwell";
|
||||
$migrate_dedup_users["macoss"] = "ossmac";
|
||||
$migrate_dedup_users["bunnyboy212"] = "blender_buddie";
|
||||
$migrate_dedup_users["maxgrip"] = "czarek";
|
||||
$migrate_dedup_users["tentonman"] = "titandtat";
|
||||
$migrate_dedup_users["jabozzo"] = "bozzo";
|
||||
$migrate_dedup_users["reinways"] = "reinw";
|
||||
$migrate_dedup_users["petergk"] = "nihylius";
|
||||
$migrate_dedup_users["zphr3000"] = "zphr";
|
||||
$migrate_dedup_users["ruivo"] = "andreh";
|
||||
$migrate_dedup_users["kosta"] = "kgd";
|
||||
$migrate_dedup_users["delter"] = "dertee";
|
||||
$migrate_dedup_users["jmiller"] = "lethargic";
|
||||
$migrate_dedup_users["dealga"] = "zeffii";
|
||||
$migrate_dedup_users["bogey"] = "daveh";
|
||||
$migrate_dedup_users["silencebe"] = "silence";
|
||||
$migrate_dedup_users["temozarela"] = "gorn";
|
||||
$migrate_dedup_users["tischite"] = "greenbutton";
|
||||
$migrate_dedup_users["buisson"] = "dinodino";
|
||||
$migrate_dedup_users["cfox"] = "colinfox";
|
||||
$migrate_dedup_users["hunkadoodle"] = "hunkadoodledoo";
|
||||
$migrate_dedup_users["jlwitthuhn"] = "rahu";
|
||||
$migrate_dedup_users["hvfrancesco"] = "hva";
|
||||
$migrate_dedup_users["hazim-jamal"] = "hazim1";
|
||||
$migrate_dedup_users["aurosutru"] = "tlm";
|
||||
$migrate_dedup_users["pierrea"] = "pier2";
|
||||
$migrate_dedup_users["zoon"] = "zoonpolygonikon";
|
||||
$migrate_dedup_users["gruntbatch"] = "carmichael";
|
||||
$migrate_dedup_users["petru"] = "virusanti";
|
||||
$migrate_dedup_users["mikeh74"] = "mikeh";
|
||||
$migrate_dedup_users["sugoi"] = "juntunen";
|
||||
$migrate_dedup_users["bartje"] = "bartart3d";
|
||||
$migrate_dedup_users["yaoyansi"] = "yaoyansi2";
|
||||
$migrate_dedup_users["rafek"] = "rafek_finearts";
|
||||
$migrate_dedup_users["caspern"] = "caspernilsson";
|
||||
$migrate_dedup_users["lee"] = "s_random";
|
||||
$migrate_dedup_users["sparky"] = "mmikkelsen";
|
||||
$migrate_dedup_users["wigglyframes"] = "rene";
|
||||
$migrate_dedup_users["kroni"] = "kronos";
|
||||
$migrate_dedup_users["xgl_asyliax"] = "xglasyliax";
|
||||
$migrate_dedup_users["blendeador"] = "luisperosio";
|
||||
$migrate_dedup_users["kaos1986"] = "kaos86";
|
||||
$migrate_dedup_users["adamdoyle"] = "advs89";
|
||||
$migrate_dedup_users["kahenraz"] = "mistrel";
|
||||
$migrate_dedup_users["ccliffe"] = "cjcliffe";
|
||||
$migrate_dedup_users["nullfied"] = "xercesblue";
|
||||
$migrate_dedup_users["dustyghost"] = "dustbin1_uk";
|
||||
$migrate_dedup_users["claaskuhnen"] = "cekuhnendev";
|
||||
$migrate_dedup_users["vercingetorix"] = "diamond_rust";
|
||||
$migrate_dedup_users["plugboy"] = "centerlaw";
|
||||
$migrate_dedup_users["rben13"] = "raybenjamin";
|
||||
$migrate_dedup_users["deangiberson"] = "voidptr";
|
||||
$migrate_dedup_users["makeitwork"] = "bboybram";
|
||||
$migrate_dedup_users["iljosli"] = "jos";
|
||||
$migrate_dedup_users["slowan"] = "slovan";
|
||||
$migrate_dedup_users["mooonwalkercz"] = "mooonwalker";
|
||||
$migrate_dedup_users["tapplek"] = "tapple";
|
||||
$migrate_dedup_users["blendmond"] = "cornix";
|
||||
$migrate_dedup_users["giorgiomartini"] = "tweakingknobs";
|
||||
$migrate_dedup_users["davidray"] = "deadman";
|
||||
$migrate_dedup_users["justthisguy"] = "nyctef";
|
||||
$migrate_dedup_users["logobar"] = "freyer";
|
||||
$migrate_dedup_users["zooo"] = "leon_cheung";
|
||||
$migrate_dedup_users["josiasalexandre"] = "josias";
|
||||
$migrate_dedup_users["tsukiko_chan"] = "tsukikochan";
|
||||
$migrate_dedup_users["akira_san"] = "akira_b";
|
||||
$migrate_dedup_users["walberti"] = "walbertievarist";
|
||||
$migrate_dedup_users["astro"] = "tnboma";
|
||||
$migrate_dedup_users["mccx"] = "mcq";
|
||||
$migrate_dedup_users["daa84"] = "daa";
|
||||
$migrate_dedup_users["sivert3"] = "cent";
|
||||
$migrate_dedup_users["twentyone"] = "glade";
|
||||
$migrate_dedup_users["endi2"] = "endi";
|
||||
$migrate_dedup_users["jamesr"] = "james_r";
|
||||
$migrate_dedup_users["reece"] = "reecerobinson";
|
||||
$migrate_dedup_users["dustractor"] = "bpygrams";
|
||||
$migrate_dedup_users["pencilhead"] = "pencil-head";
|
||||
$migrate_dedup_users["toml"] = "tomol";
|
||||
$migrate_dedup_users["colinm"] = "tablaman";
|
||||
$migrate_dedup_users["blendphys2"] = "blendphys";
|
||||
$migrate_dedup_users["xgoff"] = "zzyxz";
|
||||
$migrate_dedup_users["coleingraham"] = "coledingraham";
|
||||
$migrate_dedup_users["danielvmacedo"] = "skul3r";
|
||||
$migrate_dedup_users["burster"] = "przemaz";
|
||||
$migrate_dedup_users["tung"] = "tungster";
|
||||
$migrate_dedup_users["chessie"] = "blackcatt";
|
||||
$migrate_dedup_users["foxdog"] = "rubbernuke";
|
||||
$migrate_dedup_users["mordachai"] = "gus";
|
||||
$migrate_dedup_users["chilamlai"] = "cllai";
|
||||
$migrate_dedup_users["sliders34"] = "sliders";
|
||||
$migrate_dedup_users["benji852"] = "benjamin852";
|
||||
$migrate_dedup_users["bebinalpha"] = "bebin";
|
||||
$migrate_dedup_users["mr78"] = "alexandr";
|
||||
$migrate_dedup_users["avirillion"] = "tarion";
|
||||
$migrate_dedup_users["matthiasro"] = "matthias_r";
|
||||
$migrate_dedup_users["debearseax"] = "seogeniuss";
|
||||
$migrate_dedup_users["karja"] = "trockenfrosch";
|
||||
$migrate_dedup_users["rojuinex"] = "ifrit";
|
||||
$migrate_dedup_users["bernardo"] = "dados";
|
||||
$migrate_dedup_users["ddeclara"] = "decden";
|
||||
$migrate_dedup_users["zm_sansan"] = "sansan";
|
||||
$migrate_dedup_users["useless"] = "cortot";
|
||||
$migrate_dedup_users["tymnclono"] = "sooccatly";
|
||||
$migrate_dedup_users["rodrigo_b"] = "rodrigob";
|
||||
$migrate_dedup_users["shnurui"] = "spinster";
|
||||
$migrate_dedup_users["michalisz"] = "michaliszissiou";
|
||||
$migrate_dedup_users["fbbdev"] = "babboide";
|
||||
$migrate_dedup_users["tjackson"] = "tjonline";
|
||||
$migrate_dedup_users["ramaswamy"] = "ramaswamysriram";
|
||||
$migrate_dedup_users["allrod5"] = "rodblender";
|
||||
$migrate_dedup_users["qcp"] = "qpblendpolis";
|
||||
$migrate_dedup_users["ftsf"] = "thesleepless";
|
||||
$migrate_dedup_users["umagoo2012"] = "umagoo";
|
||||
$migrate_dedup_users["raven"] = "rune";
|
||||
$migrate_dedup_users["hsaito"] = "integer";
|
||||
$migrate_dedup_users["paulthegreat"] = "digitalpyro";
|
||||
$migrate_dedup_users["capheen"] = "dval";
|
||||
$migrate_dedup_users["rskinner"] = "rws";
|
||||
$migrate_dedup_users["gregstein"] = "gregorein";
|
||||
$migrate_dedup_users["matty686"] = "matty";
|
||||
$migrate_dedup_users["selby_rowley"] = "selby";
|
||||
$migrate_dedup_users["shembolstudio"] = "natadams8";
|
||||
$migrate_dedup_users["grenzfrequence"] = "goatrance";
|
||||
$migrate_dedup_users["stephan"] = "schdeffan";
|
||||
$migrate_dedup_users["axis33"] = "dsc512";
|
||||
$migrate_dedup_users["redandfish"] = "red-fish";
|
||||
$migrate_dedup_users["artsapcemedia"] = "arzpace";
|
||||
$migrate_dedup_users["artspacemedia"] = "arzpace";
|
||||
$migrate_dedup_users["mccmcc"] = "mcq";
|
||||
$migrate_dedup_users["seocitterx"] = "mediabuy";
|
||||
$migrate_dedup_users["lightning_limn"] = "lightning4";
|
||||
$migrate_dedup_users["omarlakhdar"] = "archimage";
|
||||
$migrate_dedup_users["regeleionescu"] = "regele";
|
||||
$migrate_dedup_users["mitchell_decker"] = "michealikruhara";
|
||||
$migrate_dedup_users["joselebon"] = "jl57";
|
||||
$migrate_dedup_users["simonbroggi"] = "broggsim";
|
||||
$migrate_dedup_users["inwadnepe"] = "ceapbatatry";
|
||||
$migrate_dedup_users["ehobjman"] = "resbsp";
|
||||
$migrate_dedup_users["davelassanske"] = "dolby411";
|
||||
$migrate_dedup_users["jsu"] = "jansub";
|
||||
$migrate_dedup_users["agricola"] = "agricola1";
|
||||
$migrate_dedup_users["bartoszek"] = "bartus";
|
||||
$migrate_dedup_users["captainoblivion"] = "cptoblivion";
|
||||
$migrate_dedup_users["alexmcourt"] = "personalex";
|
||||
$migrate_dedup_users["jmsprss"] = "xonar";
|
||||
$migrate_dedup_users["awarnock"] = "salsa";
|
||||
$migrate_dedup_users["mcc2"] = "mcq";
|
||||
$migrate_dedup_users["psyborg042"] = "psyborg";
|
||||
$migrate_dedup_users["ushiproject"] = "ushi";
|
||||
$migrate_dedup_users["mrjimmy"] = "mrjimmyos";
|
||||
$migrate_dedup_users["thefinalcut"] = "tlousky";
|
||||
$migrate_dedup_users["startheshadow"] = "star";
|
||||
$migrate_dedup_users["axredneck"] = "redneck";
|
||||
$migrate_dedup_users["phimestudio"] = "phime";
|
||||
$migrate_dedup_users["dwatts1"] = "dlax";
|
||||
$migrate_dedup_users["rertjoi"] = "rertjwi";
|
||||
$migrate_dedup_users["erdjkgh"] = "rertjwi";
|
||||
$migrate_dedup_users["libertainsrg"] = "fcougar";
|
||||
$migrate_dedup_users["godling72"] = "dmelchio";
|
||||
$migrate_dedup_users["myclay"] = "thenewone";
|
||||
$migrate_dedup_users["ecaspersen"] = "ecasper";
|
||||
$migrate_dedup_users["driewiel"] = "driesiedriewiel";
|
||||
$migrate_dedup_users["bhupen"] = "bhupendra";
|
||||
$migrate_dedup_users["caosdoar"] = "mailoyo";
|
||||
$migrate_dedup_users["polyspin"] = "butler";
|
||||
$migrate_dedup_users["qalb_al_aqrab"] = "efimpetelin";
|
||||
$migrate_dedup_users["fdfdfdfffd"] = "fcougar";
|
||||
$migrate_dedup_users["brianlockett"] = "macrow";
|
||||
$migrate_dedup_users["claude"] = "coco";
|
||||
$migrate_dedup_users["mattostgard"] = "drflail";
|
||||
$migrate_dedup_users["cekuhnen_new"] = "cekuhnendev";
|
||||
$migrate_dedup_users["kirill_lukyanov"] = "kirill";
|
||||
$migrate_dedup_users["jan-eric"] = "janeric96";
|
||||
$migrate_dedup_users["daniel_h"] = "dhoughto";
|
||||
$migrate_dedup_users["raphaelbarros"] = "thebigheadone";
|
||||
$migrate_dedup_users["salas"] = "tychota";
|
||||
$migrate_dedup_users["danieljsamson"] = "techfix";
|
||||
$migrate_dedup_users["vinagrito"] = "aechemendia";
|
||||
$migrate_dedup_users["lin_165"] = "b1657022405";
|
||||
$migrate_dedup_users["cwebber"] = "paroneayea";
|
||||
$migrate_dedup_users["harolddadomo"] = "harold";
|
||||
$migrate_dedup_users["rabidsquirrel"] = "genericusername";
|
||||
$migrate_dedup_users["larry3"] = "lehibou";
|
||||
$migrate_dedup_users["predoe"] = "petronius3d";
|
||||
$migrate_dedup_users["skoo"] = "stefano";
|
||||
$migrate_dedup_users["cabergolinety"] = "azathioprinewww";
|
||||
$migrate_dedup_users["prestijkorsan07"] = "prestij07";
|
||||
$migrate_dedup_users["scottpetrovic"] = "slpetrov";
|
||||
$migrate_dedup_users["zooly76"] = "zooly";
|
||||
$migrate_dedup_users["theoryanimation"] = "davidandrade";
|
||||
$migrate_dedup_users["daninsky"] = "danishit";
|
||||
$migrate_dedup_users["eyesee2013"] = "eyesee";
|
||||
$migrate_dedup_users["megacal"] = "cmcgaugh";
|
||||
$migrate_dedup_users["const"] = "kostas100";
|
||||
$migrate_dedup_users["ngaudenzi"] = "puppetmaster";
|
||||
$migrate_dedup_users["mroguski"] = "kaelthas";
|
||||
$migrate_dedup_users["brdf"] = "origin";
|
||||
$migrate_dedup_users["davis3d"] = "davis";
|
||||
$migrate_dedup_users["rldigital"] = "locatelli";
|
||||
$migrate_dedup_users["tomforsythe"] = "gallifrey77203";
|
||||
$migrate_dedup_users["gbrnk"] = "benoe";
|
||||
$migrate_dedup_users["arekkasprzyk"] = "kasperski";
|
||||
$migrate_dedup_users["imbusy1"] = "imbusy";
|
||||
$migrate_dedup_users["mfoxdoggg"] = "mfoxdogg";
|
||||
|
||||
$migrate_dedup_users["knusk"] = "kanutus";
|
||||
$migrate_dedup_users["tomekk"] = "anders211";
|
||||
$migrate_dedup_users["kitsueb"] = "kitsu_eb";
|
||||
$migrate_dedup_users["slugzzz"] = "tsquar3d";
|
||||
$migrate_dedup_users["moore500"] = "mmoore500";
|
||||
$migrate_dedup_users["verumbra"] = "sebastian0";
|
||||
$migrate_dedup_users["blenderbug"] = "nikola";
|
||||
|
||||
$migrate_dedup_users["adailtoncomp"] = "adailton";
|
||||
$migrate_dedup_users["mchs3d"] = "abtrumpet";
|
||||
|
||||
// disabled users who have tasks
|
||||
$migrate_dedup_users["sjoerd"] = "sjoerddevries";
|
||||
$migrate_dedup_users["matali"] = "mat_ali";
|
||||
$migrate_dedup_users["voicelesscushio"] = "None";
|
||||
$migrate_dedup_users["bigben0328"] = "None";
|
||||
$migrate_dedup_users["santamouse"] = "None";
|
||||
$migrate_dedup_users["andreanckaert"] = "None";
|
||||
$migrate_dedup_users["yesmydear"] = "None";
|
||||
$migrate_dedup_users["spacetug"] = "None";
|
||||
$migrate_dedup_users["omegafold"] = "None";
|
||||
|
||||
// testing
|
||||
$migrate_dedup_users["blendix_rename_test_a"] = "blendix";
|
||||
$migrate_dedup_users["blendix_rename_test_b"] = "blendix";
|
||||
|
Before Width: | Height: | Size: 9.7 KiB After Width: | Height: | Size: 9.8 KiB |
Before Width: | Height: | Size: 6.4 KiB After Width: | Height: | Size: 11 KiB |
Before Width: | Height: | Size: 16 KiB After Width: | Height: | Size: 13 KiB |
Before Width: | Height: | Size: 5.0 KiB After Width: | Height: | Size: 5.4 KiB |
@@ -9,10 +9,10 @@ return array(
|
||||
'names' => array(
|
||||
'conpherence.pkg.css' => '0e3cf785',
|
||||
'conpherence.pkg.js' => '020aebcf',
|
||||
'core.pkg.css' => 'ba768cdb',
|
||||
'core.pkg.js' => '845355f4',
|
||||
'core.pkg.css' => 'f784f26b',
|
||||
'core.pkg.js' => '74ad315f',
|
||||
'dark-console.pkg.js' => '187792c2',
|
||||
'differential.pkg.css' => '5c459f92',
|
||||
'differential.pkg.css' => '32879ab6',
|
||||
'differential.pkg.js' => '218fda21',
|
||||
'diffusion.pkg.css' => '42c75c37',
|
||||
'diffusion.pkg.js' => 'a98c0bf7',
|
||||
@@ -38,9 +38,9 @@ return array(
|
||||
'rsrc/css/aphront/typeahead.css' => '8779483d',
|
||||
'rsrc/css/application/almanac/almanac.css' => '2e050f4f',
|
||||
'rsrc/css/application/auth/auth.css' => 'c2f23d74',
|
||||
'rsrc/css/application/base/main-menu-view.css' => 'bcec20f0',
|
||||
'rsrc/css/application/base/main-menu-view.css' => 'eacf7e46',
|
||||
'rsrc/css/application/base/notification-menu.css' => '4df1ee30',
|
||||
'rsrc/css/application/base/phui-theme.css' => '35883b37',
|
||||
'rsrc/css/application/base/phui-theme.css' => '63311e09',
|
||||
'rsrc/css/application/base/standard-page-view.css' => 'a374f94c',
|
||||
'rsrc/css/application/chatlog/chatlog.css' => 'abdc76ee',
|
||||
'rsrc/css/application/conduit/conduit-api.css' => 'ce2cfc41',
|
||||
@@ -67,7 +67,7 @@ return array(
|
||||
'rsrc/css/application/differential/core.css' => '7300a73e',
|
||||
'rsrc/css/application/differential/phui-inline-comment.css' => '9863a85e',
|
||||
'rsrc/css/application/differential/revision-comment.css' => '7dbc8d1d',
|
||||
'rsrc/css/application/differential/revision-history.css' => '8aa3eac5',
|
||||
'rsrc/css/application/differential/revision-history.css' => '04edcc29',
|
||||
'rsrc/css/application/differential/revision-list.css' => '93d2df7d',
|
||||
'rsrc/css/application/differential/table-of-contents.css' => 'bba788b9',
|
||||
'rsrc/css/application/diffusion/diffusion-icons.css' => '23b31a1b',
|
||||
@@ -137,7 +137,7 @@ return array(
|
||||
'rsrc/css/phui/object-item/phui-oi-simple-ui.css' => '6a30fa46',
|
||||
'rsrc/css/phui/phui-action-list.css' => '1b0085b2',
|
||||
'rsrc/css/phui/phui-action-panel.css' => '6c386cbf',
|
||||
'rsrc/css/phui/phui-badge.css' => '666e25ad',
|
||||
'rsrc/css/phui/phui-badge.css' => '96576409',
|
||||
'rsrc/css/phui/phui-basic-nav-view.css' => '56ebd66d',
|
||||
'rsrc/css/phui/phui-big-info-view.css' => '362ad37b',
|
||||
'rsrc/css/phui/phui-box.css' => '5ed3b8cb',
|
||||
@@ -147,14 +147,14 @@ return array(
|
||||
'rsrc/css/phui/phui-comment-form.css' => '68a2d99a',
|
||||
'rsrc/css/phui/phui-comment-panel.css' => 'ec4e31c0',
|
||||
'rsrc/css/phui/phui-crumbs-view.css' => '614f43cf',
|
||||
'rsrc/css/phui/phui-curtain-object-ref-view.css' => '12404744',
|
||||
'rsrc/css/phui/phui-curtain-object-ref-view.css' => 'b43b7307',
|
||||
'rsrc/css/phui/phui-curtain-view.css' => '68c5efb6',
|
||||
'rsrc/css/phui/phui-document-pro.css' => 'b9613a10',
|
||||
'rsrc/css/phui/phui-document-summary.css' => 'b068eed1',
|
||||
'rsrc/css/phui/phui-document.css' => '52b748a5',
|
||||
'rsrc/css/phui/phui-feed-story.css' => 'a0c05029',
|
||||
'rsrc/css/phui/phui-fontkit.css' => '1ec937e5',
|
||||
'rsrc/css/phui/phui-form-view.css' => '01b796c0',
|
||||
'rsrc/css/phui/phui-form-view.css' => 'a8e0a1ab',
|
||||
'rsrc/css/phui/phui-form.css' => '1f177cb7',
|
||||
'rsrc/css/phui/phui-formation-view.css' => 'd2dec8ed',
|
||||
'rsrc/css/phui/phui-head-thing.css' => 'd7f293df',
|
||||
@@ -187,6 +187,16 @@ return array(
|
||||
'rsrc/css/sprite-login.css' => '18b368a6',
|
||||
'rsrc/css/sprite-tokens.css' => 'f1896dc5',
|
||||
'rsrc/css/syntax/syntax-default.css' => '055fc231',
|
||||
'rsrc/custom/css/phabricator-welcome-page.css' => 'a641fcc9',
|
||||
'rsrc/custom/image/badges/badge_devfund_bronze.png' => '0f98ccf2',
|
||||
'rsrc/custom/image/badges/badge_devfund_diamond.png' => '196d8206',
|
||||
'rsrc/custom/image/badges/badge_devfund_gold.png' => 'd03e1722',
|
||||
'rsrc/custom/image/badges/badge_devfund_platinum.png' => '3e517840',
|
||||
'rsrc/custom/image/badges/badge_devfund_silver.png' => '73594dee',
|
||||
'rsrc/custom/image/badges/badge_devfund_titanium.png' => 'e30aa898',
|
||||
'rsrc/custom/image/badges/badge_sprite_fright.png' => '6f4b20e6',
|
||||
'rsrc/custom/image/badges/badge_studio.png' => 'ffbdcabb',
|
||||
'rsrc/custom/image/blender_logo.png' => '86dc8498',
|
||||
'rsrc/externals/d3/d3.min.js' => '9d068042',
|
||||
'rsrc/externals/font/fontawesome/fontawesome-webfont.eot' => '23f8c698',
|
||||
'rsrc/externals/font/fontawesome/fontawesome-webfont.ttf' => '70983df0',
|
||||
@@ -272,7 +282,7 @@ return array(
|
||||
'rsrc/externals/javelin/lib/control/typeahead/source/TypeaheadPreloadedSource.js' => '5a79f6c3',
|
||||
'rsrc/externals/javelin/lib/control/typeahead/source/TypeaheadSource.js' => '8badee71',
|
||||
'rsrc/externals/javelin/lib/control/typeahead/source/TypeaheadStaticSource.js' => '80bff3af',
|
||||
'rsrc/favicons/favicon-16x16.png' => '4c51a03a',
|
||||
'rsrc/favicons/favicon-16x16.png' => 'b1399751',
|
||||
'rsrc/favicons/mask-icon.svg' => 'db699fe1',
|
||||
'rsrc/image/BFCFDA.png' => '74b5c88b',
|
||||
'rsrc/image/actions/edit.png' => 'fd987dff',
|
||||
@@ -490,7 +500,7 @@ return array(
|
||||
'rsrc/js/core/behavior-more.js' => '506aa3f4',
|
||||
'rsrc/js/core/behavior-object-selector.js' => '98ef467f',
|
||||
'rsrc/js/core/behavior-oncopy.js' => 'da8f5259',
|
||||
'rsrc/js/core/behavior-phabricator-remarkup-assist.js' => '54262396',
|
||||
'rsrc/js/core/behavior-phabricator-remarkup-assist.js' => '99e30c81',
|
||||
'rsrc/js/core/behavior-read-only-warning.js' => 'b9109f8f',
|
||||
'rsrc/js/core/behavior-redirect.js' => '407ee861',
|
||||
'rsrc/js/core/behavior-refresh-csrf.js' => '46116c01',
|
||||
@@ -564,7 +574,7 @@ return array(
|
||||
'differential-core-view-css' => '7300a73e',
|
||||
'differential-revision-add-comment-css' => '7e5900d9',
|
||||
'differential-revision-comment-css' => '7dbc8d1d',
|
||||
'differential-revision-history-css' => '8aa3eac5',
|
||||
'differential-revision-history-css' => '04edcc29',
|
||||
'differential-revision-list-css' => '93d2df7d',
|
||||
'differential-table-of-contents-css' => 'bba788b9',
|
||||
'diffusion-css' => 'b54c77b0',
|
||||
@@ -650,7 +660,7 @@ return array(
|
||||
'javelin-behavior-phabricator-notification-example' => '29819b75',
|
||||
'javelin-behavior-phabricator-object-selector' => '98ef467f',
|
||||
'javelin-behavior-phabricator-oncopy' => 'da8f5259',
|
||||
'javelin-behavior-phabricator-remarkup-assist' => '54262396',
|
||||
'javelin-behavior-phabricator-remarkup-assist' => '99e30c81',
|
||||
'javelin-behavior-phabricator-reveal-content' => 'b105a3a6',
|
||||
'javelin-behavior-phabricator-search-typeahead' => '1cb7d027',
|
||||
'javelin-behavior-phabricator-show-older-transactions' => '8b5c7d65',
|
||||
@@ -790,7 +800,7 @@ return array(
|
||||
'phabricator-flag-css' => '2b77be8d',
|
||||
'phabricator-keyboard-shortcut' => '1a844c06',
|
||||
'phabricator-keyboard-shortcut-manager' => '81debc48',
|
||||
'phabricator-main-menu-view' => 'bcec20f0',
|
||||
'phabricator-main-menu-view' => 'eacf7e46',
|
||||
'phabricator-nav-view-css' => '423f92cc',
|
||||
'phabricator-notification' => 'a9b91e3f',
|
||||
'phabricator-notification-css' => '30240bd2',
|
||||
@@ -808,6 +818,7 @@ return array(
|
||||
'phabricator-title' => '43bc9360',
|
||||
'phabricator-tooltip' => '83754533',
|
||||
'phabricator-ui-example-css' => 'b4795059',
|
||||
'phabricator-welcome-page' => 'a641fcc9',
|
||||
'phabricator-zindex-css' => 'ac3bfcd4',
|
||||
'phame-css' => 'bb442327',
|
||||
'pholio-css' => '88ef5ef1',
|
||||
@@ -820,7 +831,7 @@ return array(
|
||||
'phrequent-css' => 'bd79cc67',
|
||||
'phriction-document-css' => '03380da0',
|
||||
'phui-action-panel-css' => '6c386cbf',
|
||||
'phui-badge-view-css' => '666e25ad',
|
||||
'phui-badge-view-css' => '96576409',
|
||||
'phui-basic-nav-view-css' => '56ebd66d',
|
||||
'phui-big-info-view-css' => '362ad37b',
|
||||
'phui-box-css' => '5ed3b8cb',
|
||||
@@ -837,7 +848,7 @@ return array(
|
||||
'phui-comment-form-css' => '68a2d99a',
|
||||
'phui-comment-panel-css' => 'ec4e31c0',
|
||||
'phui-crumbs-view-css' => '614f43cf',
|
||||
'phui-curtain-object-ref-view-css' => '12404744',
|
||||
'phui-curtain-object-ref-view-css' => 'b43b7307',
|
||||
'phui-curtain-view-css' => '68c5efb6',
|
||||
'phui-document-summary-view-css' => 'b068eed1',
|
||||
'phui-document-view-css' => '52b748a5',
|
||||
@@ -846,7 +857,7 @@ return array(
|
||||
'phui-font-icon-base-css' => '303c9b87',
|
||||
'phui-fontkit-css' => '1ec937e5',
|
||||
'phui-form-css' => '1f177cb7',
|
||||
'phui-form-view-css' => '01b796c0',
|
||||
'phui-form-view-css' => 'a8e0a1ab',
|
||||
'phui-formation-view-css' => 'd2dec8ed',
|
||||
'phui-head-thing-view-css' => 'd7f293df',
|
||||
'phui-header-view-css' => '36c86a58',
|
||||
@@ -877,7 +888,7 @@ return array(
|
||||
'phui-spacing-css' => 'b05cadc3',
|
||||
'phui-status-list-view-css' => 'e5ff8be0',
|
||||
'phui-tag-view-css' => '8519160a',
|
||||
'phui-theme-css' => '35883b37',
|
||||
'phui-theme-css' => '63311e09',
|
||||
'phui-timeline-view-css' => '2d32d7a9',
|
||||
'phui-two-column-view-css' => 'f96d319f',
|
||||
'phui-workboard-color-css' => 'e86de308',
|
||||
@@ -1411,17 +1422,6 @@ return array(
|
||||
'541f81c3' => array(
|
||||
'javelin-install',
|
||||
),
|
||||
54262396 => array(
|
||||
'javelin-behavior',
|
||||
'javelin-stratcom',
|
||||
'javelin-dom',
|
||||
'phabricator-phtize',
|
||||
'phabricator-textareautils',
|
||||
'javelin-workflow',
|
||||
'javelin-vector',
|
||||
'phuix-autocomplete',
|
||||
'javelin-mask',
|
||||
),
|
||||
'548567f6' => array(
|
||||
'syntax-default-css',
|
||||
),
|
||||
@@ -1809,6 +1809,17 @@ return array(
|
||||
'javelin-request',
|
||||
'javelin-router',
|
||||
),
|
||||
'99e30c81' => array(
|
||||
'javelin-behavior',
|
||||
'javelin-stratcom',
|
||||
'javelin-dom',
|
||||
'phabricator-phtize',
|
||||
'phabricator-textareautils',
|
||||
'javelin-workflow',
|
||||
'javelin-vector',
|
||||
'phuix-autocomplete',
|
||||
'javelin-mask',
|
||||
),
|
||||
'9aae2b66' => array(
|
||||
'javelin-install',
|
||||
'javelin-util',
|
||||
@@ -2034,9 +2045,6 @@ return array(
|
||||
'phabricator-drag-and-drop-file-upload',
|
||||
'javelin-workboard-board',
|
||||
),
|
||||
'bcec20f0' => array(
|
||||
'phui-theme-css',
|
||||
),
|
||||
'c03f2fb4' => array(
|
||||
'javelin-install',
|
||||
),
|
||||
@@ -2164,6 +2172,9 @@ return array(
|
||||
'javelin-install',
|
||||
'javelin-event',
|
||||
),
|
||||
'eacf7e46' => array(
|
||||
'phui-theme-css',
|
||||
),
|
||||
'ebe83a6b' => array(
|
||||
'javelin-install',
|
||||
),
|
||||
|
@@ -7,6 +7,7 @@ $status_map = array(
|
||||
3 => 'invalid',
|
||||
4 => 'duplicate',
|
||||
5 => 'spite',
|
||||
123450 => 'archived',
|
||||
);
|
||||
|
||||
$conn_w = id(new ManiphestTask())->establishConnection('w');
|
||||
|
172
scripts/auth_provider/auth_provider.php
Executable file
@@ -0,0 +1,172 @@
|
||||
#!/usr/local/bin/php
|
||||
<?php
|
||||
#
|
||||
# ***** BEGIN GPL LICENSE BLOCK *****
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
# as published by the Free Software Foundation; either version 2
|
||||
# of the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software Foundation,
|
||||
# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
#
|
||||
# The Original Code is Copyright (C) 2019, Blender Foundation
|
||||
# All rights reserved.
|
||||
#
|
||||
# Contributor(s): Sergey Sharybin.
|
||||
#
|
||||
# ***** END GPL LICENSE BLOCK *****
|
||||
#
|
||||
# This scripts implements external AuthBasicProvider which can be used
|
||||
# to authentificate users using Phabricator's database.
|
||||
#
|
||||
# Example configuration:
|
||||
#
|
||||
# .htaccess file:
|
||||
#
|
||||
# AuthType Basic
|
||||
# AuthName "Please Enter Password"
|
||||
# AuthBasicProvider external
|
||||
# AuthExternal phabricator
|
||||
# Require valid-user
|
||||
#
|
||||
# It is also required to have the following provider registered in the
|
||||
# configuration. There are two ways to do it:
|
||||
#
|
||||
# 1. Separate conf file in /etc/apache2/conf-enabled
|
||||
# Create a file (say, authz_external_phabricator.conf) with the following
|
||||
# content:
|
||||
#
|
||||
# DefineExternalAuth phabricator pipe /path/to/auth_provider.php
|
||||
#
|
||||
# This method allows to use provider in any VHOST.
|
||||
#
|
||||
# Downside: from local tests .htaccess file picks the provider nicely,
|
||||
# but attempts to specifu the provider in virtual host configuration
|
||||
# resulted in issues (seems to be different initialization order between
|
||||
# global config in those files and virtual hosts).
|
||||
#
|
||||
# 2. Define provider in the virtual host definition:
|
||||
#
|
||||
# <IfModule mod_authnz_external.c>
|
||||
# AddExternalAuth phabricator /path/to/auth_provider.php
|
||||
# SetExternalAuthMethod phabricator pipe
|
||||
# </IfModule>
|
||||
#
|
||||
# This method allowed to use this auth provider for SVN DAV.
|
||||
|
||||
$IS_DEBUG = false;
|
||||
$PHABRICATOR_ROOT = dirname(dirname(dirname(__FILE__)));
|
||||
require_once $PHABRICATOR_ROOT.'/scripts/__init_script__.php';
|
||||
|
||||
function initLogging() {
|
||||
global $IS_DEBUG;
|
||||
global $argv;
|
||||
for ($i = 1; $i < count($argv); ++$i) {
|
||||
if ($argv[$i] == '--debug') {
|
||||
$IS_DEBUG = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function debugLog(string $text) {
|
||||
global $IS_DEBUG;
|
||||
if (!$IS_DEBUG) {
|
||||
return;
|
||||
}
|
||||
print("${text}\n");
|
||||
}
|
||||
|
||||
function removeSingleTrailingNewline(string $string) {
|
||||
if ($string === '') {
|
||||
return $string;
|
||||
}
|
||||
$length = strlen($string);
|
||||
if ($string[$length - 1] == "\n") {
|
||||
return substr($string, 0, -1);
|
||||
}
|
||||
return $string;
|
||||
}
|
||||
|
||||
class AuthRequest {
|
||||
public $user_name;
|
||||
public $password;
|
||||
|
||||
static function fromStdin() {
|
||||
$auth_request = new AuthRequest();
|
||||
$stdin = fopen('php://stdin', 'r');
|
||||
$auth_request->user_name = removeSingleTrailingNewline(fgets($stdin));
|
||||
$auth_request->password = removeSingleTrailingNewline(fgets($stdin));
|
||||
return $auth_request;
|
||||
}
|
||||
};
|
||||
|
||||
function getUserForAuthRequest(AuthRequest $auth_request) {
|
||||
if ($auth_request->user_name === '') {
|
||||
return null;
|
||||
}
|
||||
|
||||
$username_or_email = $auth_request->user_name;
|
||||
|
||||
$user = id(new PhabricatorUser())->loadOneWhere(
|
||||
'username = %s',
|
||||
$username_or_email);
|
||||
|
||||
if (!$user) {
|
||||
$user = PhabricatorUser::loadOneWithEmailAddress(
|
||||
$username_or_email);
|
||||
}
|
||||
|
||||
return $user;
|
||||
}
|
||||
|
||||
function createContentSourceForAuth() {
|
||||
return PhabricatorContentSource::newForSource(
|
||||
PhabricatorUnitTestContentSource::SOURCECONST);
|
||||
}
|
||||
|
||||
function isValidAuth(AuthRequest $auth_request) {
|
||||
debugLog("Begin authentification check for user '$auth_request->user_name'");
|
||||
$user = getUserForAuthRequest($auth_request);
|
||||
if (!$user) {
|
||||
debugLog("No PhabricatorUser() object found for requested user.");
|
||||
return false;
|
||||
}
|
||||
|
||||
$content_source = createContentSourceForAuth();
|
||||
$envelope = new PhutilOpaqueEnvelope($auth_request->password);
|
||||
|
||||
$engine = id(new PhabricatorAuthPasswordEngine())
|
||||
->setViewer($user)
|
||||
->setContentSource($content_source)
|
||||
->setPasswordType(PhabricatorAuthPassword::PASSWORD_TYPE_ACCOUNT)
|
||||
->setObject($user);
|
||||
|
||||
if (!$engine->isValidPassword($envelope)) {
|
||||
debugLog('Engine reported invalid password.');
|
||||
return false;
|
||||
}
|
||||
|
||||
debugLog('Authentirfication passed.');
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
function main() {
|
||||
initLogging();
|
||||
$auth_request = AuthRequest::fromStdin();
|
||||
if (!isValidAuth($auth_request)) {
|
||||
exit(1);
|
||||
}
|
||||
exit(0);
|
||||
}
|
||||
|
||||
main();
|
||||
?>
|
576
scripts/bake/bake.php
Normal file
@@ -0,0 +1,576 @@
|
||||
#!/usr/local/bin/php
|
||||
<?php
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
// Bootstrap.
|
||||
|
||||
$PHABRICATOR_ROOT = dirname(dirname(dirname(__FILE__)));
|
||||
require_once $PHABRICATOR_ROOT.'/scripts/__init_script__.php';
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
// Command line.
|
||||
|
||||
$argc = count($argv);
|
||||
if ($argc < 3 || $argc > 4) {
|
||||
print("Usage: $argv[0] <conduit_token_file> <output_directory> [timestamp]\n");
|
||||
die;
|
||||
}
|
||||
|
||||
$CONDUIT_TOKEN_FILE = $argv[1];
|
||||
$OUTPUT_DIR = $argv[2];
|
||||
$TIMESTAMP = ($argc == 4) ? (int)$argv[3] : 0;
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
// Global configuration.
|
||||
|
||||
$HOST = 'phabricator.local';
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
// Utilities.
|
||||
|
||||
// Create an instance of the AphrontApplicationConfiguration configured with all
|
||||
// invariant settings (settings which do not change between handlers of different
|
||||
// revisions).
|
||||
function CreateApplicationConfiguration() {
|
||||
global $HOST;
|
||||
|
||||
$application_configuration = new AphrontApplicationConfiguration();
|
||||
$application_configuration->setHost($HOST);
|
||||
return $application_configuration;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
// Global state.
|
||||
|
||||
$site = id(new PhabricatorPlatformSite());
|
||||
|
||||
$viewer = PhabricatorUser::getOmnipotentUser();
|
||||
|
||||
$application_configuration = CreateApplicationConfiguration();
|
||||
|
||||
$differential_application = id(new PhabricatorDifferentialApplication());
|
||||
$revision_controller = id(new DifferentialRevisionViewController())
|
||||
->setCurrentApplication($differential_application);
|
||||
|
||||
$maniphest_application = id(new PhabricatorManiphestApplication());
|
||||
$maniphest_controller = id(new ManiphestTaskDetailController())
|
||||
->setCurrentApplication($maniphest_application);
|
||||
|
||||
$differential_routing_map = id(new AphrontRoutingMap())
|
||||
->setSite($site)
|
||||
->setApplication($differential_application)
|
||||
->setRoutes($differential_application->getRoutes());
|
||||
|
||||
$maniphest_routing_map = id(new AphrontRoutingMap())
|
||||
->setSite($site)
|
||||
->setApplication($maniphest_application)
|
||||
->setRoutes($maniphest_application->getRoutes());
|
||||
|
||||
$conduit = id(new ConduitClient('https://developer.blender.org/api/'))
|
||||
->setConduitToken(trim(file_get_contents($CONDUIT_TOKEN_FILE)));
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
// Baking utilities.
|
||||
|
||||
function EnsureDirectoryOrDie($dir) {
|
||||
if (!is_dir($dir)) {
|
||||
if (!mkdir($dir, 0777, true)) {
|
||||
print("Error creating output durectory $dir\n");
|
||||
die;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function RenderElement($element) {
|
||||
if (is_array($element)) {
|
||||
$html = '';
|
||||
foreach ($element as $child) {
|
||||
$html .= RenderElement($child);
|
||||
}
|
||||
return $html;
|
||||
}
|
||||
|
||||
return $element->render();
|
||||
}
|
||||
|
||||
function RenderResponseToHTML($response) {
|
||||
$html = '';
|
||||
|
||||
$crumbs = $response->getCrumbs();
|
||||
if ($crumbs) {
|
||||
$html .= $crumbs->render();
|
||||
}
|
||||
|
||||
foreach ($response->renderChildren() as $child) {
|
||||
$html .= RenderElement($child);
|
||||
}
|
||||
|
||||
return $html;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
// Revision baking.
|
||||
|
||||
class RevisionInfo {
|
||||
public $title = '';
|
||||
public $page_title = '';
|
||||
|
||||
public $last_diff_id = 0;
|
||||
|
||||
public $hash = '';
|
||||
|
||||
public static function ReadFromFile($file_name) {
|
||||
$info = new RevisionInfo();
|
||||
|
||||
if (!file_exists($file_name)) {
|
||||
return $info;
|
||||
}
|
||||
|
||||
$json = json_decode(file_get_contents($file_name));
|
||||
foreach ($json as $key => $value) {
|
||||
$info->{$key} = $value;
|
||||
}
|
||||
|
||||
return $info;
|
||||
}
|
||||
|
||||
public function SaveToFile($file_name) {
|
||||
$json_str = json_encode(get_object_vars($this));
|
||||
file_put_contents($file_name, $json_str);
|
||||
}
|
||||
};
|
||||
|
||||
function GetRevisionOutputDirectory($revision) {
|
||||
global $OUTPUT_DIR;
|
||||
|
||||
$id = $revision->getID();
|
||||
|
||||
return PathJoin(array($OUTPUT_DIR, 'differential', SubpathFromId($id)));
|
||||
}
|
||||
|
||||
function EnsureRevisionOutputDirectory($revision) {
|
||||
$dir = GetRevisionOutputDirectory($revision);
|
||||
|
||||
EnsureDirectoryOrDie($dir);
|
||||
EnsureDirectoryOrDie(PathJoin(array($dir, 'raw_diff')));
|
||||
|
||||
return $dir;
|
||||
}
|
||||
|
||||
function GetRevisionInfoFilename($revision) {
|
||||
$revision_dir = GetRevisionOutputDirectory($revision);
|
||||
return PathJoin(array($revision_dir, 'info.json'));
|
||||
}
|
||||
|
||||
function GetRevisionHTMLFilename($revision, $diff_id) {
|
||||
$revision_id = $revision->getID();
|
||||
$revision_dir = GetRevisionOutputDirectory($revision);
|
||||
|
||||
$file_name = "D{$revision_id}.id{$diff_id}.html";
|
||||
|
||||
return PathJoin(array($revision_dir, $file_name));
|
||||
}
|
||||
|
||||
function GetRevisionRawDiffFilename($revision, $diff_id) {
|
||||
$revision_id = $revision->getID();
|
||||
$revision_dir = GetRevisionOutputDirectory($revision);
|
||||
|
||||
$file_name = "D{$revision_id}.id{$diff_id}.diff";
|
||||
|
||||
return PathJoin(array($revision_dir, 'raw_diff', $file_name));
|
||||
}
|
||||
|
||||
function RenderDifferentialToResponse($revision, $diff_id) {
|
||||
global $application_configuration;
|
||||
global $revision_controller;
|
||||
global $differential_routing_map;
|
||||
global $viewer;
|
||||
|
||||
$revision_id = $revision->getID();
|
||||
|
||||
$path = '/D' . $revision_id;
|
||||
|
||||
$route_result = $differential_routing_map->routePath($path);
|
||||
$uri_data = $route_result->getURIData();
|
||||
|
||||
$application_configuration->setPath($path);
|
||||
|
||||
$request_data = array(
|
||||
'id' => $diff_id,
|
||||
);
|
||||
|
||||
$request = $application_configuration->buildRequest()
|
||||
->setUser($viewer)
|
||||
->setRequestData($request_data)
|
||||
->setURIMap($uri_data);
|
||||
|
||||
$response = id($revision_controller)
|
||||
->setRequest($request)
|
||||
->handleRequest($request);
|
||||
|
||||
return $response;
|
||||
}
|
||||
|
||||
function StoreRawDiff($revision, $diff_id) {
|
||||
global $viewer;
|
||||
global $conduit;
|
||||
|
||||
$diff = id(new DifferentialDiffQuery())
|
||||
->setViewer($viewer)
|
||||
->withIDs(array($diff_id))
|
||||
->needChangesets(true)
|
||||
->executeOne();
|
||||
|
||||
$raw_changes = $diff->buildChangesList();
|
||||
|
||||
$changes = array();
|
||||
foreach ($raw_changes as $changedict) {
|
||||
$changes[] = ArcanistDiffChange::newFromDictionary($changedict);
|
||||
}
|
||||
|
||||
$bundle = ArcanistBundle::newFromChanges($changes);
|
||||
$bundle->setConduit($conduit);
|
||||
$raw_diff = $bundle->toGitPatch();
|
||||
|
||||
$output_file = GetRevisionRawDiffFilename($revision, $diff_id);
|
||||
file_put_contents($output_file, $raw_diff);
|
||||
}
|
||||
|
||||
function GetRevisionHash($revision) {
|
||||
global $viewer;
|
||||
|
||||
$xaction = id(new DifferentialTransactionQuery())
|
||||
->setViewer($viewer)
|
||||
->withObjectPHIDs(array($revision->getPHID()))
|
||||
->setOrder('updated')
|
||||
->setLimit(1)
|
||||
->executeOne();
|
||||
|
||||
$digest = '';
|
||||
|
||||
$digest .= $revision->getDateModified();
|
||||
|
||||
if ($xaction) {
|
||||
$digest .= '_' . $xaction->getPHID();
|
||||
$digest .= '_' . $xaction->getDateModified();
|
||||
}
|
||||
|
||||
return $digest;
|
||||
}
|
||||
|
||||
function NeedBakeRevision($info, $revision, $diff_id) {
|
||||
if (!file_exists(GetRevisionHTMLFilename($revision, $diff_id))) {
|
||||
return true;
|
||||
}
|
||||
if (!file_exists(GetRevisionRawDiffFilename($revision, $diff_id))) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if ($info->last_diff_id < $diff_id) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if ($revision->getTitle() != $info->title) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (GetRevisionHash($revision) != $info->hash) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
function BakeRevision($revision, $diff_id) {
|
||||
$revision_id = $revision->getID();
|
||||
|
||||
printf('Baking D' . $revision_id . '?id=' . $diff_id . ' ...' . "\n");
|
||||
|
||||
$info_file_name = GetRevisionInfoFilename($revision);
|
||||
|
||||
$info = RevisionInfo::ReadFromFile($info_file_name);
|
||||
|
||||
if (!NeedBakeRevision($info, $revision, $diff_id)) {
|
||||
print(' ... ignoring: up to date' . "\n");
|
||||
return;
|
||||
}
|
||||
|
||||
$response = RenderDifferentialToResponse($revision, $diff_id);
|
||||
|
||||
$html = RenderResponseToHTML($response);
|
||||
$html_file_name = GetRevisionHTMLFIlename($revision, $diff_id);
|
||||
file_put_contents($html_file_name, $html);
|
||||
|
||||
StoreRawDiff($revision, $diff_id);
|
||||
|
||||
$info->title = $revision->getTitle();
|
||||
$info->page_title = $response->getTitle();
|
||||
$info->hash = GetRevisionHash($revision);
|
||||
$info->last_diff_id = max($info->last_diff_id, $diff_id);
|
||||
|
||||
$info->SaveToFile($info_file_name);
|
||||
}
|
||||
|
||||
function GetAllRevisions() {
|
||||
global $viewer;
|
||||
|
||||
return id(new DifferentialRevisionQuery())
|
||||
->setViewer($viewer)
|
||||
->needDiffIDs(true)
|
||||
->setOrder('oldest')
|
||||
->execute();
|
||||
}
|
||||
|
||||
|
||||
function GetModifiedRevisionsSince($timestamp) {
|
||||
if (!$timestamp) {
|
||||
return GetAllRevisions();
|
||||
}
|
||||
|
||||
global $viewer;
|
||||
|
||||
$xactions = id(new DifferentialTransactionQuery())
|
||||
->setViewer($viewer)
|
||||
->setOrder('oldest')
|
||||
->withUpdatedEpochAfter($timestamp)
|
||||
->execute();
|
||||
|
||||
$revision_ids_set = array();
|
||||
|
||||
foreach ($xactions as $xaction_id => $xaction) {
|
||||
$revision = $xaction->getObject();
|
||||
$revision_id = $revision->getID();
|
||||
|
||||
$revision_ids_set[$revision_id] = 1;
|
||||
}
|
||||
|
||||
$updated_revision_ids = array_keys($revision_ids_set);
|
||||
|
||||
return id(new DifferentialRevisionQuery())
|
||||
->setViewer($viewer)
|
||||
->needDiffIDs(true)
|
||||
->setOrder('oldest')
|
||||
->withIDs($updated_revision_ids)
|
||||
->execute();
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
// Task baking.
|
||||
|
||||
class TaskInfo {
|
||||
public $title = '';
|
||||
public $page_title = '';
|
||||
|
||||
public $hash = '';
|
||||
|
||||
public static function ReadFromFile($file_name) {
|
||||
$info = new TaskInfo();
|
||||
|
||||
if (!file_exists($file_name)) {
|
||||
return $info;
|
||||
}
|
||||
|
||||
$json = json_decode(file_get_contents($file_name));
|
||||
foreach ($json as $key => $value) {
|
||||
$info->{$key} = $value;
|
||||
}
|
||||
|
||||
return $info;
|
||||
}
|
||||
|
||||
public function SaveToFile($file_name) {
|
||||
$json_str = json_encode(get_object_vars($this));
|
||||
file_put_contents($file_name, $json_str);
|
||||
}
|
||||
};
|
||||
|
||||
function GetTaskOutputDirectory($task) {
|
||||
global $OUTPUT_DIR;
|
||||
|
||||
$id = $task->getID();
|
||||
|
||||
return PathJoin(array($OUTPUT_DIR, 'maniphest', SubpathFromId($id)));
|
||||
}
|
||||
|
||||
function EnsureTaskOutputDirectory($task) {
|
||||
$dir = GetTaskOutputDirectory($task);
|
||||
|
||||
EnsureDirectoryOrDie($dir);
|
||||
|
||||
return $dir;
|
||||
}
|
||||
|
||||
function GetTaskInfoFilename($task) {
|
||||
$task_dir = GetTaskOutputDirectory($task);
|
||||
return PathJoin(array($task_dir, 'info.json'));
|
||||
}
|
||||
|
||||
function GetTaskHTMLFilename($task) {
|
||||
$task_id = $task->getID();
|
||||
$task_dir = GetTaskOutputDirectory($task);
|
||||
|
||||
$file_name = "index.html";
|
||||
|
||||
return PathJoin(array($task_dir, $file_name));
|
||||
}
|
||||
|
||||
function RenderTaskToResponse($task) {
|
||||
global $application_configuration;
|
||||
global $maniphest_routing_map;
|
||||
global $viewer;
|
||||
global $maniphest_controller;
|
||||
|
||||
$task_id = $task->getID();
|
||||
|
||||
$path = '/T' . $task_id;
|
||||
|
||||
$route_result = $maniphest_routing_map->routePath($path);
|
||||
$uri_data = $route_result->getURIData();
|
||||
|
||||
$application_configuration->setPath($path);
|
||||
|
||||
$request_data = array(
|
||||
);
|
||||
|
||||
$request = $application_configuration->buildRequest()
|
||||
->setUser($viewer)
|
||||
->setRequestData($request_data)
|
||||
->setURIMap($uri_data);
|
||||
|
||||
$response = id($maniphest_controller)
|
||||
->setRequest($request)
|
||||
->handleRequest($request);
|
||||
|
||||
return $response;
|
||||
}
|
||||
|
||||
function GetTaskHash($task) {
|
||||
global $viewer;
|
||||
|
||||
$xaction = id(new ManiphestTransactionQuery())
|
||||
->setViewer($viewer)
|
||||
->withObjectPHIDs(array($task->getPHID()))
|
||||
->setOrder('updated')
|
||||
->setLimit(1)
|
||||
->executeOne();
|
||||
|
||||
$digest = '';
|
||||
|
||||
$digest .= $task->getDateModified();
|
||||
|
||||
if ($xaction) {
|
||||
$digest .= '_' . $xaction->getPHID();
|
||||
$digest .= '_' . $xaction->getDateModified();
|
||||
}
|
||||
|
||||
return $digest;
|
||||
}
|
||||
|
||||
function NeedBakeTask($info, $task) {
|
||||
if (!file_exists(GetTaskHTMLFilename($task))) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if ($task->getTitle() != $info->title) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (GetTaskHash($task) != $info->hash) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
function BakeTask($task) {
|
||||
$task_id = $task->getID();
|
||||
|
||||
printf('Baking T' . $task_id . ' ...' . "\n");
|
||||
|
||||
$info_file_name = GetTaskInfoFilename($task);
|
||||
|
||||
$info = TaskInfo::ReadFromFile($info_file_name);
|
||||
|
||||
if (!NeedBakeTask($info, $task)) {
|
||||
print(' ... ignoring: up to date' . "\n");
|
||||
return;
|
||||
}
|
||||
|
||||
$response = RenderTaskToResponse($task);
|
||||
|
||||
$html = RenderResponseToHTML($response);
|
||||
|
||||
$html_file_name = GetTaskHTMLFIlename($task);
|
||||
file_put_contents($html_file_name, $html);
|
||||
|
||||
$info->title = $task->getTitle();
|
||||
$info->page_title = $response->getTitle();
|
||||
$info->hash = GetTaskHash($task);
|
||||
|
||||
$info->SaveToFile($info_file_name);
|
||||
}
|
||||
|
||||
function GetAllTasks() {
|
||||
global $viewer;
|
||||
|
||||
return id(new ManiphestTaskQuery())
|
||||
->setViewer($viewer)
|
||||
->setOrder('oldest')
|
||||
->execute();
|
||||
}
|
||||
|
||||
function GetModifiedTasksSinze($timestamp) {
|
||||
if (!$timestamp) {
|
||||
return GetAllTasks();
|
||||
}
|
||||
|
||||
global $viewer;
|
||||
|
||||
$xactions = id(new ManiphestTransactionQuery())
|
||||
->setViewer($viewer)
|
||||
->setOrder('updated')
|
||||
->withUpdatedEpochAfter($timestamp)
|
||||
->execute();
|
||||
|
||||
$task_ids_set = array();
|
||||
|
||||
foreach ($xactions as $xaction_id => $xaction) {
|
||||
$task = $xaction->getObject();
|
||||
$task_id = $task->getID();
|
||||
|
||||
$task_ids_set[$task_id] = 1;
|
||||
}
|
||||
|
||||
$updated_task_ids = array_keys($task_ids_set);
|
||||
|
||||
return id(new ManiphestTaskQuery())
|
||||
->setViewer($viewer)
|
||||
->setOrder('oldest')
|
||||
->withIDs($updated_task_ids)
|
||||
->execute();
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
// Baking main loop.
|
||||
|
||||
print('Querying differential revisions from the database ... ' . "\n");
|
||||
$revisions = GetModifiedRevisionsSince($TIMESTAMP);
|
||||
|
||||
foreach ($revisions as $revision_id => $revision) {
|
||||
EnsureRevisionOutputDirectory($revision);
|
||||
|
||||
foreach ($revision->getDiffIDs() as $diff_id) {
|
||||
BakeRevision($revision, $diff_id);
|
||||
}
|
||||
}
|
||||
|
||||
print("\n");
|
||||
print('Querying maniphest tasks from the database ... ' . "\n");
|
||||
$tasks = GetModifiedTasksSinze($TIMESTAMP);
|
||||
|
||||
foreach ($tasks as $task_id => $task) {
|
||||
EnsureTaskOutputDirectory($task);
|
||||
BakeTask($task);
|
||||
}
|
||||
|
||||
?>
|
49
scripts/bake/get_modified_tasks.php
Normal file
@@ -0,0 +1,49 @@
|
||||
#!/usr/local/bin/php
|
||||
<?php
|
||||
|
||||
$PHABRICATOR_ROOT = dirname(dirname(dirname(__FILE__)));
|
||||
require_once $PHABRICATOR_ROOT.'/scripts/__init_script__.php';
|
||||
|
||||
if (count($argv) != 2) {
|
||||
print("Usage: $argv[0] timestamp\n");
|
||||
die;
|
||||
}
|
||||
|
||||
$TIMESTAMP = $argv[1];
|
||||
|
||||
$viewer = PhabricatorUser::getOmnipotentUser();
|
||||
|
||||
$xactions = id(new ManiphestTransactionQuery())
|
||||
->setViewer($viewer)
|
||||
->setOrder('updated')
|
||||
->withUpdatedEpochAfter($TIMESTAMP)
|
||||
->execute();
|
||||
|
||||
$tasks = array();
|
||||
|
||||
foreach ($xactions as $xaction_id => $xaction) {
|
||||
$task = $xaction->getObject();
|
||||
$task_id = $task->getID();
|
||||
|
||||
$tasks[$task_id] = 1;
|
||||
}
|
||||
|
||||
$task_ids = array_keys($tasks);
|
||||
sort($task_ids);
|
||||
|
||||
$handle = fopen("tasks.json", "w");
|
||||
fwrite($handle, "[\n");
|
||||
|
||||
$is_first = true;
|
||||
foreach ($task_ids as $task_id ) {
|
||||
if (!$is_first) {
|
||||
fwrite($handle, ",\n");
|
||||
}
|
||||
fwrite($handle, " {$task_id}");
|
||||
$is_first = false;
|
||||
}
|
||||
|
||||
fwrite($handle, "\n]\n");
|
||||
fclose($handle);
|
||||
|
||||
?>
|
32
scripts/bake/list_files.php
Normal file
@@ -0,0 +1,32 @@
|
||||
#!/usr/local/bin/php
|
||||
<?php
|
||||
|
||||
$PHABRICATOR_ROOT = dirname(dirname(dirname(__FILE__)));
|
||||
require_once $PHABRICATOR_ROOT.'/scripts/__init_script__.php';
|
||||
|
||||
$viewer = PhabricatorUser::getOmnipotentUser();
|
||||
|
||||
# print("Querying all files...\n");
|
||||
$files = id(new PhabricatorFileQuery())
|
||||
->setViewer($viewer)
|
||||
->setOrder('oldest')
|
||||
->execute();
|
||||
|
||||
# print("Looping over the files\n");
|
||||
print("ids = (\n");
|
||||
foreach ($files as $file_id => $file) {
|
||||
$authorPHID = $file->getAuthorPHID();
|
||||
|
||||
if (!$authorPHID) {
|
||||
$name = $file->getName();
|
||||
if (substr($name, 0, 8) != 'preview-') {
|
||||
$prev_file = $file;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
print($file->getID() . ",\n");
|
||||
}
|
||||
print(")\n");
|
||||
|
||||
?>
|
6
scripts/gitadmin/gitx-ssh
Executable file
@@ -0,0 +1,6 @@
|
||||
#!/usr/local/bin/bash
|
||||
|
||||
set -e
|
||||
set -u
|
||||
|
||||
ssh -i $SSH_KEYFILE $@
|
443
scripts/gitadmin/rebuild_gitadmin.php
Executable file
@@ -0,0 +1,443 @@
|
||||
#!/usr/local/bin/php
|
||||
<?php
|
||||
|
||||
$root = dirname(dirname(dirname(__FILE__)));
|
||||
require_once $root.'/scripts/__init_script__.php';
|
||||
|
||||
function escape_name($name) {
|
||||
return preg_replace('/[^A-Za-z0-9\-]/', '_', $name);
|
||||
}
|
||||
|
||||
function startswith($string, $prefix) {
|
||||
return substr($string, 0, strlen($prefix)) == $prefix;
|
||||
}
|
||||
|
||||
function endswith($string, $suffix) {
|
||||
$suffix_length = strlen($suffix);
|
||||
return substr($string, strlen($string) - $suffix_length,
|
||||
$suffix_length) == $suffix;
|
||||
}
|
||||
|
||||
function write_ini_file($array, $file) {
|
||||
$res = array();
|
||||
foreach ($array as $key => $val) {
|
||||
if (is_array($val)) {
|
||||
$res[] = "[$key]";
|
||||
foreach ($val as $skey => $sval) {
|
||||
$res[] = "$skey = $sval";
|
||||
}
|
||||
$res[] = '';
|
||||
} else {
|
||||
$res[] = "$key = $val";
|
||||
}
|
||||
}
|
||||
file_put_contents($file, implode("\n", $res));
|
||||
}
|
||||
|
||||
function getProjectMembersPHIDs($viewer, $project_phid) {
|
||||
$project = id(new PhabricatorProjectQuery())
|
||||
->setViewer($viewer)
|
||||
->needMembers(true)
|
||||
->withPHIDs(array($project_phid))
|
||||
->executeOne();
|
||||
|
||||
return $project->getMemberPHIDs();
|
||||
}
|
||||
|
||||
// Get user's heys and put them to the configuration
|
||||
function handleSingleUserPHID(
|
||||
$keydir, $viewer, $userPHID, $system_keys, &$used_keys) {
|
||||
$user = id(new PhabricatorPeopleQuery())
|
||||
->setViewer($viewer)
|
||||
->withPHIDs(array($userPHID))
|
||||
->executeOne();
|
||||
if (!$user) {
|
||||
return array();
|
||||
}
|
||||
|
||||
if ($user->getIsDisabled()) {
|
||||
return array();
|
||||
}
|
||||
|
||||
$keys = id(new PhabricatorAuthSSHKey())->loadAllWhere(
|
||||
'objectPHID = %s',
|
||||
$user->getPHID());
|
||||
|
||||
$members = array();
|
||||
foreach ($keys as $key) {
|
||||
$full_key_content =
|
||||
$key->getKeyType().' '.
|
||||
$key->getKeyBody().' '.
|
||||
$key->getKeyComment()."\n";
|
||||
|
||||
if (array_key_exists($full_key_content, $system_keys)) {
|
||||
$members[] = $system_keys[$full_key_content];
|
||||
} else {
|
||||
$escaped_key_name = escape_name($key->getName());
|
||||
$member = 'PHAB_'.$user->getUserName().
|
||||
'_'.$escaped_key_name.
|
||||
'_'.$key->getID();
|
||||
$members[] = $member;
|
||||
if (!array_key_exists($member, $used_keys)) {
|
||||
$used_keys[$member] = true;
|
||||
file_put_contents("$keydir/$member.pub", $full_key_content);
|
||||
}
|
||||
}
|
||||
}
|
||||
return $members;
|
||||
}
|
||||
|
||||
function handleUsersPolicyRule(
|
||||
$keydir, $viewer, $rule, $system_keys, &$used_keys) {
|
||||
$members = array();
|
||||
foreach ($rule['value'] as $userPHID) {
|
||||
$members = array_merge($members,
|
||||
handleSingleUserPHID($keydir, $viewer, $userPHID,
|
||||
$system_keys, $used_keys));
|
||||
}
|
||||
return $members;
|
||||
}
|
||||
|
||||
function handleProjectsPolicyRule(
|
||||
$keydir, $viewer, $rule, $system_keys, &$used_keys) {
|
||||
$members = array();
|
||||
foreach ($rule['value'] as $projectPHID) {
|
||||
$memberPHIDs = getProjectMembersPHIDs($viewer, $projectPHID);
|
||||
foreach ($memberPHIDs as $userPHID) {
|
||||
$members = array_merge($members,
|
||||
handleSingleUserPHID($keydir, $viewer, $userPHID,
|
||||
$system_keys, $used_keys));
|
||||
}
|
||||
}
|
||||
return $members;
|
||||
}
|
||||
|
||||
function handleProjectsAllPolicyRule(
|
||||
$keydir, $viewer, $rule, $system_keys, &$used_keys) {
|
||||
$is_first_project = true;
|
||||
$allowed_members_phids = array();
|
||||
foreach ($rule['value'] as $project_phid) {
|
||||
$memberPHIDs = getProjectMembersPHIDs($viewer, $project_phid);
|
||||
if ($is_first_project) {
|
||||
$allowed_members_phids = $memberPHIDs;
|
||||
$is_first_project = false;
|
||||
} else {
|
||||
$allowed_members_phids = array_intersect(
|
||||
$allowed_members_phids, $memberPHIDs);
|
||||
}
|
||||
}
|
||||
|
||||
$members = array();
|
||||
foreach ($allowed_members_phids as $userPHID) {
|
||||
$members = array_merge($members,
|
||||
handleSingleUserPHID($keydir, $viewer, $userPHID,
|
||||
$system_keys, $used_keys));
|
||||
}
|
||||
return $members;
|
||||
}
|
||||
|
||||
function handleAdministratorsPolicyRule(
|
||||
$keydir, $viewer, $rule, $system_keys, &$used_keys) {
|
||||
$administrators = id(new PhabricatorPeopleQuery())
|
||||
->setViewer($viewer)
|
||||
->withIsAdmin(true)
|
||||
->execute();
|
||||
|
||||
$members = array();
|
||||
foreach ($administrators as $administrator) {
|
||||
$members = array_merge($members,
|
||||
handleSingleUserPHID($keydir, $viewer, $administrator->getPHID(),
|
||||
$system_keys, $used_keys));
|
||||
}
|
||||
return $members;
|
||||
}
|
||||
|
||||
function handleLegalpadSingleDocument(
|
||||
$keydir, $viewer, $document, $system_keys, &$used_keys) {
|
||||
if ($document->getSignatureType() !=
|
||||
LegalpadDocument::SIGNATURE_TYPE_INDIVIDUAL) {
|
||||
return array();
|
||||
}
|
||||
|
||||
$members = array();
|
||||
foreach ($document->getSignatures() as $signature) {
|
||||
if ($signature->getSignatureType() !=
|
||||
LegalpadDocument::SIGNATURE_TYPE_INDIVIDUAL) {
|
||||
continue;
|
||||
}
|
||||
$members = array_merge($members,
|
||||
handleSingleUserPHID($keydir, $viewer, $signature->getSignerPHID(),
|
||||
$system_keys, $used_keys));
|
||||
}
|
||||
return $members;
|
||||
}
|
||||
|
||||
function handleLegalpadSignaturePolicyRule(
|
||||
$keydir, $viewer, $rule, $system_keys, &$used_keys) {
|
||||
$documents = id(new LegalpadDocumentQuery())
|
||||
->setViewer($viewer)
|
||||
->withPHIDs($rule['value'])
|
||||
->needSignatures(true)
|
||||
->execute();
|
||||
|
||||
$members = array();
|
||||
foreach ($documents as $document) {
|
||||
$members = array_merge(
|
||||
$members,
|
||||
handleLegalpadSingleDocument(
|
||||
$keydir, $viewer, $document, $system_keys, $used_keys));
|
||||
}
|
||||
return $members;
|
||||
}
|
||||
|
||||
function handleCustomPolicy(
|
||||
$keydir, $viewer, $policy, $system_keys, &$used_keys) {
|
||||
$members = array();
|
||||
$rules = $policy->getRules();
|
||||
foreach ($rules as $rule) {
|
||||
// Everyone is denied by default anyway
|
||||
if ($rule['action'] != 'allow') {
|
||||
continue;
|
||||
}
|
||||
|
||||
$policy_members = array();
|
||||
$rule_type = $rule['rule'];
|
||||
if ($rule_type == 'PhabricatorPolicyRuleUsers') {
|
||||
$policy_members = handleUsersPolicyRule(
|
||||
$keydir, $viewer, $rule, $system_keys, $used_keys);
|
||||
} else if ($rule_type == 'PhabricatorProjectsPolicyRule') {
|
||||
$policy_members = handleProjectsPolicyRule(
|
||||
$keydir, $viewer, $rule, $system_keys, $used_keys);
|
||||
} else if ($rule_type == 'PhabricatorProjectsAllPolicyRule') {
|
||||
$policy_members = handleProjectsAllPolicyRule(
|
||||
$keydir, $viewer, $rule, $system_keys, $used_keys);
|
||||
} else if ($rule_type == 'PhabricatorAdministratorsPolicyRule') {
|
||||
$policy_members = handleAdministratorsPolicyRule(
|
||||
$keydir, $viewer, $rule, $system_keys, $used_keys);
|
||||
} else if ($rule_type == 'PhabricatorLegalpadSignaturePolicyRule') {
|
||||
$policy_members = handleLegalpadSignaturePolicyRule(
|
||||
$keydir, $viewer, $rule, $system_keys, $used_keys);
|
||||
}
|
||||
|
||||
$members = array_merge($members, $policy_members);
|
||||
}
|
||||
|
||||
return $members;
|
||||
}
|
||||
|
||||
// Parse repository and put it's members to the config file
|
||||
function handleSingleRepository(
|
||||
$keydir, $viewer, $repository, $all_repositories, $system_keys,
|
||||
&$new_configuration, &$used_keys) {
|
||||
$policies = PhabricatorPolicyQuery::loadPolicies(
|
||||
$viewer,
|
||||
$repository);
|
||||
|
||||
$pushable = $policies[DiffusionPushCapability::CAPABILITY];
|
||||
$type = $pushable->getType();
|
||||
|
||||
$members = array();
|
||||
|
||||
if ($type == PhabricatorPolicyType::TYPE_PROJECT) {
|
||||
$project = id(new PhabricatorProjectQuery())
|
||||
->setViewer($viewer)
|
||||
->needMembers(true)
|
||||
->withPHIDs(array($pushable->getPHID()))
|
||||
->executeOne();
|
||||
|
||||
$memberPHIDs = $project->getMemberPHIDs();
|
||||
foreach ($memberPHIDs as $memberPHID) {
|
||||
$members = array_merge($members,
|
||||
handleSingleUserPHID($keydir, $viewer, $memberPHID,
|
||||
$system_keys, $used_keys));
|
||||
}
|
||||
} else if ($type == PhabricatorPolicyType::TYPE_USER) {
|
||||
$members = handleSingleUserPHID(
|
||||
$keydir, $viewer, $pushable->getPHID(), $system_keys, $used_keys);
|
||||
} else if ($type == PhabricatorPolicyType::TYPE_CUSTOM) {
|
||||
$members = handleCustomPolicy(
|
||||
$keydir, $viewer, $pushable, $system_keys, $used_keys);
|
||||
} else {
|
||||
/* pass */
|
||||
}
|
||||
|
||||
if (count($members)) {
|
||||
$uri = $repository->getRemoteURI();
|
||||
$repository_name = basename($uri, '.git');
|
||||
$escaped_repository_name = escape_name($repository->getName());
|
||||
$group_name = "PHAB_${escaped_repository_name}";
|
||||
$values = array();
|
||||
$values['members'] = join(' ', $members);
|
||||
$values['readonly'] = join(' ', $all_repositories);
|
||||
$values['writable'] = $repository_name;
|
||||
$new_configuration["group $group_name"] = $values;
|
||||
}
|
||||
}
|
||||
|
||||
// Remove groups from previous automated configuration built
|
||||
function getCleanOldConfiguration($old_configuration) {
|
||||
$new_configuration = array();
|
||||
foreach ($old_configuration as $group => $values) {
|
||||
if (!startswith($group, 'group PHAB')) {
|
||||
$new_configuration[$group] = $values;
|
||||
}
|
||||
}
|
||||
return $new_configuration;
|
||||
}
|
||||
|
||||
// Get non-phab keys
|
||||
function getSystemPublicKeys($keydir) {
|
||||
$files = scandir($keydir);
|
||||
$system_keys = array();
|
||||
foreach ($files as $file) {
|
||||
if (!startswith($file, "PHAB") && endswith($file, '.pub')) {
|
||||
$key = file_get_contents("$keydir/$file");
|
||||
$system_keys[$key] = basename($file, '.pub');
|
||||
}
|
||||
}
|
||||
return $system_keys;
|
||||
}
|
||||
|
||||
// Remove unused public keys
|
||||
function removeUnusedPublicKeys($keydir, $used_keys) {
|
||||
$files = scandir($keydir);
|
||||
foreach ($files as $file) {
|
||||
if (startswith($file, "PHAB")) {
|
||||
$member = basename($file, '.pub');
|
||||
if (!array_key_exists($member, $used_keys)) {
|
||||
unlink("$keydir/$file");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function rebuildConfiguration($gitosis_root) {
|
||||
$keydir = "$gitosis_root/keydir";
|
||||
$configuration_file = "$gitosis_root/gitosis.conf";
|
||||
|
||||
if (!file_exists($configuration_file)) {
|
||||
print("Not found: $configuration_file\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
$viewer = id(new PhabricatorUser())
|
||||
->loadOneWhere('username = %s', 'sergey');
|
||||
|
||||
$old_configuration = parse_ini_file(
|
||||
$configuration_file, true, INI_SCANNER_RAW);
|
||||
|
||||
$new_configuration = getCleanOldConfiguration(
|
||||
$old_configuration);
|
||||
|
||||
// Get "system" keys to re-use if phab account uses the
|
||||
// same public key
|
||||
$system_keys = getSystemPublicKeys($keydir);
|
||||
|
||||
// Get list of all repos which is awailable for read
|
||||
$all_repositories = array();
|
||||
foreach ($old_configuration as $group => $values) {
|
||||
if (startswith($group, 'repo')) {
|
||||
$repository_name = substr($group, 5, strlen($group) - 5);
|
||||
if ($repository_name == 'gitosis-admin')
|
||||
continue;
|
||||
$all_repositories[] = $repository_name;
|
||||
}
|
||||
}
|
||||
|
||||
// Fill in new configuration and keys
|
||||
$used_keys = array();
|
||||
$repositories = id(new PhabricatorRepositoryQuery())
|
||||
->setViewer($viewer)
|
||||
->execute();
|
||||
|
||||
foreach ($repositories as $repository_id => $repository) {
|
||||
$type = $repository->getVersionControlSystem();
|
||||
if ($type == PhabricatorRepositoryType::REPOSITORY_TYPE_GIT) {
|
||||
handleSingleRepository(
|
||||
$keydir, $viewer, $repository, $all_repositories, $system_keys,
|
||||
$new_configuration, $used_keys);
|
||||
}
|
||||
}
|
||||
|
||||
write_ini_file($new_configuration, $configuration_file);
|
||||
removeUnusedPublicKeys($keydir, $used_keys);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
function getGitCommand($repository) {
|
||||
$git_dir = realpath("$repository/.git");
|
||||
$git = "git --git-dir='$git_dir'";
|
||||
$git .= ' --work-tree='.realpath($repository);
|
||||
return $git;
|
||||
}
|
||||
|
||||
function runGitCommand($repository, $arguments,
|
||||
&$output=null, &$return_var=null) {
|
||||
$git = getGitCommand($repository);
|
||||
$git .= " $arguments";
|
||||
exec($git, $output, $return_var);
|
||||
return $return_var == 0;
|
||||
}
|
||||
|
||||
function runGitSshCommand($repository, $key, $arguments,
|
||||
&$output=null, &$return_var=null) {
|
||||
$gitx_ssh = realpath(dirname(__FILE__) . "/gitx-ssh");
|
||||
$abs_key = realpath($key);
|
||||
$git = "SSH_KEYFILE=$abs_key GIT_SSH=$gitx_ssh ";
|
||||
$git .= getGitCommand($repository);
|
||||
$git .= " $arguments";
|
||||
exec($git, $output, $return_var);
|
||||
return $return_var == 0;
|
||||
}
|
||||
|
||||
function repositoryPull($repository, $key) {
|
||||
return runGitSshCommand($repository, $key, 'pull');
|
||||
}
|
||||
|
||||
function repositoryCommitAll($repository, $author, $message) {
|
||||
if (!runGitCommand(
|
||||
$repository, 'ls-files --other --exclude-standard', $untracked_files)) {
|
||||
return false;
|
||||
}
|
||||
if (count($untracked_files)) {
|
||||
$flat_files = join(' ', $untracked_files);
|
||||
if (!runGitCommand($repository, "add $flat_files")) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
runGitCommand($repository, "update-index -q --refresh", $output);
|
||||
runGitCommand($repository, "diff-index --name-only HEAD --", $output);
|
||||
if (count($output)) {
|
||||
return runGitCommand(
|
||||
$repository, "commit --author='$author' -a -m '$message'", $output);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
if (count($argv) != 3) {
|
||||
print("Usage: {$argv[0]} /path/to/gitosis-admin /path/to/id_rsa.pub\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
$gitosis_root = $argv[1];
|
||||
$key = $argv[2];
|
||||
|
||||
if (!repositoryPull($gitosis_root, $key)) {
|
||||
print("Failed to pull changes from server.\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (!rebuildConfiguration($gitosis_root)) {
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (!repositoryCommitAll(
|
||||
$gitosis_root, 'Rebuild Gitadmin <null@git.blender.org>',
|
||||
'Update to correspond changes in Phabricator')) {
|
||||
print("Failed to commit changes.\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
runGitSshCommand($gitosis_root, $key, 'push origin master');
|
||||
?>
|
504
scripts/gitolite/rebuild_gitolite.php
Executable file
@@ -0,0 +1,504 @@
|
||||
#!/usr/local/bin/php
|
||||
<?php
|
||||
|
||||
$root = dirname(dirname(dirname(__FILE__)));
|
||||
require_once $root.'/scripts/__init_script__.php';
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Utilities.
|
||||
//
|
||||
// TODO(sergey): Move somewhere else. Or, evenmore ideally, use Phabricator's
|
||||
// utilities instead.
|
||||
|
||||
function escape_name($name) {
|
||||
return preg_replace('/[^A-Za-z0-9]/', '_', $name);
|
||||
}
|
||||
|
||||
function startswith($string, $prefix) {
|
||||
return substr($string, 0, strlen($prefix)) == $prefix;
|
||||
}
|
||||
|
||||
function endswith($string, $suffix) {
|
||||
$suffix_length = strlen($suffix);
|
||||
return substr($string, strlen($string) - $suffix_length,
|
||||
$suffix_length) == $suffix;
|
||||
}
|
||||
|
||||
function file_put_contents_if_different($file_name, $content) {
|
||||
if (file_exists($file_name)) {
|
||||
$current_content = file_get_contents($file_name);
|
||||
if ($current_content == $content) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
file_put_contents($file_name, $content);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Phabricator access list traversal.
|
||||
|
||||
class Configuration {
|
||||
// Phabricator user which is used as a viewer.
|
||||
public $viewer;
|
||||
|
||||
// Directory where public keys are stored.
|
||||
// Full path.
|
||||
protected $keys_directory;
|
||||
|
||||
// Gitolite configuration file (gitolite.conf).
|
||||
// Full path.
|
||||
protected $config_file;
|
||||
|
||||
// Indexed by key content, contains configuration user name.
|
||||
protected $stored_keys;
|
||||
|
||||
// Indexed by config user name.
|
||||
protected $used_keys;
|
||||
|
||||
// Indexed by committers variable name, contains list of users which are
|
||||
// configured by Phabricator to be able to commit to the repository.
|
||||
protected $committers;
|
||||
|
||||
public function __construct($gitolite_root) {
|
||||
$this->viewer = PhabricatorUser::getOmnipotentUser();
|
||||
$this->keys_directory = "$gitolite_root/keydir";
|
||||
$this->config_file = "$gitolite_root/conf/gitolite.conf";
|
||||
|
||||
$this->collectSystemPublicKeys();
|
||||
|
||||
$this->used_keys = array();
|
||||
$this->committers = array();
|
||||
|
||||
if (!file_exists($this->config_file)) {
|
||||
die("Not found: $this->config_file\n");
|
||||
}
|
||||
}
|
||||
|
||||
// Store given key of given user.
|
||||
//
|
||||
// Includes both storing public key in the file, and storing mapping between
|
||||
// user and the key.
|
||||
public function storeUserPublicKey($user, $key) {
|
||||
$full_key_content = $this->getPublicKeyContent($key);
|
||||
|
||||
if (array_key_exists($full_key_content, $this->stored_keys)) {
|
||||
return $this->stored_keys[$full_key_content];
|
||||
}
|
||||
|
||||
$config_user_name = $this->getConfigUserName($user, $key);
|
||||
|
||||
if (!array_key_exists($config_user_name, $this->used_keys)) {
|
||||
$this->used_keys[$config_user_name] = true;
|
||||
file_put_contents_if_different("$this->keys_directory/$config_user_name.pub",
|
||||
$full_key_content);
|
||||
}
|
||||
|
||||
$this->stored_keys[$full_key_content] = $config_user_name;
|
||||
|
||||
return $config_user_name;
|
||||
}
|
||||
|
||||
public function setRepositoryUsers($repository, $config_user_names) {
|
||||
$uri = $repository->getRemoteURI();
|
||||
$repository_name = basename($uri, '.git');
|
||||
|
||||
$variable_name = '@committers_' . escape_name(strtolower($repository_name));
|
||||
|
||||
if (array_key_exists($variable_name, $this->committers)) {
|
||||
die("Duplicate variable mapping for repository $uri\n");
|
||||
}
|
||||
|
||||
$this->committers[$variable_name] = $config_user_names;
|
||||
}
|
||||
|
||||
public function writeNewConfiguration() {
|
||||
$current_config = file_get_contents($this->config_file);
|
||||
$current_config_lines = explode("\n", $current_config);
|
||||
|
||||
$new_config = "";
|
||||
foreach ($current_config_lines as $line) {
|
||||
if (startswith($line, '@committers_')) {
|
||||
$parts = explode('=', $line);
|
||||
$variable_name = trim($parts[0]);
|
||||
if (array_key_exists($variable_name, $this->committers)) {
|
||||
$system_committers = $this->getNonPhabtricatorUsers($parts[1]);
|
||||
$all_committers = array_merge(
|
||||
$system_committers, $this->committers[$variable_name]);
|
||||
$unique_committers = array_unique($all_committers);
|
||||
$committers = implode(' ', $unique_committers);
|
||||
$line = "$variable_name = $committers";
|
||||
}
|
||||
}
|
||||
$new_config .= $line . "\n";
|
||||
}
|
||||
|
||||
file_put_contents_if_different($this->config_file, trim($new_config) . "\n");
|
||||
}
|
||||
|
||||
protected function getNonPhabtricatorUsers($configuration_value) {
|
||||
$system_users = array();
|
||||
$users = explode(' ', $configuration_value);
|
||||
foreach ($users as $user) {
|
||||
$user = trim($user);
|
||||
if (empty($user)) {
|
||||
continue;
|
||||
}
|
||||
if (startswith($user, 'PHAB')) {
|
||||
continue;
|
||||
}
|
||||
$system_users[] = $user;
|
||||
}
|
||||
return $system_users;
|
||||
}
|
||||
|
||||
public function finalize() {
|
||||
$this->removeUnusedPublicKeys();
|
||||
}
|
||||
|
||||
// Get content of a public key to be stored in file.
|
||||
protected function getPublicKeyContent($key) {
|
||||
return $key->getKeyType().' '.
|
||||
$key->getKeyBody().' '.
|
||||
$key->getKeyComment()."\n";
|
||||
}
|
||||
|
||||
// Get user+key name used by the Gitolite configuration.
|
||||
protected function getConfigUserName($user, $key) {
|
||||
$escaped_key_name = escape_name($key->getName());
|
||||
return 'PHAB_'.$user->getUserName().
|
||||
'_'.$escaped_key_name.
|
||||
'_'.$key->getID();
|
||||
}
|
||||
|
||||
// Get keys which are not managed by this Phabricator/Git integration script.
|
||||
//
|
||||
// Returns map from key content to the key file name. This is used to avoid
|
||||
// public key duplication in the case system key is used by phabricator user.
|
||||
protected function collectSystemPublicKeys() {
|
||||
$files = scandir($this->keys_directory);
|
||||
foreach ($files as $file) {
|
||||
if (startswith($file, "PHAB")) {
|
||||
continue;
|
||||
}
|
||||
if (!endswith($file, '.pub')) {
|
||||
continue;
|
||||
}
|
||||
$key = file_get_contents("$this->keys_directory/$file");
|
||||
$file_we = basename($file, '.pub');
|
||||
$this->stored_keys[$key] = $file_we;
|
||||
$this->used_keys[$file_we] = true;
|
||||
}
|
||||
}
|
||||
|
||||
protected function removeUnusedPublicKeys() {
|
||||
$files = scandir($this->keys_directory);
|
||||
foreach ($files as $file) {
|
||||
if (!startswith($file, "PHAB")) {
|
||||
continue;
|
||||
}
|
||||
$config_user_name = basename($file, '.pub');
|
||||
if (!array_key_exists($config_user_name, $this->used_keys)) {
|
||||
unlink("$this->keys_directory/$file");
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
function getProjectMembersPHIDs($viewer, $project_phid) {
|
||||
$project = id(new PhabricatorProjectQuery())
|
||||
->setViewer($viewer)
|
||||
->needMembers(true)
|
||||
->withPHIDs(array($project_phid))
|
||||
->executeOne();
|
||||
|
||||
return $project->getMemberPHIDs();
|
||||
}
|
||||
|
||||
// Get user's heys and put them to the configuration
|
||||
function handleSingleUserPHID($config, $userPHID) {
|
||||
$user = id(new PhabricatorPeopleQuery())
|
||||
->setViewer($config->viewer)
|
||||
->withPHIDs(array($userPHID))
|
||||
->executeOne();
|
||||
if (!$user) {
|
||||
return array();
|
||||
}
|
||||
|
||||
if ($user->getIsDisabled()) {
|
||||
return array();
|
||||
}
|
||||
|
||||
$keys = id(new PhabricatorAuthSSHKey())->loadAllWhere(
|
||||
'objectPHID = %s',
|
||||
$user->getPHID());
|
||||
|
||||
$config_user_names = array();
|
||||
foreach ($keys as $key) {
|
||||
$config_user_name = $config->storeUserPublicKey($user, $key);
|
||||
$config_user_names[] = $config_user_name;
|
||||
}
|
||||
|
||||
return $config_user_names;
|
||||
}
|
||||
|
||||
function handleUsersPolicyRule($config, $rule) {
|
||||
$config_user_names = array();
|
||||
foreach ($rule['value'] as $userPHID) {
|
||||
$config_user_names = array_merge($config_user_names,
|
||||
handleSingleUserPHID($config, $userPHID));
|
||||
}
|
||||
return $config_user_names;
|
||||
}
|
||||
|
||||
function handleProjectsPolicyRule($config, $rule) {
|
||||
$config_user_names = array();
|
||||
foreach ($rule['value'] as $projectPHID) {
|
||||
$memberPHIDs = getProjectMembersPHIDs($config->viewer, $projectPHID);
|
||||
foreach ($memberPHIDs as $userPHID) {
|
||||
$config_user_names = array_merge($config_user_names,
|
||||
handleSingleUserPHID($config, $userPHID));
|
||||
}
|
||||
}
|
||||
return $config_user_names;
|
||||
}
|
||||
|
||||
function handleProjectsAllPolicyRule($config, $rule) {
|
||||
$is_first_project = true;
|
||||
$allowed_members_phids = array();
|
||||
foreach ($rule['value'] as $project_phid) {
|
||||
$memberPHIDs = getProjectMembersPHIDs($config->viewer, $project_phid);
|
||||
if ($is_first_project) {
|
||||
$allowed_members_phids = $memberPHIDs;
|
||||
$is_first_project = false;
|
||||
} else {
|
||||
$allowed_members_phids = array_intersect(
|
||||
$allowed_members_phids, $memberPHIDs);
|
||||
}
|
||||
}
|
||||
|
||||
$config_user_names = array();
|
||||
foreach ($allowed_members_phids as $userPHID) {
|
||||
$config_user_names = array_merge($config_user_names,
|
||||
handleSingleUserPHID($config, $userPHID));
|
||||
}
|
||||
return $config_user_names;
|
||||
}
|
||||
|
||||
function handleAdministratorsPolicyRule($config, $rule) {
|
||||
$administrators = id(new PhabricatorPeopleQuery())
|
||||
->setViewer($config->viewer)
|
||||
->withIsAdmin(true)
|
||||
->execute();
|
||||
|
||||
$config_user_names = array();
|
||||
foreach ($administrators as $administrator) {
|
||||
$config_user_names = array_merge($config_user_names,
|
||||
handleSingleUserPHID($config, $administrator->getPHID()));
|
||||
}
|
||||
return $config_user_names;
|
||||
}
|
||||
|
||||
function handleLegalpadSingleDocument($config, $document) {
|
||||
if ($document->getSignatureType() !=
|
||||
LegalpadDocument::SIGNATURE_TYPE_INDIVIDUAL) {
|
||||
return array();
|
||||
}
|
||||
|
||||
$config_user_names = array();
|
||||
foreach ($document->getSignatures() as $signature) {
|
||||
if ($signature->getSignatureType() !=
|
||||
LegalpadDocument::SIGNATURE_TYPE_INDIVIDUAL) {
|
||||
continue;
|
||||
}
|
||||
$config_user_names = array_merge($config_user_names,
|
||||
handleSingleUserPHID($config, $signature->getSignerPHID()));
|
||||
}
|
||||
return $config_user_names;
|
||||
}
|
||||
|
||||
function handleLegalpadSignaturePolicyRule($config, $rule) {
|
||||
$documents = id(new LegalpadDocumentQuery())
|
||||
->setViewer($config->viewer)
|
||||
->withPHIDs($rule['value'])
|
||||
->needSignatures(true)
|
||||
->execute();
|
||||
|
||||
$config_user_names = array();
|
||||
foreach ($documents as $document) {
|
||||
$config_user_names = array_merge($config_user_names,
|
||||
handleLegalpadSingleDocument($config, $document));
|
||||
}
|
||||
return $config_user_names;
|
||||
}
|
||||
|
||||
function handleCustomPolicy($config, $policy) {
|
||||
$config_user_names = array();
|
||||
$rules = $policy->getRules();
|
||||
foreach ($rules as $rule) {
|
||||
// Everyone is denied by default anyway
|
||||
if ($rule['action'] != 'allow') {
|
||||
continue;
|
||||
}
|
||||
|
||||
$policy_config_user_names = array();
|
||||
$rule_type = $rule['rule'];
|
||||
if ($rule_type == 'PhabricatorPolicyRuleUsers') {
|
||||
$policy_config_user_names =
|
||||
handleUsersPolicyRule($config, $rule);
|
||||
} else if ($rule_type == 'PhabricatorProjectsPolicyRule') {
|
||||
$policy_config_user_names =
|
||||
handleProjectsPolicyRule($config, $rule);
|
||||
} else if ($rule_type == 'PhabricatorProjectsAllPolicyRule') {
|
||||
$policy_config_user_names =
|
||||
handleProjectsAllPolicyRule($config, $rule);
|
||||
} else if ($rule_type == 'PhabricatorAdministratorsPolicyRule') {
|
||||
$policy_config_user_names =
|
||||
handleAdministratorsPolicyRule($config, $rule);
|
||||
} else if ($rule_type == 'PhabricatorLegalpadSignaturePolicyRule') {
|
||||
$policy_config_user_names =
|
||||
handleLegalpadSignaturePolicyRule($config, $rule);
|
||||
}
|
||||
|
||||
$config_user_names = array_merge(
|
||||
$config_user_names, $policy_config_user_names);
|
||||
}
|
||||
|
||||
return $config_user_names;
|
||||
}
|
||||
|
||||
// Parse repository and put it's members to the config file
|
||||
function handleSingleRepository($config, $repository) {
|
||||
$policies = PhabricatorPolicyQuery::loadPolicies(
|
||||
$config->viewer,
|
||||
$repository);
|
||||
|
||||
$pushable = $policies[DiffusionPushCapability::CAPABILITY];
|
||||
$type = $pushable->getType();
|
||||
|
||||
$config_user_names = array();
|
||||
|
||||
if ($type == PhabricatorPolicyType::TYPE_PROJECT) {
|
||||
$project = id(new PhabricatorProjectQuery())
|
||||
->setViewer($config->viewer)
|
||||
->needMembers(true)
|
||||
->withPHIDs(array($pushable->getPHID()))
|
||||
->executeOne();
|
||||
|
||||
$memberPHIDs = $project->getMemberPHIDs();
|
||||
foreach ($memberPHIDs as $memberPHID) {
|
||||
$config_user_names = array_merge($config_user_names,
|
||||
handleSingleUserPHID($config, $memberPHID));
|
||||
}
|
||||
} else if ($type == PhabricatorPolicyType::TYPE_USER) {
|
||||
$config_user_names = handleSingleUserPHID($config, $pushable->getPHID());
|
||||
} else if ($type == PhabricatorPolicyType::TYPE_CUSTOM) {
|
||||
$config_user_names = handleCustomPolicy($config, $pushable);
|
||||
} else {
|
||||
/* pass */
|
||||
}
|
||||
|
||||
$config->setRepositoryUsers($repository, $config_user_names);
|
||||
}
|
||||
|
||||
function rebuildConfiguration($gitolite_root) {
|
||||
$config = new Configuration($gitolite_root);
|
||||
|
||||
// Fill in new configuration and keys
|
||||
$used_keys = array();
|
||||
$repositories = id(new PhabricatorRepositoryQuery())
|
||||
->setViewer($config->viewer)
|
||||
->execute();
|
||||
|
||||
foreach ($repositories as $repository_id => $repository) {
|
||||
$type = $repository->getVersionControlSystem();
|
||||
if ($type == PhabricatorRepositoryType::REPOSITORY_TYPE_GIT) {
|
||||
handleSingleRepository($config, $repository);
|
||||
}
|
||||
}
|
||||
|
||||
$config->writeNewConfiguration();
|
||||
|
||||
$config->finalize();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Repository manipulation functionality.
|
||||
|
||||
function getGitCommand($repository) {
|
||||
$git_dir = realpath("$repository/.git");
|
||||
$git = "git --git-dir='$git_dir'";
|
||||
$git .= ' --work-tree='.realpath($repository);
|
||||
return $git;
|
||||
}
|
||||
|
||||
function runGitCommand($repository, $arguments,
|
||||
&$output=null, &$return_var=null) {
|
||||
$git = getGitCommand($repository);
|
||||
$git .= " $arguments";
|
||||
exec($git, $output, $return_var);
|
||||
return $return_var == 0;
|
||||
}
|
||||
|
||||
function runGitSshCommand($repository, $key, $arguments,
|
||||
&$output=null, &$return_var=null) {
|
||||
$abs_key = realpath($key);
|
||||
$git = "GIT_SSH_COMMAND=\"ssh -i $key -o IdentitiesOnly=yes\" ";
|
||||
$git .= getGitCommand($repository);
|
||||
$git .= " $arguments";
|
||||
exec($git, $output, $return_var);
|
||||
return $return_var == 0;
|
||||
}
|
||||
|
||||
function repositoryPull($repository, $key) {
|
||||
return runGitSshCommand($repository, $key, 'pull --rebase');
|
||||
}
|
||||
|
||||
function repositoryCommitAll($repository, $author, $message) {
|
||||
if (!runGitCommand(
|
||||
$repository, 'ls-files --other --exclude-standard', $untracked_files)) {
|
||||
return false;
|
||||
}
|
||||
if (count($untracked_files)) {
|
||||
$flat_files = join(' ', $untracked_files);
|
||||
if (!runGitCommand($repository, "add $flat_files")) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
runGitCommand($repository, "update-index -q --refresh", $output);
|
||||
runGitCommand($repository, "diff-index --name-only HEAD --", $output);
|
||||
if (count($output)) {
|
||||
return runGitCommand(
|
||||
$repository, "commit --author='$author' -a -m '$message'", $output);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
if (count($argv) != 3) {
|
||||
print("Usage: {$argv[0]} /path/to/gitolite-admin /path/to/id_rsa.pub\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
$gitolite_root = $argv[1];
|
||||
$key = $argv[2];
|
||||
|
||||
if (!repositoryPull($gitolite_root, $key)) {
|
||||
print("Failed to pull changes from server.\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (!rebuildConfiguration($gitolite_root)) {
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (!repositoryCommitAll(
|
||||
$gitolite_root, 'Rebuild Gitadmin <null@git.blender.org>',
|
||||
'Update to correspond changes in Phabricator')) {
|
||||
print("Failed to commit changes.\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
runGitSshCommand($gitolite_root, $key, 'push origin master');
|
||||
?>
|
@@ -22,7 +22,7 @@ failed() {
|
||||
}
|
||||
|
||||
ISSUE=`cat /etc/issue`
|
||||
if [[ $ISSUE != Ubuntu* ]]
|
||||
if [[ ($ISSUE != Ubuntu*) && ($ISSUE != Debian*) ]];
|
||||
then
|
||||
echo "This script is intended for use on Ubuntu, but this system appears";
|
||||
echo "to be something else. Your results may vary.";
|
||||
|
61
scripts/svnauth/archived_repos.php
Normal file
@@ -0,0 +1,61 @@
|
||||
<?php
|
||||
$ARCHIVED_REPOS = array(
|
||||
'abstractmesh',
|
||||
'beast',
|
||||
# 'bf-blender',
|
||||
'bf-docboard-es',
|
||||
'bf-extensions',
|
||||
'bf-funboard',
|
||||
'bf-scripts',
|
||||
# 'bf-translations',
|
||||
'bfct',
|
||||
'bforge',
|
||||
'blend-doc',
|
||||
'blend2cs',
|
||||
'blendedmidi',
|
||||
'blendercad',
|
||||
'blendxml',
|
||||
'bzoo',
|
||||
'docboard',
|
||||
'drqueue',
|
||||
'ghost',
|
||||
'girona',
|
||||
'guiman',
|
||||
'lsystem',
|
||||
'magic',
|
||||
'makeh',
|
||||
'mechanicblender',
|
||||
'neverblender',
|
||||
'news',
|
||||
'night',
|
||||
'nitrox',
|
||||
'osgexport',
|
||||
'peerrating',
|
||||
'piovra',
|
||||
'pyverse',
|
||||
'qdune',
|
||||
'scolblender',
|
||||
'skined',
|
||||
'smdio',
|
||||
'soapyblender',
|
||||
'soc-2005',
|
||||
'soc-2006',
|
||||
'soc-2007',
|
||||
'soc-2008',
|
||||
'sourceforge',
|
||||
'spe',
|
||||
'stats',
|
||||
'ter2blend',
|
||||
'torqueexporter',
|
||||
'tuhopuu',
|
||||
'tzuray',
|
||||
'vectex',
|
||||
'vectorrender',
|
||||
'verse',
|
||||
'vrmlimportexp',
|
||||
'warblender',
|
||||
'wpyre',
|
||||
'yafray',
|
||||
'yofrankie'
|
||||
);
|
||||
?>
|
292
scripts/svnauth/rebuild_svnauth.php
Executable file
@@ -0,0 +1,292 @@
|
||||
#!/usr/local/bin/php
|
||||
<?php
|
||||
|
||||
$root = dirname(dirname(dirname(__FILE__)));
|
||||
require_once $root.'/scripts/__init_script__.php';
|
||||
|
||||
function getSVNRepositoryName($repository) {
|
||||
$uri = $repository->getRemoteURI();
|
||||
return preg_replace(
|
||||
'/https?\:\/\/.*?\/svnroot\/([^\/]+)\/?.*/', '$1', $uri);
|
||||
}
|
||||
|
||||
// Get user's heys and put them to the configuration
|
||||
function handleSingleUserPHID(
|
||||
$viewer, $userPHID, $repository, &$namemap, &$access) {
|
||||
$user = id(new PhabricatorPeopleQuery())
|
||||
->setViewer($viewer)
|
||||
->withPHIDs(array($userPHID))
|
||||
->executeOne();
|
||||
if (!$user) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ($user->getIsDisabled()) {
|
||||
return;
|
||||
}
|
||||
|
||||
$user_name = $user->getUserName();
|
||||
if (!array_key_exists($user_name, $namemap)) {
|
||||
$namemap[$user_name] = array('email' => $user->loadPrimaryEmailAddress(),
|
||||
'name' => $user->getRealName());
|
||||
}
|
||||
|
||||
$repository_name = getSVNRepositoryName($repository);
|
||||
|
||||
$repository_rootpath = $repository_name . ':/';
|
||||
if (!array_key_exists($repository_rootpath, $access)) {
|
||||
$access[$repository_rootpath]['RW'] = array();
|
||||
$access[$repository_rootpath]['RO'] = array();
|
||||
}
|
||||
$access[$repository_rootpath]['RO'][] = $user_name;
|
||||
|
||||
// Store write access settings to current subath
|
||||
$subpath = $repository->getDetail('svn-subpath');
|
||||
$subpath = rtrim($subpath, '/');
|
||||
$repository_pathname = "$repository_name:/$subpath";
|
||||
if (!array_key_exists($repository_pathname, $access)) {
|
||||
$access[$repository_pathname]['RW'] = array();
|
||||
$access[$repository_pathname]['RO'] = array();
|
||||
}
|
||||
$access[$repository_pathname]['RW'][] = $user_name;
|
||||
|
||||
// Write access to the tags
|
||||
$tags_pathname = "$repository_name:/tags";
|
||||
if (!array_key_exists($tags_pathname, $access)) {
|
||||
$access[$tags_pathname]['RW'] = array();
|
||||
$access[$tags_pathname]['RO'] = array();
|
||||
}
|
||||
$access[$tags_pathname]['RW'][] = $user_name;
|
||||
|
||||
// Write access to the branches.
|
||||
$branches_pathname = "$repository_name:/branches";
|
||||
if (!array_key_exists($branches_pathname, $access)) {
|
||||
$access[$branches_pathname]['RW'] = array();
|
||||
$access[$branches_pathname]['RO'] = array();
|
||||
}
|
||||
$access[$branches_pathname]['RW'][] = $user_name;
|
||||
}
|
||||
|
||||
function getProjectMembersPHIDs($viewer, $project_phid) {
|
||||
$project = id(new PhabricatorProjectQuery())
|
||||
->setViewer($viewer)
|
||||
->needMembers(true)
|
||||
->withPHIDs(array($project_phid))
|
||||
->executeOne();
|
||||
|
||||
return $project->getMemberPHIDs();
|
||||
}
|
||||
|
||||
function handleProjectPHID(
|
||||
$viewer, $project_phid, $repository, &$namemap, &$access) {
|
||||
$memberPHIDs = getProjectMembersPHIDs($viewer, $project_phid);
|
||||
foreach ($memberPHIDs as $memberPHID) {
|
||||
handleSingleUserPHID(
|
||||
$viewer, $memberPHID, $repository, $namemap, $access);
|
||||
}
|
||||
}
|
||||
|
||||
function handleUsersPolicyRule(
|
||||
$viewer, $rule, $repository, &$namemap, &$access) {
|
||||
foreach ($rule['value'] as $user_phid) {
|
||||
handleSingleUserPHID(
|
||||
$viewer, $user_phid, $repository, $namemap, $access);
|
||||
}
|
||||
}
|
||||
|
||||
function handleProjectsPolicyRule(
|
||||
$viewer, $rule, $repository, &$namemap, &$access) {
|
||||
foreach ($rule['value'] as $project_phid) {
|
||||
handleProjectPHID(
|
||||
$viewer, $project_phid, $repository, $namemap, $access);
|
||||
}
|
||||
}
|
||||
|
||||
function handleProjectsAllPolicyRule(
|
||||
$viewer, $rule, $repository, &$namemap, &$access) {
|
||||
$is_first_project = true;
|
||||
$allowed_members_phids = array();
|
||||
foreach ($rule['value'] as $project_phid) {
|
||||
$memberPHIDs = getProjectMembersPHIDs($viewer, $project_phid);
|
||||
if ($is_first_project) {
|
||||
$allowed_members_phids = $memberPHIDs;
|
||||
$is_first_project = false;
|
||||
} else {
|
||||
$allowed_members_phids = array_intersect(
|
||||
$allowed_members_phids, $memberPHIDs);
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($allowed_members_phids as $user_phid) {
|
||||
handleSingleUserPHID(
|
||||
$viewer, $user_phid, $repository, $namemap, $access);
|
||||
}
|
||||
}
|
||||
|
||||
function handleAdministratorsPolicyRule(
|
||||
$viewer, $rule, $repository, &$namemap, &$access) {
|
||||
$administrators = id(new PhabricatorPeopleQuery())
|
||||
->setViewer($viewer)
|
||||
->withIsAdmin(true)
|
||||
->execute();
|
||||
foreach ($administrators as $administrator) {
|
||||
handleSingleUserPHID(
|
||||
$viewer, $administrator->getPHID(), $repository, $namemap, $access);
|
||||
}
|
||||
}
|
||||
|
||||
function handleLegalpadSingleDocument(
|
||||
$viewer, $document, $repository, &$namemap, &$access) {
|
||||
if ($document->getSignatureType() !=
|
||||
LegalpadDocument::SIGNATURE_TYPE_INDIVIDUAL) {
|
||||
return;
|
||||
}
|
||||
|
||||
foreach ($document->getSignatures() as $signature) {
|
||||
if ($signature->getSignatureType() !=
|
||||
LegalpadDocument::SIGNATURE_TYPE_INDIVIDUAL) {
|
||||
continue;
|
||||
}
|
||||
handleSingleUserPHID(
|
||||
$viewer, $signature->getSignerPHID(), $repository, $namemap, $access);
|
||||
}
|
||||
}
|
||||
|
||||
function handleLegalpadSignaturePolicyRule(
|
||||
$viewer, $rule, $repository, &$namemap, &$access) {
|
||||
$documents = id(new LegalpadDocumentQuery())
|
||||
->setViewer($viewer)
|
||||
->withPHIDs($rule['value'])
|
||||
->needSignatures(true)
|
||||
->execute();
|
||||
|
||||
foreach ($documents as $document) {
|
||||
handleLegalpadSingleDocument(
|
||||
$viewer, $document, $repository, $namemap, $access);
|
||||
}
|
||||
}
|
||||
|
||||
function handleCustomPolicyRule(
|
||||
$viewer, $rule, $repository, &$namemap, &$access) {
|
||||
if ($rule['action'] != PhabricatorPolicy::ACTION_ALLOW) {
|
||||
// By default the script decides to DENY unless explicitly allowed.
|
||||
return;
|
||||
}
|
||||
|
||||
$rule_type = $rule['rule'];
|
||||
if ($rule_type == 'PhabricatorUsersPolicyRule') {
|
||||
handleUsersPolicyRule(
|
||||
$viewer, $rule, $repository, $namemap, $access);
|
||||
} else if ($rule_type == 'PhabricatorProjectsPolicyRule') {
|
||||
handleProjectsPolicyRule(
|
||||
$viewer, $rule, $repository, $namemap, $access);
|
||||
} else if ($rule_type == 'PhabricatorProjectsAllPolicyRule') {
|
||||
handleProjectsAllPolicyRule(
|
||||
$viewer, $rule, $repository, $namemap, $access);
|
||||
} else if ($rule_type == 'PhabricatorAdministratorsPolicyRule') {
|
||||
handleAdministratorsPolicyRule(
|
||||
$viewer, $rule, $repository, $namemap, $access);
|
||||
} else if ($rule_type == 'PhabricatorLegalpadSignaturePolicyRule') {
|
||||
handleLegalpadSignaturePolicyRule(
|
||||
$viewer, $rule, $repository, $namemap, $access);
|
||||
}
|
||||
}
|
||||
|
||||
function handleCustomPolicy(
|
||||
$viewer, $policy, $repository, &$namemap, &$access) {
|
||||
foreach ($policy->getRules() as $rule) {
|
||||
handleCustomPolicyRule($viewer, $rule, $repository, $namemap, $access);
|
||||
}
|
||||
}
|
||||
|
||||
// Parse repository and put it's members to the config file
|
||||
function handleSingleRepository(
|
||||
$viewer, $repository, &$namemap, &$access) {
|
||||
$policies = PhabricatorPolicyQuery::loadPolicies(
|
||||
$viewer,
|
||||
$repository);
|
||||
|
||||
$pushable = $policies[DiffusionPushCapability::CAPABILITY];
|
||||
$type = phid_get_type($pushable->getPHID());
|
||||
|
||||
// Make sure repository is always available for read-only access
|
||||
$repository_rootpath = getSVNRepositoryName($repository) . ':/';
|
||||
if (!array_key_exists($repository_rootpath, $access)) {
|
||||
$access[$repository_rootpath]['RW'] = array();
|
||||
$access[$repository_rootpath]['RO'] = array();
|
||||
}
|
||||
|
||||
if ($type == PhabricatorProjectProjectPHIDType::TYPECONST) {
|
||||
handleProjectPHID(
|
||||
$viewer, $pushable->getPHID(), $repository, $namemap, $access);
|
||||
} else if ($type == PhabricatorPolicyType::TYPE_USER) {
|
||||
handleSingleUserPHID(
|
||||
$viewer, $pushable->getPHID(), $repository, $namemap, $access);
|
||||
} else if ($type == PhabricatorPolicyPHIDTypePolicy::TYPECONST) {
|
||||
handleCustomPolicy(
|
||||
$viewer, $pushable, $repository, $namemap, $access);
|
||||
/* pass */
|
||||
} else {
|
||||
/* pass */
|
||||
}
|
||||
}
|
||||
|
||||
function rebuildConfiguration($what) {
|
||||
$viewer = id(new PhabricatorUser())
|
||||
->loadOneWhere('username = %s', 'sergey');
|
||||
|
||||
$repositories = id(new PhabricatorRepositoryQuery())
|
||||
->setViewer($viewer)
|
||||
->execute();
|
||||
|
||||
$namemap = array();
|
||||
$access = array();
|
||||
|
||||
require_once 'archived_repos.php';
|
||||
foreach ($ARCHIVED_REPOS as $repository) {
|
||||
$repository_pathname = "$repository:/";
|
||||
$access[$repository_pathname]['RW'] = array();
|
||||
$access[$repository_pathname]['RO'] = array();
|
||||
}
|
||||
|
||||
foreach ($repositories as $repository_id => $repository) {
|
||||
$type = $repository->getVersionControlSystem();
|
||||
if ($type == PhabricatorRepositoryType::REPOSITORY_TYPE_SVN) {
|
||||
handleSingleRepository(
|
||||
$viewer, $repository, $namemap, $access);
|
||||
}
|
||||
}
|
||||
|
||||
if ($what == 'ACCESS') {
|
||||
foreach ($access as $repository => $users) {
|
||||
print("[$repository]\n");
|
||||
$rw_users = array();
|
||||
foreach ($users['RW'] as $user) {
|
||||
print("$user = rw\n");
|
||||
$rw_users[$user] = true;
|
||||
}
|
||||
foreach ($users['RO'] as $user) {
|
||||
if (!array_key_exists($user, $rw_users)) {
|
||||
print("$user = r\n");
|
||||
}
|
||||
}
|
||||
print("anonsvn = r\n");
|
||||
print("* = r\n\n");
|
||||
}
|
||||
} else if ($what == 'NAMEMAP') {
|
||||
foreach ($namemap as $user => $data) {
|
||||
print("$user\t${data['email']}\t${data['name']}\n");
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
if (count($argv) != 2 ||
|
||||
($argv[1] != 'ACCESS' && $argv[1] != 'NAMEMAP')) {
|
||||
print("Usage: {$argv[0]} ACCESS|NAMEMAP\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
rebuildConfiguration($argv[1]);
|
||||
?>
|
@@ -1773,6 +1773,7 @@ phutil_register_library_map(array(
|
||||
'ManiphestReportController' => 'applications/maniphest/controller/ManiphestReportController.php',
|
||||
'ManiphestSchemaSpec' => 'applications/maniphest/storage/ManiphestSchemaSpec.php',
|
||||
'ManiphestSearchConduitAPIMethod' => 'applications/maniphest/conduit/ManiphestSearchConduitAPIMethod.php',
|
||||
'ManiphestSearchController' => 'applications/maniphest/controller/ManiphestSearchController.php',
|
||||
'ManiphestStatusEmailCommand' => 'applications/maniphest/command/ManiphestStatusEmailCommand.php',
|
||||
'ManiphestStatusSearchConduitAPIMethod' => 'applications/maniphest/conduit/ManiphestStatusSearchConduitAPIMethod.php',
|
||||
'ManiphestStatusesConfigType' => 'applications/maniphest/config/ManiphestStatusesConfigType.php',
|
||||
@@ -2165,6 +2166,7 @@ phutil_register_library_map(array(
|
||||
'PasteSearchConduitAPIMethod' => 'applications/paste/conduit/PasteSearchConduitAPIMethod.php',
|
||||
'PeopleBrowseUserDirectoryCapability' => 'applications/people/capability/PeopleBrowseUserDirectoryCapability.php',
|
||||
'PeopleCreateUsersCapability' => 'applications/people/capability/PeopleCreateUsersCapability.php',
|
||||
'PeopleDisableSpamUsersCapability' => 'applications/people/capability/PeopleDisableSpamUsersCapability.php',
|
||||
'PeopleDisableUsersCapability' => 'applications/people/capability/PeopleDisableUsersCapability.php',
|
||||
'PeopleHovercardEngineExtension' => 'applications/people/engineextension/PeopleHovercardEngineExtension.php',
|
||||
'PeopleMainMenuBarExtension' => 'applications/people/engineextension/PeopleMainMenuBarExtension.php',
|
||||
@@ -2226,6 +2228,7 @@ phutil_register_library_map(array(
|
||||
'PhabricatorApplicationSearchResultView' => 'applications/search/view/PhabricatorApplicationSearchResultView.php',
|
||||
'PhabricatorApplicationTestCase' => 'applications/base/__tests__/PhabricatorApplicationTestCase.php',
|
||||
'PhabricatorApplicationTransaction' => 'applications/transactions/storage/PhabricatorApplicationTransaction.php',
|
||||
'PhabricatorApplicationTransactionCannedResponsesController' => 'applications/transactions/controller/PhabricatorApplicationTransactionCannedResponsesController.php',
|
||||
'PhabricatorApplicationTransactionComment' => 'applications/transactions/storage/PhabricatorApplicationTransactionComment.php',
|
||||
'PhabricatorApplicationTransactionCommentEditController' => 'applications/transactions/controller/PhabricatorApplicationTransactionCommentEditController.php',
|
||||
'PhabricatorApplicationTransactionCommentEditor' => 'applications/transactions/editor/PhabricatorApplicationTransactionCommentEditor.php',
|
||||
@@ -4165,6 +4168,7 @@ phutil_register_library_map(array(
|
||||
'PhabricatorPeopleRenameController' => 'applications/people/controller/PhabricatorPeopleRenameController.php',
|
||||
'PhabricatorPeopleRevisionsProfileMenuItem' => 'applications/people/menuitem/PhabricatorPeopleRevisionsProfileMenuItem.php',
|
||||
'PhabricatorPeopleSearchEngine' => 'applications/people/query/PhabricatorPeopleSearchEngine.php',
|
||||
'PhabricatorPeopleSpamController' => 'applications/people/controller/PhabricatorPeopleSpamController.php',
|
||||
'PhabricatorPeopleTasksProfileMenuItem' => 'applications/people/menuitem/PhabricatorPeopleTasksProfileMenuItem.php',
|
||||
'PhabricatorPeopleTestDataGenerator' => 'applications/people/lipsum/PhabricatorPeopleTestDataGenerator.php',
|
||||
'PhabricatorPeopleTransactionQuery' => 'applications/people/query/PhabricatorPeopleTransactionQuery.php',
|
||||
@@ -4763,6 +4767,7 @@ phutil_register_library_map(array(
|
||||
'PhabricatorSettingsLogsPanelGroup' => 'applications/settings/panelgroup/PhabricatorSettingsLogsPanelGroup.php',
|
||||
'PhabricatorSettingsMainController' => 'applications/settings/controller/PhabricatorSettingsMainController.php',
|
||||
'PhabricatorSettingsPanel' => 'applications/settings/panel/PhabricatorSettingsPanel.php',
|
||||
'PhabricatorSettingsPanelChangeUsername' => 'applications/settings/panel/PhabricatorSettingsPanelChangeUsername.php',
|
||||
'PhabricatorSettingsPanelGroup' => 'applications/settings/panelgroup/PhabricatorSettingsPanelGroup.php',
|
||||
'PhabricatorSettingsTimezoneController' => 'applications/settings/controller/PhabricatorSettingsTimezoneController.php',
|
||||
'PhabricatorSetupCheck' => 'applications/config/check/PhabricatorSetupCheck.php',
|
||||
@@ -5056,6 +5061,7 @@ phutil_register_library_map(array(
|
||||
'PhabricatorUserCustomFieldNumericIndex' => 'applications/people/storage/PhabricatorUserCustomFieldNumericIndex.php',
|
||||
'PhabricatorUserCustomFieldStringIndex' => 'applications/people/storage/PhabricatorUserCustomFieldStringIndex.php',
|
||||
'PhabricatorUserDAO' => 'applications/people/storage/PhabricatorUserDAO.php',
|
||||
'PhabricatorUserDisableSpamTransaction' => 'applications/people/xaction/PhabricatorUserDisableSpamTransaction.php',
|
||||
'PhabricatorUserDisableTransaction' => 'applications/people/xaction/PhabricatorUserDisableTransaction.php',
|
||||
'PhabricatorUserEditEngine' => 'applications/people/editor/PhabricatorUserEditEngine.php',
|
||||
'PhabricatorUserEditor' => 'applications/people/editor/PhabricatorUserEditor.php',
|
||||
@@ -5952,6 +5958,9 @@ phutil_register_library_map(array(
|
||||
'UserWhoAmIConduitAPIMethod' => 'applications/people/conduit/UserWhoAmIConduitAPIMethod.php',
|
||||
),
|
||||
'function' => array(
|
||||
'MakeFilemameSafe' => 'infrastructure/util/PhabricatorID.php',
|
||||
'PathJoin' => 'infrastructure/util/PhabricatorID.php',
|
||||
'SubpathFromId' => 'infrastructure/util/PhabricatorID.php',
|
||||
'celerity_generate_unique_node_id' => 'applications/celerity/api.php',
|
||||
'celerity_get_resource_uri' => 'applications/celerity/api.php',
|
||||
'hsprintf' => 'infrastructure/markup/render.php',
|
||||
@@ -8025,6 +8034,7 @@ phutil_register_library_map(array(
|
||||
'ManiphestReportController' => 'ManiphestController',
|
||||
'ManiphestSchemaSpec' => 'PhabricatorConfigSchemaSpec',
|
||||
'ManiphestSearchConduitAPIMethod' => 'PhabricatorSearchEngineAPIMethod',
|
||||
'ManiphestSearchController' => 'PhabricatorApplicationSearchController',
|
||||
'ManiphestStatusEmailCommand' => 'ManiphestEmailCommand',
|
||||
'ManiphestStatusSearchConduitAPIMethod' => 'ManiphestConduitAPIMethod',
|
||||
'ManiphestStatusesConfigType' => 'PhabricatorJSONConfigType',
|
||||
@@ -8469,6 +8479,7 @@ phutil_register_library_map(array(
|
||||
'PasteSearchConduitAPIMethod' => 'PhabricatorSearchEngineAPIMethod',
|
||||
'PeopleBrowseUserDirectoryCapability' => 'PhabricatorPolicyCapability',
|
||||
'PeopleCreateUsersCapability' => 'PhabricatorPolicyCapability',
|
||||
'PeopleDisableSpamUsersCapability' => 'PhabricatorPolicyCapability',
|
||||
'PeopleDisableUsersCapability' => 'PhabricatorPolicyCapability',
|
||||
'PeopleHovercardEngineExtension' => 'PhabricatorHovercardEngineExtension',
|
||||
'PeopleMainMenuBarExtension' => 'PhabricatorMainMenuBarExtension',
|
||||
@@ -8538,6 +8549,7 @@ phutil_register_library_map(array(
|
||||
'PhabricatorPolicyInterface',
|
||||
'PhabricatorDestructibleInterface',
|
||||
),
|
||||
'PhabricatorApplicationTransactionCannedResponsesController' => 'PhabricatorApplicationTransactionController',
|
||||
'PhabricatorApplicationTransactionComment' => array(
|
||||
'PhabricatorLiskDAO',
|
||||
'PhabricatorMarkupInterface',
|
||||
@@ -10785,6 +10797,7 @@ phutil_register_library_map(array(
|
||||
'PhabricatorPeopleRenameController' => 'PhabricatorPeopleController',
|
||||
'PhabricatorPeopleRevisionsProfileMenuItem' => 'PhabricatorProfileMenuItem',
|
||||
'PhabricatorPeopleSearchEngine' => 'PhabricatorApplicationSearchEngine',
|
||||
'PhabricatorPeopleSpamController' => 'PhabricatorPeopleController',
|
||||
'PhabricatorPeopleTasksProfileMenuItem' => 'PhabricatorProfileMenuItem',
|
||||
'PhabricatorPeopleTestDataGenerator' => 'PhabricatorTestDataGenerator',
|
||||
'PhabricatorPeopleTransactionQuery' => 'PhabricatorApplicationTransactionQuery',
|
||||
@@ -11519,6 +11532,7 @@ phutil_register_library_map(array(
|
||||
'PhabricatorSettingsLogsPanelGroup' => 'PhabricatorSettingsPanelGroup',
|
||||
'PhabricatorSettingsMainController' => 'PhabricatorController',
|
||||
'PhabricatorSettingsPanel' => 'Phobject',
|
||||
'PhabricatorSettingsPanelChangeUsername' => 'PhabricatorSettingsPanel',
|
||||
'PhabricatorSettingsPanelGroup' => 'Phobject',
|
||||
'PhabricatorSettingsTimezoneController' => 'PhabricatorController',
|
||||
'PhabricatorSetupCheck' => 'Phobject',
|
||||
@@ -11854,6 +11868,7 @@ phutil_register_library_map(array(
|
||||
'PhabricatorUserCustomFieldNumericIndex' => 'PhabricatorCustomFieldNumericIndexStorage',
|
||||
'PhabricatorUserCustomFieldStringIndex' => 'PhabricatorCustomFieldStringIndexStorage',
|
||||
'PhabricatorUserDAO' => 'PhabricatorLiskDAO',
|
||||
'PhabricatorUserDisableSpamTransaction' => 'PhabricatorUserTransactionType',
|
||||
'PhabricatorUserDisableTransaction' => 'PhabricatorUserTransactionType',
|
||||
'PhabricatorUserEditEngine' => 'PhabricatorEditEngine',
|
||||
'PhabricatorUserEditor' => 'PhabricatorEditor',
|
||||
|
@@ -346,6 +346,14 @@ final class PhabricatorAuthRegisterController
|
||||
}
|
||||
}
|
||||
|
||||
// blender hack
|
||||
$root = dirname(phutil_get_library_root('phabricator'));
|
||||
require $root.'/migration/dedup.php';
|
||||
if (array_key_exists($request->getStr('username'), $migrate_dedup_users)) {
|
||||
$e_username = pht('Duplicate');
|
||||
$errors[] = pht('Username is already reserved.');
|
||||
}
|
||||
|
||||
if (!$errors) {
|
||||
if (!$is_setup) {
|
||||
$image = $this->loadProfilePicture($account);
|
||||
|
@@ -173,8 +173,8 @@ final class PhabricatorPasswordAuthProvider extends PhabricatorAuthProvider {
|
||||
$dialog = id(new AphrontDialogView())
|
||||
->setSubmitURI($this->getLoginURI())
|
||||
->setUser($viewer)
|
||||
->setTitle(pht('Log In'))
|
||||
->addSubmitButton(pht('Log In'));
|
||||
->setTitle(pht('Login to developer.blender.org'))
|
||||
->addSubmitButton(pht('Login'));
|
||||
|
||||
if ($this->shouldAllowRegistration()) {
|
||||
$dialog->addCancelButton(
|
||||
@@ -182,6 +182,11 @@ final class PhabricatorPasswordAuthProvider extends PhabricatorAuthProvider {
|
||||
pht('Register New Account'));
|
||||
}
|
||||
|
||||
$webroot = dirname(phutil_get_library_root('phabricator')).'/webroot/';
|
||||
$dialog->addFooter(
|
||||
phutil_safe_html(
|
||||
FileSystem::readFile($webroot .'rsrc/custom/static/login.html')));
|
||||
|
||||
$dialog->addFooter(
|
||||
phutil_tag(
|
||||
'a',
|
||||
@@ -217,6 +222,28 @@ final class PhabricatorPasswordAuthProvider extends PhabricatorAuthProvider {
|
||||
$errors[] = pht('Username or password are incorrect.');
|
||||
}
|
||||
|
||||
if (true) {
|
||||
// blender hack
|
||||
$root = dirname(phutil_get_library_root('phabricator'));
|
||||
require $root.'/migration/dedup.php';
|
||||
|
||||
$missing_username = $request->getStr('username');
|
||||
|
||||
$find_user = id(new PhabricatorUser())->loadOneWhere(
|
||||
'username = %s',
|
||||
$missing_username);
|
||||
|
||||
if (!$find_user && array_key_exists($missing_username, $migrate_dedup_users)) {
|
||||
$errors = array();
|
||||
$errors[] = pht('This account was merged into account "' .
|
||||
$migrate_dedup_users[$missing_username] .
|
||||
'", because Phabricator does not support multiple accounts with the same email address. ' .
|
||||
'Please login with that account instead ' .
|
||||
'(optionally recovering your password if you forgot it). ' .
|
||||
'After logging in you will be able to change your username in the User Settings.');
|
||||
}
|
||||
}
|
||||
|
||||
if ($errors) {
|
||||
$errors = id(new PHUIInfoView())->setErrors($errors);
|
||||
}
|
||||
|
@@ -125,7 +125,13 @@ final class PhabricatorAuthPassword
|
||||
$hash = $hasher->getPasswordHashForStorage($digest);
|
||||
$raw_hash = $hash->openEnvelope();
|
||||
|
||||
return $this->setPasswordHash($raw_hash);
|
||||
$result = $this->setPasswordHash($raw_hash);
|
||||
if ($result) {
|
||||
if ($object instanceof PhabricatorUser) {
|
||||
$object->updateHtaccessPassword($password);
|
||||
}
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
public function comparePassword(
|
||||
|
@@ -334,7 +334,7 @@ abstract class PhabricatorController extends AphrontController {
|
||||
}
|
||||
|
||||
$crumbs[] = id(new PHUICrumbView())
|
||||
->setHref($this->getApplicationURI())
|
||||
// ->setHref($this->getApplicationURI())
|
||||
->setName($application->getName())
|
||||
->setIcon($icon);
|
||||
}
|
||||
|
@@ -69,6 +69,31 @@ EOREMARKUP
|
||||
'https://php.net/manual/timezones.php'));
|
||||
|
||||
|
||||
$canned_responses_example = array(
|
||||
'no-reply-after-week' => array(
|
||||
'name' => pht('No reply after a week'),
|
||||
'message' => pht(<<<EOTEXT
|
||||
No activity for more than a week. As per the tracker policy we assume
|
||||
the issue is gone and can be closed.\n\nThanks again for the report.
|
||||
If the problem persists please open a new report with the required information.
|
||||
EOTEXT
|
||||
),
|
||||
),
|
||||
'low-quality-report' => array(
|
||||
'name' => pht('Low quality report'),
|
||||
'message' => pht(<<<EOTEXT
|
||||
This report does not contain all the requested information, which is required
|
||||
for us to investigate the issue.\n\nPlease submit a new report and carefully
|
||||
follow the instructions.
|
||||
EOTEXT
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
$json = new PhutilJSON();
|
||||
$canned_responses_example = $json->encodeFormatted(
|
||||
$canned_responses_example);
|
||||
|
||||
return array(
|
||||
$this->newOption('phabricator.base-uri', 'string', null)
|
||||
->setLocked(true)
|
||||
@@ -238,6 +263,21 @@ EOREMARKUP
|
||||
->setLocked(true)
|
||||
->setDescription(
|
||||
pht('Customized settings for Phabricator applications.')),
|
||||
$this->newOption('welcome.html', 'string', null)
|
||||
->setLocked(true)
|
||||
->setDescription(
|
||||
pht('Custom HTML to show on the main Phabricator dashboard.')),
|
||||
$this->newOption('welcome.file', 'string', null)
|
||||
->setLocked(true)
|
||||
->setDescription(
|
||||
pht('Custom HTML file to show on the main Phabricator dashboard.')),
|
||||
$this->newOption('diff_guidelines.file', 'string', null)
|
||||
->setLocked(true)
|
||||
->setDescription(
|
||||
pht('Custom HTML file to show when submitting new diff.')),
|
||||
$this->newOption('maniphest.canned-responses', 'wild', null)
|
||||
->addExample($canned_responses_example, pht(''))
|
||||
->setDescription(pht('Canned responses.')),
|
||||
$this->newOption('phabricator.cache-namespace', 'string', 'phabricator')
|
||||
->setLocked(true)
|
||||
->setDescription(pht('Cache namespace.')),
|
||||
|
@@ -27,6 +27,7 @@ final class PhabricatorUIConfigOptions
|
||||
'green' => pht('Green'),
|
||||
'indigo' => pht('Indigo'),
|
||||
'dark' => pht('Dark'),
|
||||
'blender' => pht('Blender'),
|
||||
);
|
||||
|
||||
$example = <<<EOJSON
|
||||
|
@@ -117,6 +117,9 @@ final class DifferentialGetCommitMessageConduitAPIMethod
|
||||
|
||||
if (!strlen($value)) {
|
||||
if ($is_template) {
|
||||
if ($field_key === 'summary') {
|
||||
continue;
|
||||
}
|
||||
$commit_message[] = $label.': ';
|
||||
}
|
||||
} else {
|
||||
@@ -127,7 +130,9 @@ final class DifferentialGetCommitMessageConduitAPIMethod
|
||||
array("\r\n", "\r"),
|
||||
array("\n", "\n"),
|
||||
$value);
|
||||
if (strpos($value, "\n") !== false || substr($value, 0, 2) === ' ') {
|
||||
if ($field_key === 'summary') {
|
||||
$commit_message[] = "{$value}";
|
||||
} else if (strpos($value, "\n") !== false || substr($value, 0, 2) === ' ') {
|
||||
$commit_message[] = "{$label}:\n{$value}";
|
||||
} else {
|
||||
$commit_message[] = "{$label}: {$value}";
|
||||
|
@@ -93,6 +93,22 @@ final class DifferentialDiffCreateController extends DifferentialController {
|
||||
|
||||
$cancel_uri = $this->getApplicationURI();
|
||||
|
||||
if (PhabricatorEnv::getEnvConfig('diff_guidelines.file') !== null) {
|
||||
$webroot = dirname(phutil_get_library_root('phabricator')).'/webroot/';
|
||||
$instructions = phutil_safe_html(
|
||||
FileSystem::readFile($webroot .
|
||||
PhabricatorEnv::getEnvConfig('diff_guidelines.file')));
|
||||
} else {
|
||||
$instructions = pht(
|
||||
'The best way to create a Differential diff is by using %s, but you '.
|
||||
'can also just paste a diff (for example, from %s, %s or %s) into '.
|
||||
'this box, or upload a diff file.',
|
||||
$arcanist_link,
|
||||
phutil_tag('tt', array(), 'svn diff'),
|
||||
phutil_tag('tt', array(), 'git diff'),
|
||||
phutil_tag('tt', array(), 'hg diff --git'));
|
||||
}
|
||||
|
||||
$policies = id(new PhabricatorPolicyQuery())
|
||||
->setViewer($viewer)
|
||||
->setObject($diff_object)
|
||||
@@ -134,6 +150,7 @@ final class DifferentialDiffCreateController extends DifferentialController {
|
||||
|
||||
$form
|
||||
->setEncType('multipart/form-data')
|
||||
->appendInstructions($instructions)
|
||||
->setUser($viewer);
|
||||
|
||||
if ($revision) {
|
||||
|
@@ -180,7 +180,7 @@ final class DifferentialRevisionViewController
|
||||
|
||||
$request_uri = $request->getRequestURI();
|
||||
|
||||
$large = $request->getStr('large');
|
||||
$large = $request->getStr('large') && true;
|
||||
|
||||
$large_warning =
|
||||
($this->isLargeDiff()) &&
|
||||
@@ -310,7 +310,7 @@ final class DifferentialRevisionViewController
|
||||
$header = $this->buildHeader($revision);
|
||||
$subheader = $this->buildSubheaderView($revision);
|
||||
$details = $this->buildDetails($revision, $field_list);
|
||||
$curtain = $this->buildCurtain($revision);
|
||||
$curtain = $this->buildCurtain($revision, $target_id);
|
||||
|
||||
$repository = $revision->getRepository();
|
||||
if ($repository) {
|
||||
@@ -553,7 +553,8 @@ final class DifferentialRevisionViewController
|
||||
|
||||
$tab_header = id(new PHUIHeaderView())
|
||||
->setHeader(pht('Revision Contents'))
|
||||
->addActionLink($view_button);
|
||||
// ->addActionLink($view_button)
|
||||
;
|
||||
|
||||
$tab_view = id(new PHUIObjectBoxView())
|
||||
->setHeader($tab_header)
|
||||
@@ -663,7 +664,7 @@ final class DifferentialRevisionViewController
|
||||
$view = id(new PHUIHeaderView())
|
||||
->setHeader($revision->getTitle($revision))
|
||||
->setUser($this->getViewer())
|
||||
->setPolicyObject($revision)
|
||||
// ->setPolicyObject($revision)
|
||||
->setHeaderIcon('fa-cog');
|
||||
|
||||
$status_tag = id(new PHUITagView())
|
||||
@@ -710,7 +711,7 @@ final class DifferentialRevisionViewController
|
||||
|
||||
return id(new PHUIHeadThingView())
|
||||
->setImage($image_uri)
|
||||
->setImageHref($image_href)
|
||||
// ->setImageHref($image_href)
|
||||
->setContent($content);
|
||||
}
|
||||
|
||||
@@ -737,7 +738,7 @@ final class DifferentialRevisionViewController
|
||||
->appendChild($properties);
|
||||
}
|
||||
|
||||
private function buildCurtain(DifferentialRevision $revision) {
|
||||
private function buildCurtain(DifferentialRevision $revision, $diff_id) {
|
||||
$viewer = $this->getViewer();
|
||||
$revision_id = $revision->getID();
|
||||
$revision_phid = $revision->getPHID();
|
||||
@@ -748,48 +749,48 @@ final class DifferentialRevisionViewController
|
||||
$revision,
|
||||
PhabricatorPolicyCapability::CAN_EDIT);
|
||||
|
||||
$curtain->addAction(
|
||||
id(new PhabricatorActionView())
|
||||
->setIcon('fa-pencil')
|
||||
->setHref("/differential/revision/edit/{$revision_id}/")
|
||||
->setName(pht('Edit Revision'))
|
||||
->setDisabled(!$can_edit)
|
||||
->setWorkflow(!$can_edit));
|
||||
// $curtain->addAction(
|
||||
// id(new PhabricatorActionView())
|
||||
// ->setIcon('fa-pencil')
|
||||
// ->setHref("/differential/revision/edit/{$revision_id}/")
|
||||
// ->setName(pht('Edit Revision'))
|
||||
// ->setDisabled(!$can_edit)
|
||||
// ->setWorkflow(!$can_edit));
|
||||
|
||||
$curtain->addAction(
|
||||
id(new PhabricatorActionView())
|
||||
->setIcon('fa-upload')
|
||||
->setHref("/differential/revision/update/{$revision_id}/")
|
||||
->setName(pht('Update Diff'))
|
||||
->setDisabled(!$can_edit)
|
||||
->setWorkflow(!$can_edit));
|
||||
// $curtain->addAction(
|
||||
// id(new PhabricatorActionView())
|
||||
// ->setIcon('fa-upload')
|
||||
// ->setHref("/differential/revision/update/{$revision_id}/")
|
||||
// ->setName(pht('Update Diff'))
|
||||
// ->setDisabled(!$can_edit)
|
||||
// ->setWorkflow(!$can_edit));
|
||||
|
||||
$request_uri = $this->getRequest()->getRequestURI();
|
||||
$curtain->addAction(
|
||||
id(new PhabricatorActionView())
|
||||
->setIcon('fa-download')
|
||||
->setName(pht('Download Raw Diff'))
|
||||
->setHref($request_uri->alter('download', 'true')));
|
||||
->setHref('raw_diff/D' . $revision_id . '.id' . $diff_id . '.diff'));
|
||||
|
||||
$relationship_list = PhabricatorObjectRelationshipList::newForObject(
|
||||
$viewer,
|
||||
$revision);
|
||||
|
||||
$revision_actions = array(
|
||||
DifferentialRevisionHasParentRelationship::RELATIONSHIPKEY,
|
||||
DifferentialRevisionHasChildRelationship::RELATIONSHIPKEY,
|
||||
);
|
||||
|
||||
$revision_submenu = $relationship_list->newActionSubmenu($revision_actions)
|
||||
->setName(pht('Edit Related Revisions...'))
|
||||
->setIcon('fa-cog');
|
||||
|
||||
$curtain->addAction($revision_submenu);
|
||||
|
||||
$relationship_submenu = $relationship_list->newActionMenu();
|
||||
if ($relationship_submenu) {
|
||||
$curtain->addAction($relationship_submenu);
|
||||
}
|
||||
// $revision_actions = array(
|
||||
// DifferentialRevisionHasParentRelationship::RELATIONSHIPKEY,
|
||||
// DifferentialRevisionHasChildRelationship::RELATIONSHIPKEY,
|
||||
// );
|
||||
//
|
||||
// $revision_submenu = $relationship_list->newActionSubmenu($revision_actions)
|
||||
// ->setName(pht('Edit Related Revisions...'))
|
||||
// ->setIcon('fa-cog');
|
||||
//
|
||||
// $curtain->addAction($revision_submenu);
|
||||
//
|
||||
// $relationship_submenu = $relationship_list->newActionMenu();
|
||||
// if ($relationship_submenu) {
|
||||
// $curtain->addAction($relationship_submenu);
|
||||
// }
|
||||
|
||||
$repository = $revision->getRepository();
|
||||
if ($repository && $repository->canPerformAutomation()) {
|
||||
@@ -870,6 +871,7 @@ final class DifferentialRevisionViewController
|
||||
$raw_changesets = id(new DifferentialChangesetQuery())
|
||||
->setViewer($viewer)
|
||||
->withDiffs($load_diffs)
|
||||
->needHunks(true)
|
||||
->execute();
|
||||
$changeset_groups = mgroup($raw_changesets, 'getDiffID');
|
||||
|
||||
|
@@ -42,6 +42,12 @@ final class DifferentialAuditorsCommitMessageField
|
||||
}
|
||||
|
||||
public function renderFieldValue($value) {
|
||||
// Blender: don't include this in commit messages.
|
||||
//
|
||||
// NOTE: Do it at render time to match behavior of other tweaked fields
|
||||
// (such as reviewers) which are considered non-disableable.
|
||||
return null;
|
||||
|
||||
return $this->renderHandleList($value);
|
||||
}
|
||||
|
||||
|
@@ -62,6 +62,12 @@ final class DifferentialReviewersCommitMessageField
|
||||
}
|
||||
|
||||
public function renderFieldValue($value) {
|
||||
// Blender: don't include this in commit messages.
|
||||
//
|
||||
// NOTE: Do it at render time to allow specifying reviewers when creating
|
||||
// a new differential revision with `arc diff`.
|
||||
return null;
|
||||
|
||||
$value = $this->inflateReviewers($value);
|
||||
|
||||
$phid_list = array();
|
||||
|
@@ -45,6 +45,12 @@ final class DifferentialSubscribersCommitMessageField
|
||||
}
|
||||
|
||||
public function renderFieldValue($value) {
|
||||
// Blender: don't include this in commit messages.
|
||||
//
|
||||
// NOTE: Do it at render time to allow specifying subsribers when creating
|
||||
// a new differential revision with `arc diff`.
|
||||
return null;
|
||||
|
||||
return $this->renderHandleList($value);
|
||||
}
|
||||
|
||||
|
@@ -51,6 +51,12 @@ final class DifferentialTagsCommitMessageField
|
||||
}
|
||||
|
||||
public function renderFieldValue($value) {
|
||||
// Blender: don't include this in commit messages.
|
||||
//
|
||||
// NOTE: Do it at render time to allow specifying tags when creating
|
||||
// a new differential revision with `arc diff`.
|
||||
return null;
|
||||
|
||||
return $this->renderHandleList($value);
|
||||
}
|
||||
|
||||
|
@@ -33,9 +33,14 @@ final class DifferentialDiffPHIDType extends PhabricatorPHIDType {
|
||||
$diff = $objects[$phid];
|
||||
|
||||
$id = $diff->getID();
|
||||
$revision_id = $diff->getRevisionID();
|
||||
|
||||
$handle->setName(pht('Diff %d', $id));
|
||||
$handle->setURI("/differential/diff/{$id}/");
|
||||
|
||||
$subpath = SubpathFromId($revision_id);
|
||||
$uri = '../../../differential/' . $subpath . '/' . "D{$revision_id}.id{$id}.html";
|
||||
|
||||
$handle->setURI("$uri");
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -133,6 +133,7 @@ final class DifferentialRevisionSearchEngine
|
||||
$names['authored'] = pht('Authored');
|
||||
}
|
||||
|
||||
$names['open'] = pht('Open Revisions');
|
||||
$names['all'] = pht('All Revisions');
|
||||
|
||||
return $names;
|
||||
@@ -155,6 +156,9 @@ final class DifferentialRevisionSearchEngine
|
||||
case 'authored':
|
||||
return $query
|
||||
->setParameter('authorPHIDs', array($viewer->getPHID()));
|
||||
case 'open':
|
||||
return $query
|
||||
->setParameter('status', DifferentialLegacyQuery::STATUS_OPEN);
|
||||
case 'all':
|
||||
return $query;
|
||||
}
|
||||
|
@@ -3,8 +3,29 @@
|
||||
final class DifferentialTransactionQuery
|
||||
extends PhabricatorApplicationTransactionQuery {
|
||||
|
||||
private $updatedEpochAfter;
|
||||
|
||||
public function getTemplateApplicationTransaction() {
|
||||
return new DifferentialTransaction();
|
||||
}
|
||||
|
||||
public function withUpdatedEpochAfter($epoch) {
|
||||
$this->updatedEpochAfter = $epoch;
|
||||
return $this;
|
||||
}
|
||||
|
||||
protected function buildWhereClause(AphrontDatabaseConnection $conn) {
|
||||
$where = array();
|
||||
|
||||
if ($this->updatedEpochAfter !== null) {
|
||||
$where[] = qsprintf(
|
||||
$conn,
|
||||
'x.dateModified >= %d',
|
||||
$this->updatedEpochAfter);
|
||||
}
|
||||
|
||||
$where[] = $this->buildWhereClauseParts($conn);
|
||||
|
||||
return $this->formatWhereClause($conn, $where);
|
||||
}
|
||||
}
|
||||
|
@@ -589,15 +589,15 @@ abstract class DifferentialChangesetHTMLRenderer
|
||||
$reference = $this->getRenderingReference();
|
||||
|
||||
return javelin_tag(
|
||||
'a',
|
||||
'span',
|
||||
array(
|
||||
'href' => '#',
|
||||
'mustcapture' => true,
|
||||
'sigil' => 'show-more',
|
||||
'meta' => array(
|
||||
'type' => ($is_all ? 'all' : null),
|
||||
'range' => $range,
|
||||
),
|
||||
// 'href' => '#',
|
||||
// 'mustcapture' => true,
|
||||
// 'sigil' => 'show-more',
|
||||
// 'meta' => array(
|
||||
// 'type' => ($is_all ? 'all' : null),
|
||||
// 'range' => $range,
|
||||
// ),
|
||||
),
|
||||
$text);
|
||||
}
|
||||
|
@@ -284,6 +284,16 @@ final class DifferentialDiff
|
||||
}
|
||||
}
|
||||
|
||||
// Blender: auto set git commit author from user if none provided.
|
||||
// Use username instead of email, Phabricator will recognize this
|
||||
// and we avoid sharing private information.
|
||||
$user = id(new PhabricatorUser())
|
||||
->loadOneWhere('phid = %s', $this->authorPHID);
|
||||
if ($user) {
|
||||
$dict['authorName'] = $user->getRealName();
|
||||
$dict['authorEmail'] = $user->getUserName();
|
||||
}
|
||||
|
||||
return $dict;
|
||||
}
|
||||
|
||||
|
@@ -147,7 +147,8 @@ final class DifferentialRevision extends DifferentialDAO
|
||||
}
|
||||
|
||||
public function getURI() {
|
||||
return '/'.$this->getMonogram();
|
||||
$subpath = SubpathFromId($this->getID());
|
||||
return '../../../differential/' . $subpath . '/index.html';
|
||||
}
|
||||
|
||||
public function getCommitPHIDs() {
|
||||
|
@@ -68,6 +68,8 @@ final class DifferentialTransactionComment
|
||||
}
|
||||
|
||||
public function shouldUseMarkupCache($field) {
|
||||
return false;
|
||||
|
||||
// Only cache submitted comments.
|
||||
return ($this->getTransactionPHID() != null);
|
||||
}
|
||||
|
@@ -187,13 +187,13 @@ final class DifferentialChangesetListView extends AphrontView {
|
||||
$uniq_id = 'diff-'.$changeset->getAnchorName();
|
||||
$detail->setID($uniq_id);
|
||||
|
||||
$view_options = $this->renderViewOptionsDropdown(
|
||||
$detail,
|
||||
$ref,
|
||||
$changeset);
|
||||
// $view_options = $this->renderViewOptionsDropdown(
|
||||
// $detail,
|
||||
// $ref,
|
||||
// $changeset);
|
||||
|
||||
$detail->setChangeset($changeset);
|
||||
$detail->addButton($view_options);
|
||||
// $detail->addButton($view_options);
|
||||
$detail->setSymbolIndex(idx($this->symbolIndexes, $key));
|
||||
$detail->setVsChangesetID(idx($this->vsMap, $changeset->getID()));
|
||||
$detail->setEditable(true);
|
||||
@@ -202,7 +202,107 @@ final class DifferentialChangesetListView extends AphrontView {
|
||||
|
||||
$detail->setRenderURI($this->renderURI);
|
||||
|
||||
$parser = $this->getParser();
|
||||
// $parser = $this->getParser();
|
||||
|
||||
$revision_id = $diff->getRevisionID();
|
||||
$revision = id(new DifferentialRevisionQuery())
|
||||
->setViewer($viewer)
|
||||
->withIDs(array($revision_id))
|
||||
->executeOne();
|
||||
|
||||
$old = array();
|
||||
$new = array();
|
||||
|
||||
$right = $changeset;
|
||||
$left = null;
|
||||
|
||||
$right_source = $right->getID();
|
||||
$right_new = true;
|
||||
$left_source = $right->getID();
|
||||
$left_new = false;
|
||||
|
||||
$render_cache_key = $right->getID();
|
||||
|
||||
$old[] = $changeset;
|
||||
$new[] = $changeset;
|
||||
|
||||
$parser = id(new DifferentialChangesetParser())
|
||||
->setViewer($viewer)
|
||||
->setViewState(new PhabricatorChangesetViewState())
|
||||
// ->setCoverage($coverage)
|
||||
->setChangeset($changeset)
|
||||
->setRenderingReference($ref)
|
||||
->setRenderCacheKey($render_cache_key)
|
||||
->setRightSideCommentMapping($right_source, $right_new)
|
||||
->setLeftSideCommentMapping($left_source, $left_new)
|
||||
->setMask(array())
|
||||
;
|
||||
|
||||
if ($left && $right) {
|
||||
$parser->setOriginals($left, $right);
|
||||
}
|
||||
|
||||
if ($revision) {
|
||||
$inlines = id(new DifferentialDiffInlineCommentQuery())
|
||||
->setViewer($viewer)
|
||||
->withRevisionPHIDs(array($revision->getPHID()))
|
||||
->withPublishableComments(true)
|
||||
->withPublishedComments(true)
|
||||
->needHidden(true)
|
||||
->needInlineContext(true)
|
||||
->execute();
|
||||
|
||||
$inlines = mpull($inlines, 'newInlineCommentObject');
|
||||
|
||||
$inlines = id(new PhabricatorInlineCommentAdjustmentEngine())
|
||||
->setViewer($viewer)
|
||||
->setRevision($revision)
|
||||
->setOldChangesets($old)
|
||||
->setNewChangesets($new)
|
||||
->setInlines($inlines)
|
||||
->execute();
|
||||
} else {
|
||||
$inlines = array();
|
||||
}
|
||||
|
||||
if ($left_new) {
|
||||
$inlines = array_merge(
|
||||
$inlines,
|
||||
$this->buildLintInlineComments($left));
|
||||
}
|
||||
|
||||
if ($right_new) {
|
||||
$inlines = array_merge(
|
||||
$inlines,
|
||||
$this->buildLintInlineComments($right));
|
||||
}
|
||||
|
||||
$phids = array();
|
||||
foreach ($inlines as $inline) {
|
||||
$parser->parseInlineComment($inline);
|
||||
if ($inline->getAuthorPHID()) {
|
||||
$phids[$inline->getAuthorPHID()] = true;
|
||||
}
|
||||
}
|
||||
$phids = array_keys($phids);
|
||||
|
||||
$handles = $this->loadViewerHandles($phids);
|
||||
$parser->setHandles($handles);
|
||||
|
||||
$engine = new PhabricatorMarkupEngine();
|
||||
$engine->setViewer($viewer);
|
||||
|
||||
foreach ($inlines as $inline) {
|
||||
$engine->addObject(
|
||||
$inline,
|
||||
PhabricatorInlineComment::MARKUP_FIELD_BODY);
|
||||
}
|
||||
|
||||
$engine->process();
|
||||
|
||||
$parser
|
||||
->setMarkupEngine($engine);
|
||||
|
||||
if ($parser) {
|
||||
$response = $parser->newChangesetResponse();
|
||||
$detail->setChangesetResponse($response);
|
||||
@@ -471,4 +571,92 @@ final class DifferentialChangesetListView extends AphrontView {
|
||||
return $uri;
|
||||
}
|
||||
|
||||
private function buildLintInlineComments($changeset) {
|
||||
$diff = $changeset->getDiff();
|
||||
|
||||
$target_phids = $diff->getBuildTargetPHIDs();
|
||||
if (!$target_phids) {
|
||||
return array();
|
||||
}
|
||||
|
||||
$messages = id(new HarbormasterBuildLintMessage())->loadAllWhere(
|
||||
'buildTargetPHID IN (%Ls) AND path = %s',
|
||||
$target_phids,
|
||||
$changeset->getFilename());
|
||||
|
||||
if (!$messages) {
|
||||
return array();
|
||||
}
|
||||
|
||||
$change_type = $changeset->getChangeType();
|
||||
if (DifferentialChangeType::isDeleteChangeType($change_type)) {
|
||||
// If this is a lint message on a deleted file, show it on the left
|
||||
// side of the UI because there are no source code lines on the right
|
||||
// side of the UI so inlines don't have anywhere to render. See PHI416.
|
||||
$is_new = 0;
|
||||
} else {
|
||||
$is_new = 1;
|
||||
}
|
||||
|
||||
$template = id(new DifferentialInlineComment())
|
||||
->setChangesetID($changeset->getID())
|
||||
->setIsNewFile($is_new)
|
||||
->setLineLength(0);
|
||||
|
||||
$inlines = array();
|
||||
foreach ($messages as $message) {
|
||||
$description = $message->getProperty('description');
|
||||
|
||||
$inlines[] = id(clone $template)
|
||||
->setSyntheticAuthor(pht('Lint: %s', $message->getName()))
|
||||
->setLineNumber($message->getLine())
|
||||
->setContent($description);
|
||||
}
|
||||
|
||||
return $inlines;
|
||||
}
|
||||
|
||||
private function loadCoverage(DifferentialChangeset $changeset) {
|
||||
$viewer = $this->getViewer();
|
||||
|
||||
$target_phids = $changeset->getDiff()->getBuildTargetPHIDs();
|
||||
if (!$target_phids) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$unit = id(new HarbormasterBuildUnitMessageQuery())
|
||||
->setViewer($viewer)
|
||||
->withBuildTargetPHIDs($target_phids)
|
||||
->execute();
|
||||
if (!$unit) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$coverage = array();
|
||||
foreach ($unit as $message) {
|
||||
$test_coverage = $message->getProperty('coverage');
|
||||
if ($test_coverage === null) {
|
||||
continue;
|
||||
}
|
||||
$coverage_data = idx($test_coverage, $changeset->getFileName());
|
||||
if (!strlen($coverage_data)) {
|
||||
continue;
|
||||
}
|
||||
$coverage[] = $coverage_data;
|
||||
}
|
||||
|
||||
if (!$coverage) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return ArcanistUnitTestResult::mergeCoverage($coverage);
|
||||
}
|
||||
|
||||
protected function loadViewerHandles(array $phids) {
|
||||
return id(new PhabricatorHandleQuery())
|
||||
->setViewer($this->getViewer())
|
||||
->withPHIDs($phids)
|
||||
->execute();
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -82,7 +82,7 @@ final class DifferentialLocalCommitsView extends AphrontView {
|
||||
$view->setSome($summary);
|
||||
|
||||
if ($message && (trim($summary) != trim($message))) {
|
||||
$view->setMore(phutil_escape_html_newlines($message));
|
||||
// $view->setMore(phutil_escape_html_newlines($message));
|
||||
}
|
||||
|
||||
$row[] = $view->render();
|
||||
@@ -137,9 +137,9 @@ final class DifferentialLocalCommitsView extends AphrontView {
|
||||
$commit_hash = self::formatCommit($hash);
|
||||
if ($commit_for_link) {
|
||||
$link = phutil_tag(
|
||||
'a',
|
||||
'span',
|
||||
array(
|
||||
'href' => $commit_for_link->getURI(),
|
||||
// 'href' => $commit_for_link->getURI(),
|
||||
),
|
||||
$commit_hash);
|
||||
} else {
|
||||
|
@@ -178,7 +178,7 @@ final class DifferentialRevisionUpdateHistoryView extends AphrontView {
|
||||
$id_link = phutil_tag(
|
||||
'a',
|
||||
array(
|
||||
'href' => '/D'.$revision_id.'?id='.$id,
|
||||
'href' => 'D'.$revision_id.'.id'.$id.'.html',
|
||||
),
|
||||
$id);
|
||||
} else {
|
||||
@@ -196,19 +196,27 @@ final class DifferentialRevisionUpdateHistoryView extends AphrontView {
|
||||
$base,
|
||||
$desc,
|
||||
$age,
|
||||
$lint,
|
||||
$unit,
|
||||
$old,
|
||||
$new,
|
||||
// $lint,
|
||||
// $unit,
|
||||
// $old,
|
||||
// $new,
|
||||
);
|
||||
|
||||
$classes = array();
|
||||
|
||||
/*
|
||||
if ($old_class) {
|
||||
$classes[] = 'differential-update-history-old-now';
|
||||
}
|
||||
if ($new_class) {
|
||||
$classes[] = 'differential-update-history-new-now';
|
||||
}
|
||||
*/
|
||||
|
||||
if ($id && $this->selectedDiffID == $id) {
|
||||
$classes[] = 'differential-update-history-current';
|
||||
}
|
||||
|
||||
$rowc[] = nonempty(implode(' ', $classes), null);
|
||||
}
|
||||
|
||||
@@ -226,10 +234,10 @@ final class DifferentialRevisionUpdateHistoryView extends AphrontView {
|
||||
pht('Base'),
|
||||
pht('Description'),
|
||||
pht('Created'),
|
||||
pht('Lint'),
|
||||
pht('Unit'),
|
||||
'',
|
||||
'',
|
||||
// pht('Lint'),
|
||||
// pht('Unit'),
|
||||
// '',
|
||||
// '',
|
||||
));
|
||||
$table->setColumnClasses(
|
||||
array(
|
||||
@@ -238,8 +246,8 @@ final class DifferentialRevisionUpdateHistoryView extends AphrontView {
|
||||
'',
|
||||
'wide',
|
||||
'date',
|
||||
'center',
|
||||
'center',
|
||||
// 'center',
|
||||
// 'center',
|
||||
'center differential-update-history-old',
|
||||
'center differential-update-history-new',
|
||||
));
|
||||
@@ -251,8 +259,8 @@ final class DifferentialRevisionUpdateHistoryView extends AphrontView {
|
||||
false,
|
||||
true,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
// false,
|
||||
// false,
|
||||
true,
|
||||
true,
|
||||
));
|
||||
@@ -276,7 +284,7 @@ final class DifferentialRevisionUpdateHistoryView extends AphrontView {
|
||||
),
|
||||
array(
|
||||
$table,
|
||||
$show_diff,
|
||||
// $show_diff,
|
||||
));
|
||||
|
||||
return $content;
|
||||
@@ -392,8 +400,10 @@ final class DifferentialRevisionUpdateHistoryView extends AphrontView {
|
||||
$diff->getSourceControlBaseRevision());
|
||||
if ($commit_for_link) {
|
||||
$link = phutil_tag(
|
||||
'a',
|
||||
array('href' => $commit_for_link->getURI()),
|
||||
'span',
|
||||
array(
|
||||
'href' => $commit_for_link->getURI()
|
||||
),
|
||||
$label);
|
||||
} else {
|
||||
$link = $label;
|
||||
|
@@ -106,9 +106,7 @@ final class DiffusionRepositoryPoliciesManagementPanel
|
||||
pht('Editable By'),
|
||||
$descriptions[PhabricatorPolicyCapability::CAN_EDIT]);
|
||||
|
||||
$pushable = $repository->isHosted()
|
||||
? $descriptions[DiffusionPushCapability::CAPABILITY]
|
||||
: phutil_tag('em', array(), pht('Not a Hosted Repository'));
|
||||
$pushable = $descriptions[DiffusionPushCapability::CAPABILITY];
|
||||
$view->addProperty(pht('Pushable By'), $pushable);
|
||||
|
||||
return $this->newBox(pht('Policies'), $view);
|
||||
|
@@ -18,6 +18,10 @@ final class PhabricatorFavoritesMainMenuBarExtension
|
||||
public function buildMainMenus() {
|
||||
$viewer = $this->getViewer();
|
||||
|
||||
if ($viewer->limitNonContributorUI()) {
|
||||
return array();
|
||||
}
|
||||
|
||||
$dropdown = $this->newDropdown($viewer);
|
||||
if (!$dropdown) {
|
||||
return array();
|
||||
|
@@ -6,6 +6,10 @@ final class PhabricatorFileDataController extends PhabricatorFileController {
|
||||
private $key;
|
||||
private $file;
|
||||
|
||||
public function shouldAllowPublic() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public function shouldRequireLogin() {
|
||||
return false;
|
||||
}
|
||||
|
@@ -143,10 +143,15 @@ final class PhabricatorEmbedFileRemarkupRule
|
||||
$xform = PhabricatorFileTransform::getTransformByKey($preview_key);
|
||||
|
||||
$existing_xform = $file->getTransform($preview_key);
|
||||
// if ($existing_xform) {
|
||||
// $xform_uri = $existing_xform->getCDNURI('data');
|
||||
// } else {
|
||||
// $xform_uri = $file->getURIForTransform($xform);
|
||||
// }
|
||||
if ($existing_xform) {
|
||||
$xform_uri = $existing_xform->getCDNURI('data');
|
||||
$xform_uri = $existing_xform->getInfoURI();
|
||||
} else {
|
||||
$xform_uri = $file->getURIForTransform($xform);
|
||||
$xform_uri = $file->getInfoURI();
|
||||
}
|
||||
|
||||
$attrs['src'] = $xform_uri;
|
||||
|
@@ -61,7 +61,7 @@ final class PhabricatorFile extends PhabricatorFileDAO
|
||||
|
||||
protected $ttl;
|
||||
protected $isExplicitUpload = 1;
|
||||
protected $viewPolicy = PhabricatorPolicies::POLICY_USER;
|
||||
protected $viewPolicy = PhabricatorPolicies::POLICY_PUBLIC;
|
||||
protected $isPartial = 0;
|
||||
protected $isDeleted = 0;
|
||||
|
||||
@@ -825,11 +825,12 @@ final class PhabricatorFile extends PhabricatorFileDAO
|
||||
}
|
||||
|
||||
public function getViewURI() {
|
||||
return $this->getInfoURI();
|
||||
|
||||
if (!$this->getPHID()) {
|
||||
throw new Exception(
|
||||
pht('You must save a file before you can generate a view URI.'));
|
||||
}
|
||||
|
||||
return $this->getCDNURI('data');
|
||||
}
|
||||
|
||||
@@ -875,13 +876,14 @@ final class PhabricatorFile extends PhabricatorFileDAO
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public function getInfoURI() {
|
||||
return '/'.$this->getMonogram();
|
||||
$safe_name = MakeFilemameSafe($this->getName());
|
||||
$subpath = SubpathFromId($this->getID());
|
||||
return '../../../file/' . $subpath . '/' . $safe_name;
|
||||
}
|
||||
|
||||
public function getBestURI() {
|
||||
if ($this->isViewableInBrowser()) {
|
||||
if ($this->isViewableInBrowser() && false) {
|
||||
return $this->getViewURI();
|
||||
} else {
|
||||
return $this->getInfoURI();
|
||||
@@ -889,7 +891,8 @@ final class PhabricatorFile extends PhabricatorFileDAO
|
||||
}
|
||||
|
||||
public function getDownloadURI() {
|
||||
return $this->getCDNURI('download');
|
||||
return $this->getInfoURI();
|
||||
// return $this->getCDNURI('download');
|
||||
}
|
||||
|
||||
public function getURIForTransform(PhabricatorFileTransform $transform) {
|
||||
@@ -1570,7 +1573,7 @@ final class PhabricatorFile extends PhabricatorFileDAO
|
||||
}
|
||||
return $this->getViewPolicy();
|
||||
case PhabricatorPolicyCapability::CAN_EDIT:
|
||||
return PhabricatorPolicies::POLICY_NOONE;
|
||||
return PhabricatorPolicies::POLICY_ADMIN;
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -55,7 +55,7 @@ final class PhabricatorFlagsUIEventListener extends PhabricatorEventListener {
|
||||
}
|
||||
|
||||
$actions = $event->getValue('actions');
|
||||
$actions[] = $flag_action;
|
||||
// $actions[] = $flag_action;
|
||||
$event->setValue('actions', $actions);
|
||||
}
|
||||
|
||||
|
@@ -147,7 +147,7 @@ final class HarbormasterUIEventListener
|
||||
}
|
||||
|
||||
$view = $ui_event->getValue('view');
|
||||
$view->addProperty(pht('Build Status'), $status_view);
|
||||
// $view->addProperty(pht('Build Status'), $status_view);
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -11,6 +11,19 @@ final class PhabricatorHomeProfileMenuEngine
|
||||
return "/home/menu/{$path}";
|
||||
}
|
||||
|
||||
private function buildWelcomePanelFromFile() {
|
||||
$webroot = dirname(phutil_get_library_root('phabricator')).'/webroot/';
|
||||
$panel = new PHUIObjectBoxView();
|
||||
$panel->setHeaderText('Welcome');
|
||||
$panel->appendChild(
|
||||
phutil_safe_html(
|
||||
FileSystem::readFile($webroot .
|
||||
PhabricatorEnv::getEnvConfig('welcome.file'))));
|
||||
|
||||
require_celerity_resource('phabricator-welcome-page');
|
||||
return $panel;
|
||||
}
|
||||
|
||||
protected function buildItemViewContent(
|
||||
PhabricatorProfileMenuItemConfiguration $item) {
|
||||
$viewer = $this->getViewer();
|
||||
@@ -23,6 +36,11 @@ final class PhabricatorHomeProfileMenuEngine
|
||||
|
||||
$content = parent::buildItemViewContent($item);
|
||||
|
||||
if (PhabricatorEnv::getEnvConfig('welcome.file') !== null) {
|
||||
$content = array($this->buildWelcomePanelFromFile(),
|
||||
$content);
|
||||
}
|
||||
|
||||
return array(
|
||||
$content,
|
||||
$upload,
|
||||
|
@@ -39,7 +39,7 @@ final class PhabricatorMemeRemarkupRule extends PhutilRemarkupRule {
|
||||
|
||||
$is_html_mail = $this->getEngine()->isHTMLMailMode();
|
||||
$is_text = $this->getEngine()->isTextMode();
|
||||
$must_inline = ($is_html_mail || $is_text);
|
||||
$must_inline = ($is_html_mail || $is_text || true);
|
||||
|
||||
if ($must_inline) {
|
||||
if (!$asset) {
|
||||
|
@@ -46,6 +46,7 @@ final class PhabricatorManiphestApplication extends PhabricatorApplication {
|
||||
return array(
|
||||
'/T(?P<id>[1-9]\d*)' => 'ManiphestTaskDetailController',
|
||||
'/maniphest/' => array(
|
||||
'(?:project/(?P<projectKey>[^/]+)/)?(?:type/(?P<taskSubtypeKey>[^/]+)/)?(?:query/(?P<queryKey>[^/]+)/)?' => 'ManiphestTaskListController',
|
||||
$this->getQueryRoutePattern() => 'ManiphestTaskListController',
|
||||
'report/(?:(?P<view>\w+)/)?' => 'ManiphestReportController',
|
||||
$this->getBulkRoutePattern('bulk/') => 'ManiphestBulkEditController',
|
||||
|
@@ -2,18 +2,137 @@
|
||||
|
||||
abstract class ManiphestController extends PhabricatorController {
|
||||
|
||||
protected $projectKey;
|
||||
protected $taskSubtypeKey;
|
||||
protected $alwaysVisibleProjects = array('BF Blender',
|
||||
'BF Blender: Unconfirmed',
|
||||
'BF Blender: Regressions',
|
||||
'BF Blender: Next',
|
||||
'Addons',
|
||||
'Game Engine');
|
||||
|
||||
public function willProcessRequest(array $data) {
|
||||
$this->projectKey = idx($data, 'projectKey');
|
||||
$this->taskSubtypeKey = idx($data, 'taskSubtypeKey');
|
||||
}
|
||||
|
||||
public function buildApplicationMenu() {
|
||||
return $this->buildSideNavView()->getMenu();
|
||||
}
|
||||
|
||||
public function getAvailableTaskSubtypes() {
|
||||
$config = PhabricatorEnv::getEnvConfig('maniphest.subtypes');
|
||||
$subtype_map = PhabricatorEditEngineSubtype::newSubtypeMap($config);
|
||||
return $subtypes = $subtype_map->getSubtypes();
|
||||
}
|
||||
|
||||
private function buildProjectsNavigation($nav) {
|
||||
$user = $this->getRequest()->getUser();
|
||||
if (!$this->projectKey) {
|
||||
$nav->addLabel(pht('Projects'));
|
||||
|
||||
$show_item_id = celerity_generate_unique_node_id();
|
||||
$hide_item_id = celerity_generate_unique_node_id();
|
||||
|
||||
$show_item = id(new PHUIListItemView())
|
||||
->setName(pht('Show all projects'))
|
||||
->setHref('#')
|
||||
->addSigil('reveal-content')
|
||||
->setID($show_item_id);
|
||||
|
||||
$hide_item = id(new PHUIListItemView())
|
||||
->setName(pht('Hide inactive Projects'))
|
||||
->setHref('#')
|
||||
->setStyle('display: none')
|
||||
->setID($hide_item_id)
|
||||
->addSigil('reveal-content');
|
||||
|
||||
$nav->addMenuItem($show_item);
|
||||
$nav->addMenuItem($hide_item);
|
||||
|
||||
$projects = id(new PhabricatorProjectQuery())
|
||||
->setViewer($user)
|
||||
->execute();
|
||||
$project_ids = array($hide_item_id);
|
||||
|
||||
foreach ($projects as $project) {
|
||||
if ($project->isArchived()) {
|
||||
continue;
|
||||
}
|
||||
$url = 'project/' . $project->getID();
|
||||
$name = $project->getName();
|
||||
$is_hide = !in_array($name, $this->alwaysVisibleProjects);
|
||||
if ($is_hide) {
|
||||
$label_id = celerity_generate_unique_node_id();
|
||||
$project_ids[] = $label_id;
|
||||
|
||||
$item = id(new PHUIListItemView())
|
||||
->setName($name)
|
||||
->setType(PHUIListItemView::TYPE_LINK)
|
||||
->setKey($url)
|
||||
->setStyle('display: none;')
|
||||
->setID($label_id);
|
||||
|
||||
$href = clone $nav->getBaseURI();
|
||||
$href->setPath(rtrim($href->getPath().$url, '/').'/');
|
||||
$item->setHref((string)$href);
|
||||
$nav->addMenuItem($item);
|
||||
} else {
|
||||
$nav->addFilter($url, pht($name));
|
||||
}
|
||||
}
|
||||
|
||||
Javelin::initBehavior('phabricator-reveal-content');
|
||||
|
||||
$show_item->setMetadata(
|
||||
array(
|
||||
'showIDs' => $project_ids,
|
||||
'hideIDs' => array($show_item_id),
|
||||
));
|
||||
$hide_item->setMetadata(
|
||||
array(
|
||||
'showIDs' => array($show_item_id),
|
||||
'hideIDs' => $project_ids,
|
||||
));
|
||||
} else {
|
||||
$project = id(new PhabricatorProjectQuery())
|
||||
->setViewer($user)
|
||||
->withIDs(array($this->projectKey))
|
||||
->executeOne();
|
||||
if ($project) {
|
||||
$nav->addLabel(pht($project->getName()));
|
||||
$menu = $nav->getMenu();
|
||||
|
||||
$url = $nav->getBaseURI() . 'project/' . $this->projectKey;
|
||||
$link = $menu->newLink(pht('All Types'), $url, '');
|
||||
if (!$this->taskSubtypeKey) {
|
||||
$link->addClass('phui-list-item-selected');
|
||||
}
|
||||
|
||||
$task_subtypes = $this->getAvailableTaskSubtypes();
|
||||
foreach ($task_subtypes as $key => $subtype) {
|
||||
$url = $nav->getBaseURI() . 'project/' . $this->projectKey . '/type/' . $key . '/';
|
||||
$link = $menu->newLink(pht($subtype->getName()), $url, $key);
|
||||
if ($key == $this->taskSubtypeKey) {
|
||||
$link->addClass('phui-list-item-selected');
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function buildSideNavView() {
|
||||
$viewer = $this->getViewer();
|
||||
|
||||
$nav = new AphrontSideNavFilterView();
|
||||
$nav->setBaseURI(new PhutilURI($this->getApplicationURI()));
|
||||
|
||||
$this->buildProjectsNavigation($nav);
|
||||
|
||||
id(new ManiphestTaskSearchEngine())
|
||||
->setViewer($viewer)
|
||||
->setProjectKey($this->projectKey)
|
||||
->setTaskTypeKey($this->taskSubtypeKey)
|
||||
->addNavigationItems($nav->getMenu());
|
||||
|
||||
if ($viewer->isLoggedIn()) {
|
||||
@@ -29,6 +148,33 @@ abstract class ManiphestController extends PhabricatorController {
|
||||
|
||||
protected function buildApplicationCrumbs() {
|
||||
$crumbs = parent::buildApplicationCrumbs();
|
||||
return $crumbs;
|
||||
|
||||
if ($this->projectKey) {
|
||||
$user = $this->getRequest()->getUser();
|
||||
$project = id(new PhabricatorProjectQuery())
|
||||
->setViewer($user)
|
||||
->withIDs(array($this->projectKey))
|
||||
->executeOne();
|
||||
if ($project) {
|
||||
// Special for for Blender and Addons reports.
|
||||
$form = 1;
|
||||
if ($this->projectKey == 3) {
|
||||
$form = 2;
|
||||
}
|
||||
$crumbs->addTextCrumb(pht($project->getName()),
|
||||
$this->taskSubtypeKey? '/maniphest/project/'.$this->projectKey: null);
|
||||
|
||||
$crumbs->addAction(
|
||||
id(new PHUIListItemView())
|
||||
->setName(pht('Report Bug'))
|
||||
->setHref($this->getApplicationURI('task/edit/form/' . $form . '/?project='.
|
||||
$project->getPHID().'&type=Bug'))
|
||||
->setIcon('fa-plus-square'));
|
||||
} else {
|
||||
throw new Exception('Unknown project was passed via the url');
|
||||
}
|
||||
}
|
||||
|
||||
id(new ManiphestEditEngine())
|
||||
->setViewer($this->getViewer())
|
||||
|
@@ -0,0 +1,65 @@
|
||||
<?php
|
||||
|
||||
final class ManiphestSearchController
|
||||
extends PhabricatorApplicationSearchController {
|
||||
|
||||
private $projectKey;
|
||||
private $taskSubtypeKey;
|
||||
private $taskSubtypes;
|
||||
|
||||
protected function getDescriptionForQuery($named_query, $dao_query) {
|
||||
$title = '';
|
||||
|
||||
if ($named_query) {
|
||||
$title = $named_query->getQueryName();
|
||||
} else {
|
||||
$title = parent::getDescriptionForQuery($named_query, $dao_query);
|
||||
if (!$title) {
|
||||
$title = pht('Advanced Search');
|
||||
}
|
||||
}
|
||||
|
||||
$description = pht('%s (%d)',
|
||||
$title,
|
||||
$dao_query->getTotalTasksCount());
|
||||
|
||||
if ($this->projectKey) {
|
||||
$user = $this->getRequest()->getUser();
|
||||
$project = id(new PhabricatorProjectQuery())
|
||||
->setViewer($user)
|
||||
->withIDs(array($this->projectKey))
|
||||
->executeOne();
|
||||
if ($project) {
|
||||
$description .= ' from project "'.pht($project->getName()).'"';
|
||||
} else {
|
||||
throw new Exception('Unknown project');
|
||||
}
|
||||
}
|
||||
|
||||
if ($this->taskSubtypeKey) {
|
||||
$task_subtype = idx($this->taskSubtypes, $this->taskSubtypeKey);
|
||||
if ($task_subtype) {
|
||||
$description .= ', task type "'.pht($task_subtype->getName()).'"';
|
||||
} else {
|
||||
throw new Exception('Unknown task type');
|
||||
}
|
||||
}
|
||||
|
||||
return $description;
|
||||
}
|
||||
|
||||
public function setProjectKey($projectKey) {
|
||||
$this->projectKey = $projectKey;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function setTaskSubtypes($taskSubtypes) {
|
||||
$this->taskSubtypes = $taskSubtypes;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function setTaskTypeKey($taskSubtypeKey) {
|
||||
$this->taskSubtypeKey = $taskSubtypeKey;
|
||||
return $this;
|
||||
}
|
||||
}
|
@@ -210,7 +210,8 @@ final class ManiphestTaskDetailController extends ManiphestController {
|
||||
$view = id(new PHUIHeaderView())
|
||||
->setHeader($task->getTitle())
|
||||
->setUser($this->getRequest()->getUser())
|
||||
->setPolicyObject($task);
|
||||
// ->setPolicyObject($task)
|
||||
;
|
||||
|
||||
$priority_name = ManiphestTaskPriority::getTaskPriorityName(
|
||||
$task->getPriority());
|
||||
@@ -271,6 +272,7 @@ final class ManiphestTaskDetailController extends ManiphestController {
|
||||
|
||||
$curtain = $this->newCurtainView($task);
|
||||
|
||||
/*
|
||||
$curtain->addAction(
|
||||
id(new PhabricatorActionView())
|
||||
->setName(pht('Edit Task'))
|
||||
@@ -278,6 +280,7 @@ final class ManiphestTaskDetailController extends ManiphestController {
|
||||
->setHref($this->getApplicationURI("/task/edit/{$id}/"))
|
||||
->setDisabled(!$can_edit)
|
||||
->setWorkflow($workflow_edit));
|
||||
*/
|
||||
|
||||
$subtype_map = $task->newEditEngineSubtypeMap();
|
||||
$subtask_options = $subtype_map->getCreateFormsForSubtype(
|
||||
@@ -325,16 +328,20 @@ final class ManiphestTaskDetailController extends ManiphestController {
|
||||
ManiphestTaskCloseAsDuplicateRelationship::RELATIONSHIPKEY,
|
||||
);
|
||||
|
||||
/*
|
||||
$task_submenu = $relationship_list->newActionSubmenu($submenu_actions)
|
||||
->setName(pht('Edit Related Tasks...'))
|
||||
->setIcon('fa-anchor');
|
||||
|
||||
$curtain->addAction($task_submenu);
|
||||
*/
|
||||
|
||||
/*
|
||||
$relationship_submenu = $relationship_list->newActionMenu();
|
||||
if ($relationship_submenu) {
|
||||
$curtain->addAction($relationship_submenu);
|
||||
}
|
||||
*/
|
||||
|
||||
$viewer_phid = $viewer->getPHID();
|
||||
$owner_phid = $task->getOwnerPHID();
|
||||
@@ -633,9 +640,9 @@ final class ManiphestTaskDetailController extends ManiphestController {
|
||||
$commit_monogram);
|
||||
|
||||
$commit_link = javelin_tag(
|
||||
'a',
|
||||
'span',
|
||||
array(
|
||||
'href' => $commit->getURI(),
|
||||
// 'href' => $commit->getURI(),
|
||||
'sigil' => 'hovercard',
|
||||
'meta' => array(
|
||||
'hoverPHID' => $commit->getPHID(),
|
||||
|
@@ -10,14 +10,269 @@ final class ManiphestTaskListController
|
||||
public function handleRequest(AphrontRequest $request) {
|
||||
$querykey = $request->getURIData('queryKey');
|
||||
|
||||
$controller = id(new PhabricatorApplicationSearchController())
|
||||
$controller = id(new ManiphestSearchController())
|
||||
->setQueryKey($querykey)
|
||||
->setTaskSubtypes($this->getAvailableTaskSubtypes())
|
||||
->setProjectKey($this->projectKey)
|
||||
->setTaskTypeKey($this->taskSubtypeKey)
|
||||
->setSearchEngine(
|
||||
id(new ManiphestTaskSearchEngine())
|
||||
->setShowBatchControls(true))
|
||||
->setShowBatchControls(true)
|
||||
->setProjectKey($this->projectKey)
|
||||
->setTaskTypeKey($this->taskSubtypeKey))
|
||||
->setNavigation($this->buildSideNavView());
|
||||
|
||||
return $this->delegateToController($controller);
|
||||
}
|
||||
|
||||
public function __renderResultsList(
|
||||
array $tasks,
|
||||
PhabricatorSavedQuery $query) {
|
||||
assert_instances_of($tasks, 'ManiphestTask');
|
||||
|
||||
$viewer = $this->getRequest()->getUser();
|
||||
|
||||
// If we didn't match anything, just pick up the default empty state.
|
||||
if (!$tasks) {
|
||||
return id(new PHUIObjectItemListView())
|
||||
->setUser($viewer);
|
||||
}
|
||||
|
||||
$group_parameter = nonempty($query->getParameter('group'), 'priority');
|
||||
$order_parameter = nonempty($query->getParameter('order'), 'priority');
|
||||
|
||||
$handles = ManiphestTaskListView::loadTaskHandles($viewer, $tasks);
|
||||
$groups = $this->groupTasks(
|
||||
$tasks,
|
||||
$group_parameter,
|
||||
$handles);
|
||||
|
||||
$can_edit_priority = $this->hasApplicationCapability(
|
||||
ManiphestCapabilityEditPriority::CAPABILITY);
|
||||
|
||||
$can_drag = ($order_parameter == 'priority') &&
|
||||
($can_edit_priority) &&
|
||||
($group_parameter == 'none' || $group_parameter == 'priority');
|
||||
|
||||
if (!$viewer->isLoggedIn()) {
|
||||
// TODO: (T603) Eventually, we conceivably need to make each task
|
||||
// draggable individually, since the user may be able to edit some but
|
||||
// not others.
|
||||
$can_drag = false;
|
||||
}
|
||||
|
||||
$result = array();
|
||||
|
||||
$can_edit = $this->hasApplicationCapability(
|
||||
PhabricatorPolicyCapability::CAN_EDIT);
|
||||
|
||||
$lists = array();
|
||||
foreach ($groups as $group => $list) {
|
||||
$task_list = new ManiphestTaskListView();
|
||||
$task_list->setShowBatchControls($can_edit);
|
||||
if ($can_drag) {
|
||||
$task_list->setShowSubpriorityControls(true);
|
||||
}
|
||||
$task_list->setUser($viewer);
|
||||
$task_list->setTasks($list);
|
||||
$task_list->setHandles($handles);
|
||||
|
||||
$header = javelin_tag(
|
||||
'h1',
|
||||
array(
|
||||
'class' => 'maniphest-task-group-header',
|
||||
'sigil' => 'task-group',
|
||||
'meta' => array(
|
||||
'priority' => head($list)->getPriority(),
|
||||
),
|
||||
),
|
||||
pht('%s (%s)', $group, new PhutilNumber(count($list))));
|
||||
|
||||
$lists[] = phutil_tag(
|
||||
'div',
|
||||
array(
|
||||
'class' => 'maniphest-task-group'
|
||||
),
|
||||
array(
|
||||
$header,
|
||||
$task_list,
|
||||
));
|
||||
}
|
||||
|
||||
if ($can_drag) {
|
||||
Javelin::initBehavior(
|
||||
'maniphest-subpriority-editor',
|
||||
array(
|
||||
'uri' => '/maniphest/subpriority/',
|
||||
));
|
||||
}
|
||||
|
||||
return phutil_tag(
|
||||
'div',
|
||||
array(
|
||||
'class' => 'maniphest-list-container',
|
||||
),
|
||||
array(
|
||||
$lists,
|
||||
$this->renderBatchEditor($query),
|
||||
));
|
||||
}
|
||||
|
||||
private function __groupTasks(array $tasks, $group, array $handles) {
|
||||
assert_instances_of($tasks, 'ManiphestTask');
|
||||
assert_instances_of($handles, 'PhabricatorObjectHandle');
|
||||
|
||||
$groups = $this->getTaskGrouping($tasks, $group);
|
||||
|
||||
$results = array();
|
||||
foreach ($groups as $label_key => $tasks) {
|
||||
$label = $this->getTaskLabelName($group, $label_key, $handles);
|
||||
$results[$label][] = $tasks;
|
||||
}
|
||||
foreach ($results as $label => $task_groups) {
|
||||
$results[$label] = array_mergev($task_groups);
|
||||
}
|
||||
|
||||
return $results;
|
||||
}
|
||||
|
||||
private function __getTaskGrouping(array $tasks, $group) {
|
||||
switch ($group) {
|
||||
case 'priority':
|
||||
return mgroup($tasks, 'getPriority');
|
||||
case 'status':
|
||||
return mgroup($tasks, 'getStatus');
|
||||
case 'assigned':
|
||||
return mgroup($tasks, 'getOwnerPHID');
|
||||
case 'project':
|
||||
return mgroup($tasks, 'getGroupByProjectPHID');
|
||||
default:
|
||||
return array(pht('Tasks') => $tasks);
|
||||
}
|
||||
}
|
||||
|
||||
private function __getTaskLabelName($group, $label_key, array $handles) {
|
||||
switch ($group) {
|
||||
case 'priority':
|
||||
return ManiphestTaskPriority::getTaskPriorityName($label_key);
|
||||
case 'status':
|
||||
return ManiphestTaskStatus::getTaskStatusFullName($label_key);
|
||||
case 'assigned':
|
||||
if ($label_key) {
|
||||
return $handles[$label_key]->getFullName();
|
||||
} else {
|
||||
return pht('(Not Assigned)');
|
||||
}
|
||||
case 'project':
|
||||
if ($label_key) {
|
||||
return $handles[$label_key]->getFullName();
|
||||
} else {
|
||||
return pht('(No Project)');
|
||||
}
|
||||
default:
|
||||
return pht('Tasks');
|
||||
}
|
||||
}
|
||||
|
||||
private function ___renderBatchEditor(PhabricatorSavedQuery $saved_query) {
|
||||
$user = $this->getRequest()->getUser();
|
||||
|
||||
$batch_capability = ManiphestCapabilityBulkEdit::CAPABILITY;
|
||||
if (!$this->hasApplicationCapability($batch_capability)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (!$user->isLoggedIn()) {
|
||||
// Don't show the batch editor or excel export for logged-out users.
|
||||
// Technically we //could// let them export, but ehh.
|
||||
return null;
|
||||
}
|
||||
|
||||
Javelin::initBehavior(
|
||||
'maniphest-batch-selector',
|
||||
array(
|
||||
'selectAll' => 'batch-select-all',
|
||||
'selectNone' => 'batch-select-none',
|
||||
'submit' => 'batch-select-submit',
|
||||
'status' => 'batch-select-status-cell',
|
||||
'idContainer' => 'batch-select-id-container',
|
||||
'formID' => 'batch-select-form',
|
||||
));
|
||||
|
||||
$select_all = javelin_tag(
|
||||
'a',
|
||||
array(
|
||||
'href' => '#',
|
||||
'mustcapture' => true,
|
||||
'class' => 'grey button',
|
||||
'id' => 'batch-select-all',
|
||||
),
|
||||
pht('Select All'));
|
||||
|
||||
$select_none = javelin_tag(
|
||||
'a',
|
||||
array(
|
||||
'href' => '#',
|
||||
'mustcapture' => true,
|
||||
'class' => 'grey button',
|
||||
'id' => 'batch-select-none',
|
||||
),
|
||||
pht('Clear Selection'));
|
||||
|
||||
$submit = phutil_tag(
|
||||
'button',
|
||||
array(
|
||||
'id' => 'batch-select-submit',
|
||||
'disabled' => 'disabled',
|
||||
'class' => 'disabled',
|
||||
),
|
||||
pht("Batch Edit Selected \xC2\xBB"));
|
||||
|
||||
$export = javelin_tag(
|
||||
'a',
|
||||
array(
|
||||
'href' => '/maniphest/export/'.$saved_query->getQueryKey().'/',
|
||||
'class' => 'grey button',
|
||||
),
|
||||
pht('Export to Excel'));
|
||||
|
||||
$hidden = phutil_tag(
|
||||
'div',
|
||||
array(
|
||||
'id' => 'batch-select-id-container',
|
||||
),
|
||||
'');
|
||||
|
||||
$editor = hsprintf(
|
||||
'<div class="maniphest-batch-editor">'.
|
||||
'<div class="batch-editor-header">%s</div>'.
|
||||
'<table class="maniphest-batch-editor-layout">'.
|
||||
'<tr>'.
|
||||
'<td>%s%s</td>'.
|
||||
'<td>%s</td>'.
|
||||
'<td id="batch-select-status-cell">%s</td>'.
|
||||
'<td class="batch-select-submit-cell">%s%s</td>'.
|
||||
'</tr>'.
|
||||
'</table>'.
|
||||
'</div>',
|
||||
pht('Batch Task Editor'),
|
||||
$select_all,
|
||||
$select_none,
|
||||
$export,
|
||||
'',
|
||||
$submit,
|
||||
$hidden);
|
||||
|
||||
$editor = phabricator_form(
|
||||
$user,
|
||||
array(
|
||||
'method' => 'POST',
|
||||
'action' => '/maniphest/batch/',
|
||||
'id' => 'batch-select-form',
|
||||
),
|
||||
$editor);
|
||||
|
||||
return $editor;
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -200,7 +200,8 @@ EODOCS
|
||||
->setIsNullable(true)
|
||||
->setSingleValue($object->getOwnerPHID())
|
||||
->setCommentActionLabel(pht('Assign / Claim'))
|
||||
->setCommentActionValue($owner_value),
|
||||
->setCommentActionValue($owner_value)
|
||||
->setCanApplyWithoutEditCapability(true),
|
||||
id(new PhabricatorSelectEditField())
|
||||
->setKey('status')
|
||||
->setLabel(pht('Status'))
|
||||
@@ -213,7 +214,8 @@ EODOCS
|
||||
->setValue($object->getStatus())
|
||||
->setOptions($status_map)
|
||||
->setCommentActionLabel(pht('Change Status'))
|
||||
->setCommentActionValue($default_status),
|
||||
->setCommentActionValue($default_status)
|
||||
->setCanApplyWithoutEditCapability(true),
|
||||
id(new PhabricatorSelectEditField())
|
||||
->setKey('priority')
|
||||
->setLabel(pht('Priority'))
|
||||
@@ -226,6 +228,7 @@ EODOCS
|
||||
->setValue($object->getPriorityKeyword())
|
||||
->setOptions($priority_map)
|
||||
->setOptionAliases($alias_map)
|
||||
->setCanApplyWithoutEditCapability(true)
|
||||
->setCommentActionLabel(pht('Change Priority')),
|
||||
);
|
||||
|
||||
@@ -350,6 +353,18 @@ EODOCS
|
||||
continue;
|
||||
}
|
||||
|
||||
// Blender: limit task reopen to contributors.
|
||||
//
|
||||
// NOTE: Similar to other semantic check here we don't do it in the
|
||||
// Conduit.
|
||||
$viewer = $this->getViewer();
|
||||
if (ManiphestTaskStatus::isClosedStatus($current_status) &&
|
||||
ManiphestTaskStatus::isOpenStatus($status) &&
|
||||
$viewer->limitNonContributorUI()) {
|
||||
unset($status_map[$status]);
|
||||
continue;
|
||||
}
|
||||
|
||||
// Don't allow tasks to be changed directly into "Closed, Duplicate"
|
||||
// status. Instead, you have to merge them. See T4819.
|
||||
if ($status == $dup_status) {
|
||||
@@ -379,6 +394,18 @@ EODOCS
|
||||
continue;
|
||||
}
|
||||
|
||||
// Blender: limit triaging to contributors.
|
||||
//
|
||||
// NOTE: Similar to other semantic check here we don't do it in the
|
||||
// Conduit.
|
||||
$viewer = $this->getViewer();
|
||||
if ($priority != $current_priority) {
|
||||
if (array_search('triage', $priority_keywords[$priority]) === false &&
|
||||
$viewer->limitNonContributorUI()) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
$keyword = head(idx($priority_keywords, $priority));
|
||||
$results[$keyword] = $priority_name;
|
||||
}
|
||||
|
@@ -36,7 +36,7 @@ final class ManiphestTaskPHIDType extends PhabricatorPHIDType {
|
||||
|
||||
$handle->setName("T{$id}");
|
||||
$handle->setFullName("T{$id}: {$title}");
|
||||
$handle->setURI("/T{$id}");
|
||||
$handle->setURI($task->getURI());
|
||||
|
||||
if ($task->isClosed()) {
|
||||
$handle->setStatus(PhabricatorObjectHandle::STATUS_CLOSED);
|
||||
|
@@ -237,7 +237,13 @@ final class ManiphestTaskQuery extends PhabricatorCursorPagedPolicyAwareQuery {
|
||||
return new ManiphestTask();
|
||||
}
|
||||
|
||||
protected function loadPage() {
|
||||
protected function buildTaskCountSelectClause(AphrontDatabaseConnection $conn) {
|
||||
$parts = $this->buildSelectClauseParts($conn);
|
||||
$parts[0] = qsprintf($conn, '`task`.id');
|
||||
return $this->formatSelectClause($conn, $parts);
|
||||
}
|
||||
|
||||
protected function getRawQueryResults($task_dao, $count_all_tasks) {
|
||||
$task_dao = new ManiphestTask();
|
||||
$conn = $task_dao->establishConnection('r');
|
||||
|
||||
@@ -252,18 +258,46 @@ final class ManiphestTaskQuery extends PhabricatorCursorPagedPolicyAwareQuery {
|
||||
break;
|
||||
}
|
||||
|
||||
$rows = queryfx_all(
|
||||
$conn,
|
||||
'%Q %Q FROM %T task %Q %Q %Q %Q %Q %Q',
|
||||
$this->buildSelectClause($conn),
|
||||
$group_column,
|
||||
$task_dao->getTableName(),
|
||||
$this->buildJoinClause($conn),
|
||||
$where,
|
||||
$this->buildGroupClause($conn),
|
||||
$this->buildHavingClause($conn),
|
||||
$this->buildOrderClause($conn),
|
||||
$this->buildLimitClause($conn));
|
||||
if ($count_all_tasks) {
|
||||
$r = queryfx_all(
|
||||
$conn,
|
||||
'%Q %Q FROM %T task %Q %Q %Q %Q %Q',
|
||||
$this->buildTaskCountSelectClause($conn),
|
||||
$group_column,
|
||||
$task_dao->getTableName(),
|
||||
$this->buildJoinClause($conn),
|
||||
$where,
|
||||
$this->buildGroupClause($conn),
|
||||
$this->buildHavingClause($conn),
|
||||
$this->buildOrderClause($conn));
|
||||
return array('count' => count($r));
|
||||
} else {
|
||||
return queryfx_all(
|
||||
$conn,
|
||||
'%Q %Q FROM %T task %Q %Q %Q %Q %Q %Q',
|
||||
$this->buildSelectClause($conn),
|
||||
$group_column,
|
||||
$task_dao->getTableName(),
|
||||
$this->buildJoinClause($conn),
|
||||
$where,
|
||||
$this->buildGroupClause($conn),
|
||||
$this->buildHavingClause($conn),
|
||||
$this->buildOrderClause($conn),
|
||||
$this->buildLimitClause($conn));
|
||||
}
|
||||
}
|
||||
|
||||
public function getTotalTasksCount() {
|
||||
$task_dao = new ManiphestTask();
|
||||
|
||||
$row = $this->getRawQueryResults($task_dao, true);
|
||||
return $row['count'];
|
||||
}
|
||||
|
||||
protected function loadPage() {
|
||||
$task_dao = new ManiphestTask();
|
||||
|
||||
$rows = $this->getRawQueryResults($task_dao, false);
|
||||
|
||||
switch ($this->groupBy) {
|
||||
case self::GROUP_PROJECT:
|
||||
|
@@ -3,6 +3,8 @@
|
||||
final class ManiphestTaskSearchEngine
|
||||
extends PhabricatorApplicationSearchEngine {
|
||||
|
||||
private $projectKey;
|
||||
private $taskSubtypeKey;
|
||||
private $showBatchControls;
|
||||
private $baseURI;
|
||||
private $isBoardView;
|
||||
@@ -206,7 +208,9 @@ final class ManiphestTaskSearchEngine
|
||||
$query->withPriorities($map['priorities']);
|
||||
}
|
||||
|
||||
if ($map['subtypes']) {
|
||||
if ($this->taskSubtypeKey) {
|
||||
$query->withSubtypes(array($this->taskSubtypeKey));
|
||||
} else if ($map['subtypes']) {
|
||||
$query->withSubtypes($map['subtypes']);
|
||||
}
|
||||
|
||||
@@ -250,6 +254,18 @@ final class ManiphestTaskSearchEngine
|
||||
$query->withSubtaskIDs($map['subtaskIDs']);
|
||||
}
|
||||
|
||||
if ($this->projectKey) {
|
||||
$project = id(new PhabricatorProjectQuery())
|
||||
->setViewer($this->requireViewer())
|
||||
->withIDs(array($this->projectKey))
|
||||
->executeOne();
|
||||
|
||||
$query->withEdgeLogicPHIDs(
|
||||
PhabricatorProjectObjectHasProjectEdgeType::EDGECONST,
|
||||
PhabricatorQueryConstraint::OPERATOR_AND,
|
||||
array($project->getPHID()));
|
||||
}
|
||||
|
||||
if ($map['columnPHIDs']) {
|
||||
$query->withColumnPHIDs($map['columnPHIDs']);
|
||||
}
|
||||
@@ -281,23 +297,30 @@ final class ManiphestTaskSearchEngine
|
||||
|
||||
protected function getURI($path) {
|
||||
if ($this->baseURI) {
|
||||
return $this->baseURI.$path;
|
||||
$url = $this->baseURI;
|
||||
} else {
|
||||
$url = '/maniphest/';
|
||||
}
|
||||
return '/maniphest/'.$path;
|
||||
if ($this->projectKey)
|
||||
$url .= 'project/' . $this->projectKey . '/';
|
||||
if ($this->taskSubtypeKey)
|
||||
$url .= 'type/' . $this->taskSubtypeKey . '/';
|
||||
$url = str_replace(" ", "%20", $url);
|
||||
return $url . $path;
|
||||
}
|
||||
|
||||
protected function getBuiltinQueryNames() {
|
||||
$names = array();
|
||||
|
||||
$names['open'] = pht('Open Tasks');
|
||||
$names['all'] = pht('All Tasks');
|
||||
|
||||
if ($this->requireViewer()->isLoggedIn()) {
|
||||
$names['assigned'] = pht('Assigned');
|
||||
$names['authored'] = pht('Authored');
|
||||
$names['subscribed'] = pht('Subscribed');
|
||||
}
|
||||
|
||||
$names['open'] = pht('Open Tasks');
|
||||
$names['all'] = pht('All Tasks');
|
||||
|
||||
return $names;
|
||||
}
|
||||
|
||||
@@ -310,7 +333,9 @@ final class ManiphestTaskSearchEngine
|
||||
|
||||
switch ($query_key) {
|
||||
case 'all':
|
||||
return $query;
|
||||
return $query
|
||||
->setParameter('order', 'created')
|
||||
->setParameter('group', 'none');
|
||||
case 'assigned':
|
||||
return $query
|
||||
->setParameter('assignedPHIDs', array($viewer_phid))
|
||||
@@ -358,6 +383,16 @@ final class ManiphestTaskSearchEngine
|
||||
);
|
||||
}
|
||||
|
||||
function setProjectKey($projectKey) {
|
||||
$this->projectKey = $projectKey;
|
||||
return $this;
|
||||
}
|
||||
|
||||
function setTaskTypeKey($taskSubtypeKey) {
|
||||
$this->taskSubtypeKey = $taskSubtypeKey;
|
||||
return $this;
|
||||
}
|
||||
|
||||
protected function renderResultList(
|
||||
array $tasks,
|
||||
PhabricatorSavedQuery $saved,
|
||||
|
@@ -3,8 +3,30 @@
|
||||
final class ManiphestTransactionQuery
|
||||
extends PhabricatorApplicationTransactionQuery {
|
||||
|
||||
private $updatedEpochAfter;
|
||||
|
||||
public function getTemplateApplicationTransaction() {
|
||||
return new ManiphestTransaction();
|
||||
}
|
||||
|
||||
public function withUpdatedEpochAfter($epoch) {
|
||||
$this->updatedEpochAfter = $epoch;
|
||||
return $this;
|
||||
}
|
||||
|
||||
protected function buildWhereClause(AphrontDatabaseConnection $conn) {
|
||||
$where = array();
|
||||
|
||||
if ($this->updatedEpochAfter !== null) {
|
||||
$where[] = qsprintf(
|
||||
$conn,
|
||||
'x.dateModified >= %d',
|
||||
$this->updatedEpochAfter);
|
||||
}
|
||||
|
||||
$where[] = $this->buildWhereClauseParts($conn);
|
||||
|
||||
return $this->formatWhereClause($conn, $where);
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -193,7 +193,8 @@ final class ManiphestTask extends ManiphestDAO
|
||||
}
|
||||
|
||||
public function getURI() {
|
||||
return '/'.$this->getMonogram();
|
||||
$subpath = SubpathFromId($this->getID());
|
||||
return '../../../maniphest/' . $subpath . '/index.html';
|
||||
}
|
||||
|
||||
public function attachGroupByProjectPHID($phid) {
|
||||
@@ -311,6 +312,8 @@ final class ManiphestTask extends ManiphestDAO
|
||||
* @task markup
|
||||
*/
|
||||
public function shouldUseMarkupCache($field) {
|
||||
return false;
|
||||
|
||||
return (bool)$this->getID();
|
||||
}
|
||||
|
||||
|
@@ -35,6 +35,7 @@ final class ManiphestTaskListView extends ManiphestView {
|
||||
require_celerity_resource('maniphest-task-summary-css');
|
||||
|
||||
$list = new PHUIObjectItemListView();
|
||||
$list->addClass('maniphest-task-group');
|
||||
|
||||
if ($this->noDataString) {
|
||||
$list->setNoDataString($this->noDataString);
|
||||
@@ -58,6 +59,11 @@ final class ManiphestTaskListView extends ManiphestView {
|
||||
->setHeader($task->getTitle())
|
||||
->setHref('/T'.$task->getID());
|
||||
|
||||
if ($task->getAuthorPHID()) {
|
||||
$author = $handles[$task->getAuthorPHID()];
|
||||
$item->addByline(pht('By: %s', $author->renderLink()));
|
||||
}
|
||||
|
||||
if ($task->getOwnerPHID()) {
|
||||
$owner = $handles[$task->getOwnerPHID()];
|
||||
$item->addByline(pht('Assigned: %s', $owner->renderLink()));
|
||||
@@ -149,6 +155,10 @@ final class ManiphestTaskListView extends ManiphestView {
|
||||
if ($assigned_phid) {
|
||||
$phids[] = $assigned_phid;
|
||||
}
|
||||
$author_phid = $task->getAuthorPHID();
|
||||
if ($author_phid) {
|
||||
$phids[] = $author_phid;
|
||||
}
|
||||
foreach ($task->getProjectPHIDs() as $project_phid) {
|
||||
$phids[] = $project_phid;
|
||||
}
|
||||
|
@@ -165,4 +165,10 @@ final class ManiphestTaskOwnerTransaction
|
||||
);
|
||||
}
|
||||
|
||||
public function getRequiredCapabilities(
|
||||
$object,
|
||||
PhabricatorApplicationTransaction $xaction) {
|
||||
return PhabricatorPolicyCapability::CAN_INTERACT;
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -201,4 +201,10 @@ final class ManiphestTaskPriorityTransaction
|
||||
);
|
||||
}
|
||||
|
||||
public function getRequiredCapabilities(
|
||||
$object,
|
||||
PhabricatorApplicationTransaction $xaction) {
|
||||
return PhabricatorPolicyCapability::CAN_INTERACT;
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -237,4 +237,10 @@ final class ManiphestTaskStatusTransaction
|
||||
);
|
||||
}
|
||||
|
||||
public function getRequiredCapabilities(
|
||||
$object,
|
||||
PhabricatorApplicationTransaction $xaction) {
|
||||
return PhabricatorPolicyCapability::CAN_INTERACT;
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -141,12 +141,14 @@ final class PhabricatorMailTarget extends Phobject {
|
||||
$body = '';
|
||||
|
||||
if ($to_handles) {
|
||||
$to_names = mpull($to_handles, 'getCommandLineObjectName');
|
||||
// $to_names = mpull($to_handles, 'getCommandLineObjectName');
|
||||
$to_names = mpull($to_handles, 'getFullName');
|
||||
$body .= "To: ".implode(', ', $to_names)."\n";
|
||||
}
|
||||
|
||||
if ($cc_handles) {
|
||||
$cc_names = mpull($cc_handles, 'getCommandLineObjectName');
|
||||
// $cc_names = mpull($cc_handles, 'getCommandLineObjectName');
|
||||
$cc_names = mpull($cc_handles, 'getFullName');
|
||||
$body .= "Cc: ".implode(', ', $cc_names)."\n";
|
||||
}
|
||||
|
||||
@@ -167,12 +169,12 @@ final class PhabricatorMailTarget extends Phobject {
|
||||
$body = array();
|
||||
if ($to_handles) {
|
||||
$body[] = phutil_tag('strong', array(), 'To: ');
|
||||
$body[] = phutil_implode_html(', ', mpull($to_handles, 'getName'));
|
||||
$body[] = phutil_implode_html(', ', mpull($to_handles, 'getFullName'));
|
||||
$body[] = phutil_tag('br');
|
||||
}
|
||||
if ($cc_handles) {
|
||||
$body[] = phutil_tag('strong', array(), 'Cc: ');
|
||||
$body[] = phutil_implode_html(', ', mpull($cc_handles, 'getName'));
|
||||
$body[] = phutil_implode_html(', ', mpull($cc_handles, 'getFullName'));
|
||||
$body[] = phutil_tag('br');
|
||||
}
|
||||
return phutil_tag('div', array(), $body);
|
||||
|
@@ -809,7 +809,6 @@ final class PhabricatorMetaMTAMail
|
||||
$exceptions);
|
||||
}
|
||||
|
||||
|
||||
public static function shouldMailEachRecipient() {
|
||||
return PhabricatorEnv::getEnvConfig('metamta.one-mail-per-recipient');
|
||||
}
|
||||
|
@@ -37,7 +37,8 @@ final class PhabricatorPastePastePHIDType extends PhabricatorPHIDType {
|
||||
|
||||
$handle->setName("P{$id}");
|
||||
$handle->setFullName($name);
|
||||
$handle->setURI("/P{$id}");
|
||||
|
||||
$handle->setURI($paste->getURI());
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -176,7 +176,7 @@ final class PhabricatorPasteSearchEngine
|
||||
$item = id(new PHUIObjectItemView())
|
||||
->setObjectName('P'.$paste->getID())
|
||||
->setHeader($title)
|
||||
->setHref('/P'.$paste->getID())
|
||||
->setHref($paste->getURI())
|
||||
->setObject($paste)
|
||||
->addByline(pht('Author: %s', $author))
|
||||
->addIcon('none', $created)
|
||||
|
@@ -60,7 +60,8 @@ final class PhabricatorPaste extends PhabricatorPasteDAO
|
||||
}
|
||||
|
||||
public function getURI() {
|
||||
return '/'.$this->getMonogram();
|
||||
$subpath = SubpathFromId($this->getID());
|
||||
return '../../../paste/' . $subpath . '/P' . $this->getID() . '.txt';
|
||||
}
|
||||
|
||||
public function getMonogram() {
|
||||
|
@@ -11,6 +11,8 @@ final class PhabricatorPasteTransactionComment
|
||||
}
|
||||
|
||||
public function shouldUseMarkupCache($field) {
|
||||
return false;
|
||||
|
||||
// Only cache submitted comments.
|
||||
return ($this->getTransactionPHID() != null);
|
||||
}
|
||||
|
@@ -38,7 +38,7 @@ final class PasteEmbedView extends AphrontView {
|
||||
$link = phutil_tag(
|
||||
'a',
|
||||
array(
|
||||
'href' => '/P'.$this->paste->getID(),
|
||||
'href' => $this->paste->getURI(),
|
||||
),
|
||||
$this->handle->getFullName());
|
||||
|
||||
|
@@ -58,6 +58,7 @@ final class PhabricatorPeopleApplication extends PhabricatorApplication {
|
||||
=> 'PhabricatorPeopleDisableController',
|
||||
'(?P<via>disable)/(?P<id>[1-9]\d*)/'
|
||||
=> 'PhabricatorPeopleDisableController',
|
||||
'spam/(?P<id>[1-9]\d*)/' => 'PhabricatorPeopleSpamController',
|
||||
'empower/(?P<id>[1-9]\d*)/' => 'PhabricatorPeopleEmpowerController',
|
||||
'delete/(?P<id>[1-9]\d*)/' => 'PhabricatorPeopleDeleteController',
|
||||
'rename/(?P<id>[1-9]\d*)/' => 'PhabricatorPeopleRenameController',
|
||||
@@ -99,6 +100,9 @@ final class PhabricatorPeopleApplication extends PhabricatorApplication {
|
||||
PeopleDisableUsersCapability::CAPABILITY => array(
|
||||
'default' => PhabricatorPolicies::POLICY_ADMIN,
|
||||
),
|
||||
PeopleDisableSpamUsersCapability::CAPABILITY => array(
|
||||
'default' => PhabricatorPolicies::POLICY_ADMIN,
|
||||
),
|
||||
PeopleBrowseUserDirectoryCapability::CAPABILITY => array(),
|
||||
);
|
||||
}
|
||||
|
@@ -0,0 +1,16 @@
|
||||
<?php
|
||||
|
||||
final class PeopleDisableSpamUsersCapability
|
||||
extends PhabricatorPolicyCapability {
|
||||
|
||||
const CAPABILITY = 'people.disable_spam.users';
|
||||
|
||||
public function getCapabilityName() {
|
||||
return pht('Can Disable Spammers');
|
||||
}
|
||||
|
||||
public function describeCapabilityRejection() {
|
||||
return pht('You do not have permission to handle spam users.');
|
||||
}
|
||||
|
||||
}
|
@@ -29,7 +29,7 @@ final class PhabricatorPeopleDeleteController
|
||||
->appendCommand(
|
||||
csprintf(
|
||||
'phabricator/ $ ./bin/remove destroy %R',
|
||||
$user->getMonogram()))
|
||||
$user->getMonogramForCommand()))
|
||||
->appendParagraph(
|
||||
pht(
|
||||
'Unless you have a very good reason to delete this user, consider '.
|
||||
|
@@ -93,6 +93,10 @@ final class PhabricatorPeopleProfileManageController
|
||||
PeopleDisableUsersCapability::CAPABILITY);
|
||||
$can_disable = ($has_disable && !$is_self);
|
||||
|
||||
$has_disable_spam_capability = $this->hasApplicationCapability(
|
||||
PeopleDisableSpamUsersCapability::CAPABILITY);
|
||||
$can_disable_spam = ($has_disable_spam_capability && !$is_self);
|
||||
|
||||
$id = $user->getID();
|
||||
|
||||
$welcome_engine = id(new PhabricatorPeopleWelcomeMailEngine())
|
||||
@@ -193,6 +197,14 @@ final class PhabricatorPeopleProfileManageController
|
||||
->setWorkflow(true)
|
||||
->setHref($this->getApplicationURI('disable/'.$id.'/')));
|
||||
|
||||
$curtain->addAction(
|
||||
id(new PhabricatorActionView())
|
||||
->setIcon('fa-shield')
|
||||
->setName(pht('Disable as Spam'))
|
||||
->setDisabled(!$can_disable_spam)
|
||||
->setWorkflow(true)
|
||||
->setHref($this->getApplicationURI('spam/'.$id.'/')));
|
||||
|
||||
$curtain->addAction(
|
||||
id(new PhabricatorActionView())
|
||||
->setIcon('fa-times')
|
||||
|
@@ -0,0 +1,90 @@
|
||||
<?php
|
||||
|
||||
final class PhabricatorPeopleSpamController
|
||||
extends PhabricatorPeopleController {
|
||||
|
||||
public function shouldRequireAdmin() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public function handleRequest(AphrontRequest $request) {
|
||||
$viewer = $this->getViewer();
|
||||
$id = $request->getURIData('id');
|
||||
|
||||
$user = id(new PhabricatorPeopleQuery())
|
||||
->setViewer($viewer)
|
||||
->withIDs(array($id))
|
||||
->executeOne();
|
||||
if (!$user) {
|
||||
return new Aphront404Response();
|
||||
}
|
||||
|
||||
$this->requireApplicationCapability(
|
||||
PeopleDisableUsersCapability::CAPABILITY);
|
||||
|
||||
$actor = $viewer;
|
||||
$done_uri = $this->getApplicationURI("manage/{$id}/");
|
||||
|
||||
if ($viewer->getPHID() == $user->getPHID()) {
|
||||
return $this->newDialog()
|
||||
->setTitle(pht('Something Stays Your Hand'))
|
||||
->appendParagraph(
|
||||
pht(
|
||||
'Try as you might, you find you can not disable your own account.'))
|
||||
->addCancelButton($done_uri, pht('Curses!'));
|
||||
}
|
||||
|
||||
if ($request->isFormPost()) {
|
||||
// Disable the account.
|
||||
if (!$user->getIsDisabled()) {
|
||||
$xactions = array();
|
||||
$xactions[] = id(new PhabricatorUserTransaction())
|
||||
->setTransactionType(PhabricatorUserDisableTransaction::TRANSACTIONTYPE)
|
||||
->setNewValue(true);
|
||||
|
||||
id(new PhabricatorUserTransactionEditor())
|
||||
->setActor($actor)
|
||||
->setActingAsPHID($viewer->getPHID())
|
||||
->setContentSourceFromRequest($request)
|
||||
->setContinueOnMissingFields(true)
|
||||
->setContinueOnNoEffect(true)
|
||||
->applyTransactions($user, $xactions);
|
||||
}
|
||||
|
||||
// Set profile info to spam and blank to everything else.
|
||||
{
|
||||
$xactions = array();
|
||||
$xactions[] = id(new PhabricatorUserTransaction())
|
||||
->setTransactionType(PhabricatorUserDisableSpamTransaction::TRANSACTIONTYPE);
|
||||
|
||||
id(new PhabricatorUserTransactionEditor())
|
||||
->setActor($actor)
|
||||
->setActingAsPHID($viewer->getPHID())
|
||||
->setContentSourceFromRequest($request)
|
||||
->setContinueOnMissingFields(true)
|
||||
->setContinueOnNoEffect(true)
|
||||
->applyTransactions($user, $xactions);
|
||||
}
|
||||
|
||||
return id(new AphrontRedirectResponse())->setURI($done_uri);
|
||||
}
|
||||
|
||||
$title = pht('Disable as Spam?');
|
||||
$short_title = pht('Disable as Spam');
|
||||
|
||||
$body = pht(
|
||||
'Is %s\'s profile spam?<br />All the profile info will be erased and '.
|
||||
'they will no longer be able to access Phabricator.',
|
||||
phutil_tag('strong', array(), $user->getUsername()));
|
||||
|
||||
$submit = pht('Disable as Spam');
|
||||
|
||||
return $this->newDialog()
|
||||
->setTitle($title)
|
||||
->setShortTitle($short_title)
|
||||
->appendParagraph($body)
|
||||
->addCancelButton($done_uri)
|
||||
->addSubmitButton($submit);
|
||||
}
|
||||
|
||||
}
|
@@ -134,7 +134,7 @@ final class PhabricatorMentionRemarkupRule extends PhutilRemarkupRule {
|
||||
font-weight: bold;
|
||||
padding: 0 4px;',
|
||||
),
|
||||
'@'.$user->getUserName());
|
||||
'@'.$user->getFullName());
|
||||
} else {
|
||||
if ($engine->getConfig('uri.full')) {
|
||||
$user_href = PhabricatorEnv::getURI($user_href);
|
||||
@@ -143,8 +143,9 @@ final class PhabricatorMentionRemarkupRule extends PhutilRemarkupRule {
|
||||
$tag = id(new PHUITagView())
|
||||
->setType(PHUITagView::TYPE_PERSON)
|
||||
->setPHID($user->getPHID())
|
||||
->setName('@'.$user->getUserName())
|
||||
->setHref($user_href);
|
||||
->setName('@'.$user->getFullName())
|
||||
// ->setHref($user_href)
|
||||
;
|
||||
|
||||
if ($user_has_no_permission) {
|
||||
$tag->addClass('phabricator-remarkup-mention-nopermission');
|
||||
|
@@ -258,10 +258,84 @@ final class PhabricatorUser
|
||||
PhabricatorPeopleUserPHIDType::TYPECONST);
|
||||
}
|
||||
|
||||
public function getMonogram() {
|
||||
return '@'.$this->getUsername();
|
||||
// Functions generateRadomNumber, generateChar, generateSalt and
|
||||
// generateHtaccessPassword are adopted from FusionForge sources,
|
||||
// which is licensed by GNU GPL license.
|
||||
private function generateRadomNumber() {
|
||||
mt_srand((double)microtime() * 1000000);
|
||||
$num = mt_rand(46,122);
|
||||
return $num;
|
||||
}
|
||||
|
||||
private function generateChar() {
|
||||
do {
|
||||
$num = $this->generateRadomNumber();
|
||||
} while ( ( $num > 57 && $num < 65 ) || ( $num > 90 && $num < 97 ) );
|
||||
$char = chr($num);
|
||||
return $char;
|
||||
}
|
||||
|
||||
private function generateSalt() {
|
||||
$a = $this->generateChar();
|
||||
$b = $this->generateChar();
|
||||
$salt = "$1$" . "$a$b";
|
||||
return $salt;
|
||||
}
|
||||
|
||||
private function generateHtaccessPassword($plainpw) {
|
||||
return crypt($plainpw, $this->generateSalt());
|
||||
}
|
||||
|
||||
public function updateHtaccessPassword(PhutilOpaqueEnvelope $password) {
|
||||
// Get custom fields list.
|
||||
$field_list = PhabricatorCustomField::getObjectFields(
|
||||
$this,
|
||||
PhabricatorCustomField::ROLE_APPLICATIONTRANSACTIONS);
|
||||
$field_list
|
||||
->setViewer($this)
|
||||
->readFieldsFromStorage($this);
|
||||
$fields = $field_list->getFields();
|
||||
// Generate new hash for htaccess password.
|
||||
$htaccess_hash = $this->generateHtaccessPassword($password->openEnvelope());
|
||||
// Generate transaction to update custom field.
|
||||
$xactions = array();
|
||||
$xaction = $this->getCustomFieldAction(
|
||||
$fields,
|
||||
'std:user:htaccess_password_hash',
|
||||
$htaccess_hash);
|
||||
if ($xaction) {
|
||||
$xactions[] = $xaction;
|
||||
}
|
||||
// Apply transactions.
|
||||
if (count($xactions)) {
|
||||
$editor = id(new PhabricatorUserTransactionEditor())
|
||||
->setActor($this)
|
||||
->setContentSource($xactions[0]->getContentSource());
|
||||
$editor->applyTransactions($this, $xactions);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private function getCustomFieldAction($fields, $field_name, $value) {
|
||||
$field = idx($fields, $field_name);
|
||||
if (!$field)
|
||||
return null;
|
||||
$old_value = $field->getOldValueForApplicationTransactions();
|
||||
return id(new PhabricatorUserTransaction())
|
||||
->setTransactionType(PhabricatorTransactions::TYPE_CUSTOMFIELD)
|
||||
->setMetadataValue('customfield:key', $field->getFieldKey())
|
||||
->setOldValue($old_value)
|
||||
->setNewValue($value);
|
||||
}
|
||||
|
||||
public function getMonogram() {
|
||||
return '@'.$this->getFullname();
|
||||
}
|
||||
|
||||
public function getMonogramForCommand() {
|
||||
return '@'.$this->getUsername();
|
||||
}
|
||||
|
||||
public function isLoggedIn() {
|
||||
return !($this->getPHID() === null);
|
||||
}
|
||||
@@ -534,6 +608,8 @@ final class PhabricatorUser
|
||||
}
|
||||
|
||||
public function getProfileImageURI() {
|
||||
return '/rsrc/image/avatar.png';
|
||||
|
||||
$uri_key = PhabricatorUserProfileImageCacheType::KEY_URI;
|
||||
return $this->requireCacheData($uri_key);
|
||||
}
|
||||
@@ -555,7 +631,7 @@ final class PhabricatorUser
|
||||
|
||||
public function getFullName() {
|
||||
if (strlen($this->getRealName())) {
|
||||
return $this->getUsername().' ('.$this->getRealName().')';
|
||||
return $this->getRealName().' ('.$this->getUsername().')';
|
||||
} else {
|
||||
return $this->getUsername();
|
||||
}
|
||||
@@ -908,6 +984,10 @@ final class PhabricatorUser
|
||||
return $this->handlePool->newHandleList($phids);
|
||||
}
|
||||
|
||||
public function getHandlePool() {
|
||||
return $this->handlePool;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get a @{class:PHUIHandleView} for a single handle.
|
||||
@@ -1016,7 +1096,7 @@ final class PhabricatorUser
|
||||
if ($this->getIsSystemAgent() || $this->getIsMailingList()) {
|
||||
return PhabricatorPolicies::POLICY_ADMIN;
|
||||
} else {
|
||||
return PhabricatorPolicies::POLICY_NOONE;
|
||||
return PhabricatorPolicies::POLICY_ADMIN;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1420,7 +1500,7 @@ final class PhabricatorUser
|
||||
|
||||
$parts = array(
|
||||
$this->getUsername(),
|
||||
$envelope->openEnvelope(),
|
||||
md5($envelope->openEnvelope()),
|
||||
$this->getPHID(),
|
||||
$password->getPasswordSalt(),
|
||||
);
|
||||
@@ -1458,5 +1538,19 @@ final class PhabricatorUser
|
||||
return $list;
|
||||
}
|
||||
|
||||
// Blender: Limit certain workflow steps to regular contributors, making it
|
||||
// easier to follow status of the tracker.
|
||||
public function limitNonContributorUI() {
|
||||
if ($this->getIsAdmin()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$project = id(new PhabricatorProjectQuery())
|
||||
->setViewer($this)
|
||||
->withNames(array('Moderators'))
|
||||
->withMemberPHIDs(array($this->getPHID()))
|
||||
->executeOne();
|
||||
|
||||
return is_null($project);
|
||||
}
|
||||
}
|
||||
|
@@ -121,9 +121,9 @@ final class PhabricatorUserCardView extends AphrontTagView {
|
||||
$user->getUsername());
|
||||
|
||||
$image = phutil_tag(
|
||||
'a',
|
||||
'span',
|
||||
array(
|
||||
'href' => $href,
|
||||
// 'href' => $href,
|
||||
'class' => 'project-card-image-href',
|
||||
),
|
||||
$image);
|
||||
|
@@ -0,0 +1,68 @@
|
||||
<?php
|
||||
|
||||
final class PhabricatorUserDisableSpamTransaction
|
||||
extends PhabricatorUserTransactionType {
|
||||
|
||||
const TRANSACTIONTYPE = 'user.disable_spam';
|
||||
|
||||
public function generateOldValue($object) {
|
||||
$user = $object;
|
||||
return (string)$user->getRealName();
|
||||
}
|
||||
|
||||
public function generateNewValue($object, $value) {
|
||||
// Deliberately not using 'spam'.
|
||||
// This way we can use this button even for accounts that
|
||||
// have been already manually renamed to 'spam'.
|
||||
// Otherwise when the name clash with the existing name
|
||||
// none of the changes happens.
|
||||
return 'disabled_spam';
|
||||
}
|
||||
|
||||
public function applyInternalEffects($object, $value) {
|
||||
$user = $object;
|
||||
$user->setRealName('spam');
|
||||
$profile = $user->loadUserProfile();
|
||||
$profile->setBlurb('');
|
||||
$profile->setTitle('');
|
||||
$profile->setIcon('');
|
||||
|
||||
$file = PhabricatorFile::loadBuiltin($user, 'profile.png');
|
||||
$user->setProfileImagePHID($file->getPHID());
|
||||
}
|
||||
|
||||
public function getTitle() {
|
||||
return pht(
|
||||
'%s set this user as spam.',
|
||||
$this->renderAuthor());
|
||||
}
|
||||
|
||||
public function shouldHideForFeed() {
|
||||
// Don't publish feed stories about handling spam.
|
||||
return true;
|
||||
}
|
||||
|
||||
public function validateTransactions($object, array $xactions) {
|
||||
$errors = array();
|
||||
|
||||
foreach ($xactions as $xaction) {
|
||||
|
||||
// You must have the "Can Disable Spam Users" permission to disable a user as spam.
|
||||
$this->requireApplicationCapability(
|
||||
PeopleDisableSpamUsersCapability::CAPABILITY);
|
||||
|
||||
if ($this->getActingAsPHID() === $object->getPHID()) {
|
||||
$errors[] = $this->newInvalidError(
|
||||
pht('You can not disable your own account as spam.'));
|
||||
}
|
||||
}
|
||||
|
||||
return $errors;
|
||||
}
|
||||
|
||||
public function getRequiredCapabilities(
|
||||
$object,
|
||||
PhabricatorApplicationTransaction $xaction) {
|
||||
return null;
|
||||
}
|
||||
}
|
@@ -146,7 +146,16 @@ final class PhabricatorObjectHandle
|
||||
}
|
||||
|
||||
public function getURI() {
|
||||
return $this->uri;
|
||||
$type = $this->getType();
|
||||
if ($type == 'TASK') {
|
||||
// XXX: Use real link to gitea task
|
||||
// At least for now rely on the existence of the manip[hest task redirector.
|
||||
// return 'https://developer.blender.org' . $this->uri;
|
||||
return $this->uri;
|
||||
} else if ($type == 'DREV' || $type == 'DIFF' || $type == 'PSTE' || $type == 'FILE') {
|
||||
return $this->uri;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public function setPHID($phid) {
|
||||
@@ -357,7 +366,7 @@ final class PhabricatorObjectHandle
|
||||
);
|
||||
|
||||
return javelin_tag(
|
||||
$uri ? 'a' : 'span',
|
||||
$uri ? 'a' : 'b',
|
||||
$attributes,
|
||||
array($circle, $icon, $name));
|
||||
}
|
||||
@@ -374,7 +383,7 @@ final class PhabricatorObjectHandle
|
||||
public function getLinkName() {
|
||||
switch ($this->getType()) {
|
||||
case PhabricatorPeopleUserPHIDType::TYPECONST:
|
||||
$name = $this->getName();
|
||||
$name = $this->getFullName();
|
||||
break;
|
||||
default:
|
||||
$name = $this->getFullName();
|
||||
|
@@ -22,6 +22,10 @@ final class PhabricatorHandlePool extends Phobject {
|
||||
return $this->viewer;
|
||||
}
|
||||
|
||||
public function getHandles() {
|
||||
return $this->handles;
|
||||
}
|
||||
|
||||
public function newHandleList(array $phids) {
|
||||
// Mark any PHIDs we haven't loaded yet as unloaded. This will let us bulk
|
||||
// load them later.
|
||||
|
@@ -56,7 +56,7 @@ final class PhabricatorProjectApplication extends PhabricatorApplication {
|
||||
'profile/(?P<id>[1-9]\d*)/'
|
||||
=> 'PhabricatorProjectProfileController',
|
||||
'view/(?P<id>[1-9]\d*)/'
|
||||
=> 'PhabricatorProjectViewController',
|
||||
=> 'PhabricatorProjectProfileController',
|
||||
'picture/(?P<id>[1-9]\d*)/'
|
||||
=> 'PhabricatorProjectEditPictureController',
|
||||
$this->getEditRoutePattern('edit/')
|
||||
@@ -125,7 +125,7 @@ final class PhabricatorProjectApplication extends PhabricatorApplication {
|
||||
=> 'PhabricatorProjectSubprojectWarningController',
|
||||
),
|
||||
'/tag/' => array(
|
||||
'(?P<slug>[^/]+)/' => 'PhabricatorProjectViewController',
|
||||
'(?P<slug>[^/]+)/' => 'PhabricatorProjectProfileController',
|
||||
'(?P<slug>[^/]+)/board/' => 'PhabricatorProjectBoardViewController',
|
||||
),
|
||||
);
|
||||
|
@@ -178,8 +178,10 @@ final class PhabricatorProjectBoardViewController
|
||||
$panel->addClass('project-panel-hidden');
|
||||
}
|
||||
|
||||
$column_menu = $this->buildColumnMenu($project, $column);
|
||||
$panel->addHeaderAction($column_menu);
|
||||
if (!$viewer->limitNonContributorUI()) {
|
||||
$column_menu = $this->buildColumnMenu($project, $column);
|
||||
$panel->addHeaderAction($column_menu);
|
||||
}
|
||||
|
||||
if ($column->canHaveTrigger()) {
|
||||
$trigger = $column->getTrigger();
|
||||
|
@@ -60,7 +60,7 @@ final class PhabricatorProjectsCurtainExtension
|
||||
),
|
||||
$column_name);
|
||||
|
||||
$annotation[] = $column_link;
|
||||
// $annotation[] = $column_link;
|
||||
}
|
||||
|
||||
if ($annotation) {
|
||||
|
@@ -37,7 +37,7 @@ final class PhabricatorProjectProjectPHIDType extends PhabricatorPHIDType {
|
||||
foreach ($handles as $phid => $handle) {
|
||||
$project = $objects[$phid];
|
||||
|
||||
$name = $project->getDisplayName();
|
||||
$name = $project->getDisplayNameWithAncestorPath();
|
||||
$id = $project->getID();
|
||||
$slug = $project->getPrimarySlug();
|
||||
|
||||
|
@@ -224,6 +224,8 @@ final class PhabricatorProjectSearchEngine
|
||||
protected function getBuiltinQueryNames() {
|
||||
$names = array();
|
||||
|
||||
$names['active'] = pht('Active');
|
||||
|
||||
if ($this->requireViewer()->isLoggedIn()) {
|
||||
$names['joined'] = pht('Joined');
|
||||
}
|
||||
@@ -232,7 +234,6 @@ final class PhabricatorProjectSearchEngine
|
||||
$names['watching'] = pht('Watching');
|
||||
}
|
||||
|
||||
$names['active'] = pht('Active');
|
||||
$names['all'] = pht('All');
|
||||
|
||||
return $names;
|
||||
|
@@ -586,6 +586,27 @@ final class PhabricatorProject extends PhabricatorProjectDAO
|
||||
return $name;
|
||||
}
|
||||
|
||||
public function getDisplayNameWithAncestorPath() {
|
||||
// Figure out the ancestors for this project
|
||||
// so that we can prepend that to the display name.
|
||||
$ancestors = mpull(array_reverse($this->getAncestorProjects()), 'getName');
|
||||
$project_name_with_path = $this->getName();
|
||||
|
||||
if ($this->isMilestone()) {
|
||||
$project_name_with_path = pht(
|
||||
'%s (%s)',
|
||||
implode(' > ', $ancestors),
|
||||
$project_name_with_path);
|
||||
} else {
|
||||
$ancestors[] = $project_name_with_path;
|
||||
$project_name_with_path = implode(' > ', $ancestors);
|
||||
}
|
||||
|
||||
|
||||
// No pht usage, since we don't have translatable items.
|
||||
return $project_name_with_path;
|
||||
}
|
||||
|
||||
public function getDisplayIconKey() {
|
||||
if ($this->isMilestone()) {
|
||||
$key = PhabricatorProjectIconSet::getMilestoneIconKey();
|
||||
|
@@ -123,7 +123,7 @@ final class PhabricatorProjectDatasource
|
||||
|
||||
$proj_result = id(new PhabricatorTypeaheadResult())
|
||||
->setName($all_strings)
|
||||
->setDisplayName($proj->getDisplayName())
|
||||
->setDisplayName($proj->getDisplayNameWithAncestorPath())
|
||||
->setDisplayType($proj->getDisplayIconName())
|
||||
->setURI($proj->getURI())
|
||||
->setPHID($phid)
|
||||
|
@@ -162,14 +162,14 @@ final class PhabricatorRepositoryQuery
|
||||
|
||||
public function getBuiltinOrders() {
|
||||
return array(
|
||||
'committed' => array(
|
||||
'vector' => array('committed', 'id'),
|
||||
'name' => pht('Most Recent Commit'),
|
||||
),
|
||||
'name' => array(
|
||||
'vector' => array('name', 'id'),
|
||||
'name' => pht('Name'),
|
||||
),
|
||||
'committed' => array(
|
||||
'vector' => array('committed', 'id'),
|
||||
'name' => pht('Most Recent Commit'),
|
||||
),
|
||||
'callsign' => array(
|
||||
'vector' => array('callsign'),
|
||||
'name' => pht('Callsign'),
|
||||
|
@@ -140,6 +140,24 @@ final class PhabricatorRepositorySearchEngine
|
||||
);
|
||||
}
|
||||
|
||||
private function getOrderOptions() {
|
||||
return array(
|
||||
'name' => pht('Name'),
|
||||
'committed' => pht('Most Recent Commit'),
|
||||
'callsign' => pht('Callsign'),
|
||||
'created' => pht('Date Created'),
|
||||
);
|
||||
}
|
||||
|
||||
private function getOrderValues() {
|
||||
return array(
|
||||
'name' => PhabricatorRepositoryQuery::ORDER_NAME,
|
||||
'committed' => PhabricatorRepositoryQuery::ORDER_COMMITTED,
|
||||
'callsign' => PhabricatorRepositoryQuery::ORDER_CALLSIGN,
|
||||
'created' => PhabricatorRepositoryQuery::ORDER_CREATED,
|
||||
);
|
||||
}
|
||||
|
||||
private function getHostedOptions() {
|
||||
return array(
|
||||
'' => pht('Hosted and Remote Repositories'),
|
||||
|
@@ -1,6 +1,6 @@
|
||||
<?php
|
||||
|
||||
final class PhabricatorApplicationSearchController
|
||||
/*final*/ class PhabricatorApplicationSearchController
|
||||
extends PhabricatorSearchBaseController {
|
||||
|
||||
private $searchEngine;
|
||||
@@ -92,6 +92,10 @@ final class PhabricatorApplicationSearchController
|
||||
}
|
||||
}
|
||||
|
||||
protected function getDescriptionForQuery($named_query, $dao_query) {
|
||||
return '';
|
||||
}
|
||||
|
||||
private function processSearchRequest() {
|
||||
$parent = $this->getDelegatingController();
|
||||
$request = $this->getRequest();
|
||||
@@ -214,6 +218,7 @@ final class PhabricatorApplicationSearchController
|
||||
$title = pht('Advanced Search');
|
||||
}
|
||||
|
||||
|
||||
$header = id(new PHUIHeaderView())
|
||||
->setHeader($title)
|
||||
->setProfileHeader(true);
|
||||
@@ -255,6 +260,13 @@ final class PhabricatorApplicationSearchController
|
||||
|
||||
$objects = $engine->executeQuery($query, $pager);
|
||||
|
||||
$description_query = $engine->buildQueryFromSavedQuery($saved_query);
|
||||
$description_query->setViewer($this->getRequest()->getUser());
|
||||
$description = $this->getDescriptionForQuery($named_query, $description_query);
|
||||
if ($description) {
|
||||
$header->setHeader($description);
|
||||
}
|
||||
|
||||
$force_nux = $request->getBool('nux');
|
||||
if (!$objects || $force_nux) {
|
||||
$nux_view = $this->renderNewUserView($engine, $force_nux);
|
||||
|
@@ -95,7 +95,7 @@ final class PhabricatorSettingsMainController
|
||||
|
||||
$this->preferences = $preferences;
|
||||
|
||||
$panels = $this->buildPanels($preferences);
|
||||
$panels = $this->buildPanels($preferences, true);
|
||||
$nav = $this->renderSideNav($panels);
|
||||
|
||||
$key = $nav->selectFilter($key, head($panels)->getPanelKey());
|
||||
@@ -136,7 +136,7 @@ final class PhabricatorSettingsMainController
|
||||
->appendChild($view);
|
||||
}
|
||||
|
||||
private function buildPanels(PhabricatorUserPreferences $preferences) {
|
||||
private function buildPanels(PhabricatorUserPreferences $preferences, $hide_disabled) {
|
||||
$viewer = $this->getViewer();
|
||||
$panels = PhabricatorSettingsPanel::getAllDisplayPanels();
|
||||
|
||||
@@ -154,6 +154,10 @@ final class PhabricatorSettingsMainController
|
||||
continue;
|
||||
}
|
||||
|
||||
if ($hide_disabled && !$panel->isEnabledForUser($viewer)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ($this->isTemplate()) {
|
||||
if (!$panel->isTemplatePanel()) {
|
||||
continue;
|
||||
@@ -221,7 +225,7 @@ final class PhabricatorSettingsMainController
|
||||
|
||||
public function buildApplicationMenu() {
|
||||
if ($this->preferences) {
|
||||
$panels = $this->buildPanels($this->preferences);
|
||||
$panels = $this->buildPanels($this->preferences, false);
|
||||
return $this->renderSideNav($panels)->getMenu();
|
||||
}
|
||||
return parent::buildApplicationMenu();
|
||||
|
@@ -163,6 +163,9 @@ abstract class PhabricatorSettingsPanel extends Phobject {
|
||||
return true;
|
||||
}
|
||||
|
||||
public function isEnabledForUser($user) {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if this panel is available to users while editing their own
|
||||
|
@@ -0,0 +1,99 @@
|
||||
<?php
|
||||
|
||||
final class PhabricatorSettingsPanelChangeUsername
|
||||
extends PhabricatorSettingsPanel {
|
||||
|
||||
public function getPanelKey() {
|
||||
return 'changeusername';
|
||||
}
|
||||
|
||||
public function getPanelGroupKey() {
|
||||
return PhabricatorSettingsAccountPanelGroup::PANELGROUPKEY;
|
||||
}
|
||||
|
||||
public function getPanelName() {
|
||||
return pht('Change Username');
|
||||
}
|
||||
|
||||
public function getAlternatives($user) {
|
||||
$root = dirname(phutil_get_library_root('phabricator'));
|
||||
require $root.'/migration/dedup.php';
|
||||
|
||||
$alternatives = array();
|
||||
|
||||
foreach($migrate_dedup_users as $from_user => $to_user) {
|
||||
if($from_user == $user->getUserName()) {
|
||||
$alternatives[$to_user] = $to_user;
|
||||
}
|
||||
else if($to_user == $user->getUserName()) {
|
||||
$alternatives[$from_user] = $from_user;
|
||||
}
|
||||
}
|
||||
|
||||
return $alternatives;
|
||||
}
|
||||
|
||||
public function isEnabledForUser($user) {
|
||||
return count($this->getAlternatives($user)) > 0;
|
||||
}
|
||||
|
||||
public function processRequest(AphrontRequest $request) {
|
||||
$user = $request->getUser();
|
||||
$alternatives = $this->getAlternatives($user);
|
||||
$new_username = $request->getStr("new_username");
|
||||
|
||||
if ($request->isFormPost()) {
|
||||
if (array_key_exists($new_username, $alternatives)) {
|
||||
id(new PhabricatorUserEditor())
|
||||
->setActor($user)
|
||||
->changeUsername($user, $new_username);
|
||||
|
||||
return id(new AphrontRedirectResponse())
|
||||
->setURI($this->getPanelURI('?saved=true'));
|
||||
}
|
||||
}
|
||||
|
||||
$instructions = pht(
|
||||
"Multiple of your accounts were merged into one because because Phabricator does not " .
|
||||
"support multiple accounts with the same email address. Here you can change your " .
|
||||
"account name your preferred one. For security purposes you must also enter choose " .
|
||||
"your password again (can be the same or new), for this you will receive an email.\n\n" .
|
||||
"Current username: **" . $user->getUserName() . "**.");
|
||||
|
||||
$form = id(new AphrontFormView())
|
||||
->setUser($user)
|
||||
->appendRemarkupInstructions($instructions)
|
||||
->appendChild(
|
||||
id(new AphrontFormSelectControl())
|
||||
->setLabel(pht('Other Username'))
|
||||
->setName("new_username")
|
||||
->setValue($user->getUserName())
|
||||
->setOptions($alternatives))
|
||||
->appendChild(
|
||||
id(new AphrontFormSubmitControl())
|
||||
->setValue(pht('Change Username')));
|
||||
|
||||
$error_view = null;
|
||||
|
||||
if ($request->getBool('saved')) {
|
||||
$error_view = id(new AphrontErrorView())
|
||||
->setTitle(pht('Username changed'))
|
||||
->setSeverity(AphrontErrorView::SEVERITY_NOTICE)
|
||||
->setErrors(array(pht('Your username has been changed, check your mail inbox for instructions on how to reset your password.')));
|
||||
}
|
||||
|
||||
$errors = array();
|
||||
if ($error_view) {
|
||||
$errors[] = $error_view;
|
||||
}
|
||||
$form_box = id(new PHUIObjectBoxView())
|
||||
->setHeaderText(pht('Change Username'))
|
||||
->setFormErrors($errors)
|
||||
->setForm($form);
|
||||
|
||||
return array(
|
||||
$form_box,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@@ -76,14 +76,10 @@ final class PhabricatorSubscriptionsCurtainExtension
|
||||
}
|
||||
|
||||
if ($show_all) {
|
||||
$view_all_uri = urisprintf(
|
||||
'/subscriptions/list/%s/',
|
||||
$object_phid);
|
||||
|
||||
$ref_list->newTailLink()
|
||||
->setURI($view_all_uri)
|
||||
->setText(pht('View All %d Subscriber(s)', $subscriber_count))
|
||||
->setWorkflow(true);
|
||||
$num_extra = $subscriber_count - $max_visible;
|
||||
if ($num_extra > 0) {
|
||||
$ref_list->addTailObject("{$num_extra} More Subscribers");
|
||||
}
|
||||
}
|
||||
|
||||
return $this->newPanel()
|
||||
|
@@ -112,8 +112,8 @@ final class PhabricatorSubscriptionsUIEventListener
|
||||
|
||||
|
||||
$actions = $event->getValue('actions');
|
||||
$actions[] = $sub_action;
|
||||
$actions[] = $mute_action;
|
||||
// $actions[] = $sub_action;
|
||||
// $actions[] = $mute_action;
|
||||
$event->setValue('actions', $actions);
|
||||
}
|
||||
|
||||
|