Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
131b15fc7a | ||
|
|
f6b1583a1a | ||
|
|
5bea900443 | ||
|
|
81baddad00 | ||
|
|
f6b5632fec | ||
|
|
f7ede727fd | ||
|
|
b870417860 | ||
|
|
25a7838e0a | ||
|
|
7c3ddf2bc0 | ||
|
|
0f8df81b87 | ||
|
|
c5121d804d | ||
|
|
8bcbbebf65 | ||
|
|
2d2afab549 | ||
|
|
35f601e769 | ||
|
|
b84cffd62e | ||
|
|
2eba0b66d4 | ||
|
|
eb2d814344 | ||
|
|
d9385ce9a2 | ||
|
|
d3522c10e4 | ||
|
|
b9957264eb | ||
|
|
da641f4122 | ||
|
|
287d86e363 | ||
|
|
faf1f1e812 | ||
|
|
cd64338a7f | ||
|
|
1b8c5d4058 | ||
|
|
5ccbeba5c2 | ||
|
|
a381b0978f | ||
|
|
0dfa2ad3cf | ||
|
|
1bb51f743a | ||
|
|
85858cebe6 | ||
|
|
6331809bd9 | ||
|
|
b9e380c9fe | ||
|
|
8960200409 | ||
|
|
ef80597c39 | ||
|
|
ecc742f3ce | ||
|
|
7a434c902a | ||
|
|
d37a30846f | ||
|
|
805864590a | ||
|
|
1c49bd4258 | ||
|
|
051875429e | ||
|
|
6936eb1022 | ||
|
|
de5b0ad0a8 | ||
|
|
472654aebe | ||
|
|
5f78b8a9a0 | ||
|
|
7fb72e671b | ||
|
|
180fe8f6a4 | ||
|
|
60c12ca3ab | ||
|
|
a8e6f68aaf | ||
|
|
27cf6d8d64 | ||
|
|
09bf503fd2 | ||
|
|
35a14cbfdc | ||
|
|
bbf422e229 | ||
|
|
8ed97f43d2 | ||
|
|
4ff77cc624 | ||
|
|
0cccce0c43 | ||
|
|
43fc812e0e | ||
|
|
f162337e1b | ||
|
|
93a33c6286 | ||
|
|
3e102f281d | ||
|
|
7673d69b96 | ||
|
|
1c4bcc5b55 | ||
|
|
8cb5acf453 | ||
|
|
030afe7428 | ||
|
|
93d1b2e0a4 | ||
|
|
cab300e650 | ||
|
|
f271e772af | ||
|
|
4bd35dae8d | ||
|
|
2d01398d67 | ||
|
|
f5b5688e8a | ||
|
|
2eb085506b | ||
|
|
a8fcf8487d | ||
|
|
5b6978a1f3 | ||
|
|
888b254844 | ||
|
|
83061e9ca2 | ||
|
|
451aa6ba4e | ||
|
|
01fdaf5977 | ||
|
|
a59e6bfb02 | ||
|
|
185ecd5854 | ||
|
|
aec989707e | ||
|
|
993b60d61e | ||
|
|
4957752d12 | ||
|
|
b8b991a7dc | ||
|
|
cdf3e2b6ef | ||
|
|
84d2ea054d | ||
|
|
076d9e7ade | ||
|
|
c67c375357 | ||
|
|
87fb78be0b | ||
|
|
eafaae73b7 | ||
|
|
4f16dc53a4 | ||
|
|
ea161c9ea4 | ||
|
|
2c1e63720e | ||
|
|
d4429a544c | ||
|
|
3a9b0988c7 | ||
|
|
6fcc512cb7 | ||
|
|
3a75b6771f | ||
|
|
a9c972fbb3 | ||
|
|
71d3bb2f7b | ||
|
|
624723d0ce | ||
|
|
64fb0a561a | ||
|
|
76a29ae337 | ||
|
|
4f35ec97e8 | ||
|
|
8195f95464 | ||
|
|
494a6ecfb0 | ||
|
|
66594d46b2 | ||
|
|
0ec13848b0 | ||
|
|
a92cce3851 | ||
|
|
522b9e6b5b | ||
|
|
07882590bb | ||
|
|
9b59ea7256 | ||
|
|
1830064918 | ||
|
|
a4c6c62c8b | ||
|
|
4458a7282b | ||
|
|
e8035c22b2 | ||
|
|
482d9a4e82 | ||
|
|
533994e5ea | ||
|
|
e951d84584 | ||
|
|
bbe8ea29e8 | ||
|
|
fbcdfee622 | ||
|
|
a70737ad59 | ||
|
|
745fec76d0 | ||
|
|
1eca3947a1 | ||
|
|
d09f7d73b3 | ||
|
|
c61424e57a | ||
|
|
b0754ca720 | ||
|
|
4f9f3097d9 | ||
|
|
d8c97b32dd | ||
|
|
918937c873 | ||
|
|
942091f9e8 | ||
|
|
8ea2ecb983 | ||
|
|
7ee55562ff | ||
|
|
c01c64e978 | ||
|
|
87742f23ed | ||
|
|
9daf39ec52 | ||
|
|
4b15dc10c1 | ||
|
|
b6bd5c7f12 | ||
|
|
1ddb59df2a | ||
|
|
200842ba5e | ||
|
|
421d420311 | ||
|
|
8531e176aa | ||
|
|
328df74dd1 | ||
|
|
792b7f30e3 | ||
|
|
b0bb41ad35 | ||
|
|
b935aebd99 | ||
|
|
ade572048a | ||
|
|
7d10755072 | ||
|
|
3f4a8469ac | ||
|
|
d461363d27 | ||
|
|
948097bc4d | ||
|
|
09bd61da74 | ||
|
|
652dc1a73a | ||
|
|
e5daf25618 | ||
|
|
5d6d0136c1 | ||
|
|
d69a05a6ee | ||
|
|
33493f8010 | ||
|
|
a798a1ac4d | ||
|
|
53a04b0a44 | ||
|
|
0153954ebb | ||
|
|
153c4c242d | ||
|
|
0582337372 | ||
|
|
1c8cf4ef83 | ||
|
|
abb0b15407 | ||
|
|
384a444cee | ||
|
|
38307c0979 | ||
|
|
96b78fdae5 | ||
|
|
377a45ae1a | ||
|
|
29e297d273 | ||
|
|
71d089c833 | ||
|
|
8adb320978 | ||
|
|
0b6a010a12 | ||
|
|
4dc7f662e3 | ||
|
|
a2626bbccf | ||
|
|
616899d879 | ||
|
|
30a7314b86 | ||
|
|
c5d998528f | ||
|
|
93ef8b7f77 | ||
|
|
15ed53cf17 | ||
|
|
5152771fdd | ||
|
|
913a806f90 | ||
|
|
d859d38dd9 | ||
|
|
14b3d6d012 | ||
|
|
4155c97222 | ||
|
|
43a6f312ed | ||
|
|
6d109258c9 | ||
|
|
9a2ec76a81 | ||
|
|
c80c1e1ead | ||
|
|
943ba3e34f | ||
|
|
68d3305ae2 | ||
|
|
fde2a497da | ||
|
|
14b2d3f4b9 | ||
|
|
54ff294da1 | ||
|
|
80a60247f5 | ||
|
|
a3dda6dc4a | ||
|
|
4e244be21c | ||
|
|
09cfef094c | ||
|
|
9c451ac157 | ||
|
|
5dd3c239d3 | ||
|
|
0beafecd3b | ||
|
|
2920daf2c8 | ||
|
|
c3d909e0cc | ||
|
|
1ecef3a95a | ||
|
|
b124501a4e | ||
|
|
225637c5dc | ||
|
|
0123dc3651 | ||
|
|
12c0f5f66e | ||
|
|
45b69c4a65 | ||
|
|
bea49ae245 | ||
|
|
4abb82fd7b | ||
|
|
79f92a675a | ||
|
|
3d5d1a38e3 | ||
|
|
e13f49d919 | ||
|
|
7a1e928b8d | ||
|
|
b0f3de5c3b | ||
|
|
2247700f24 | ||
|
|
d8ac6d2b79 | ||
|
|
2d9e669e85 | ||
|
|
d54ba39e7a | ||
|
|
91dc13f4b2 | ||
|
|
97e7432ce6 | ||
|
|
dad5f6d403 | ||
|
|
c65ab7c0f2 | ||
|
|
d6bfb7fa4d | ||
|
|
59c5d995c3 | ||
|
|
df99d8f308 | ||
|
|
d5b9dedca2 | ||
|
|
0b4a02f607 | ||
|
|
b6549d763a | ||
|
|
5e2a01656d | ||
|
|
d79c20c4f2 | ||
|
|
889bf388be | ||
|
|
16e9ffce0d | ||
|
|
44ac1a0deb | ||
|
|
1b002983c3 | ||
|
|
1535ac1220 | ||
|
|
2a945f794f | ||
|
|
0faa4568a0 | ||
|
|
3e031b4243 | ||
|
|
32b9bf0ef2 | ||
|
|
1c5a9b1773 | ||
|
|
061977d77d | ||
|
|
049051103b | ||
|
|
18066ba8bf | ||
|
|
ad25d15d6c | ||
|
|
e228110614 | ||
|
|
8a39862b19 | ||
|
|
bf3066d698 | ||
|
|
35c17355fb | ||
|
|
702b521b45 | ||
|
|
4e1e5985a1 | ||
|
|
8b710cf9de | ||
|
|
df30e18a8c | ||
|
|
64eaf328ea | ||
|
|
941f9bf3dd | ||
|
|
a39f655a7c | ||
|
|
84cdc8f2bc | ||
|
|
b2b56adbfa | ||
|
|
a80dbc49b1 | ||
|
|
78d9ae9754 | ||
|
|
3d920c13b4 | ||
|
|
976a31e941 | ||
|
|
4a729036bf | ||
|
|
c9fd7513ed | ||
|
|
8d9b04865b | ||
|
|
4024f4ac39 | ||
|
|
6ae87d7c4c | ||
|
|
860ff9345f | ||
|
|
bd85c0cbb1 | ||
|
|
832c7eaaa5 | ||
|
|
b21e85b6dc | ||
|
|
3e0acc0b7e | ||
|
|
636579b17d | ||
|
|
97f0da0b1a | ||
|
|
9072753489 | ||
|
|
66420fe4b7 | ||
|
|
5bc7dc77e2 | ||
|
|
9a1b46fe42 | ||
|
|
7eec539222 | ||
|
|
7f3c516940 | ||
|
|
3ff95e4031 | ||
|
|
bb8d360188 | ||
|
|
9595029709 | ||
|
|
31c6ebb310 | ||
|
|
3d5381b24b | ||
|
|
a456225852 | ||
|
|
5f871e9657 | ||
|
|
bf3b2ec973 | ||
|
|
49bdf62243 | ||
|
|
e219af1fbd | ||
|
|
4a2efa9252 | ||
|
|
8e00f57a88 | ||
|
|
524cd689cf | ||
|
|
b4eafd9ea8 | ||
|
|
2bcd448dda | ||
|
|
1af9c47a27 | ||
|
|
ea35fff5bf | ||
|
|
124ef65c1f | ||
|
|
361c50c1f4 | ||
|
|
27d6334afa | ||
|
|
963b1283c2 | ||
|
|
777edc13c1 | ||
|
|
d1a3fbea40 | ||
|
|
58610ec52a | ||
|
|
38b185f1dc | ||
|
|
e69631f26c | ||
|
|
47f399104b | ||
|
|
86319feef2 | ||
|
|
eb7cbd481e | ||
|
|
17c7886791 | ||
|
|
48949f979a | ||
|
|
86d756d22d | ||
|
|
ab4ff48abc | ||
|
|
63ef594033 | ||
|
|
bd8eded670 | ||
|
|
d5cc40c9b6 | ||
|
|
76ed8cc200 | ||
|
|
3539bef96b | ||
|
|
e29539df9c | ||
|
|
7e9c454478 | ||
|
|
c00b8fd12e | ||
|
|
6d9490ddcc | ||
|
|
f58db70bde | ||
|
|
51adc242a3 | ||
|
|
7fae4b0892 | ||
|
|
6239e319ac | ||
|
|
60c82a03db | ||
|
|
36c0ab196c | ||
|
|
a7c2b63fb6 | ||
|
|
5e38bd9363 | ||
|
|
a79cf8d574 | ||
|
|
3c44aac1f5 | ||
|
|
355289fa67 | ||
|
|
b536f4c657 | ||
|
|
d00014221e | ||
|
|
3b4cfe0ba8 | ||
|
|
056e3703da | ||
|
|
92a23c05bb | ||
|
|
7d8af70a63 | ||
|
|
8c65cc4712 | ||
|
|
e4724c7626 | ||
|
|
6e74a06808 | ||
|
|
bc060b31ae | ||
|
|
aebcfb1eda | ||
|
|
457c9a8e72 | ||
|
|
3f2f7153a9 | ||
|
|
f5d68cf688 | ||
|
|
81ada666bb | ||
|
|
db002edabd | ||
|
|
3baf086e2d | ||
|
|
2cf11bd64e | ||
|
|
bf6e02c739 | ||
|
|
233990dac3 | ||
|
|
c383486d71 | ||
|
|
508b0bbb8e | ||
|
|
3937caeb3c | ||
|
|
f2a12d9eb5 | ||
|
|
acad206063 | ||
|
|
f80f04e379 | ||
|
|
fde4a42e2a | ||
|
|
29b3614bcb | ||
|
|
866e9e2503 | ||
|
|
c21ee95ade | ||
|
|
7704e2d919 | ||
|
|
0634591b3d | ||
|
|
5e6fa147da | ||
|
|
8d91afc33e | ||
|
|
987a5aa221 | ||
|
|
99f9aea80a | ||
|
|
deb182337d | ||
|
|
a1f3497ec4 | ||
|
|
9c9ae21771 | ||
|
|
f8aa2dc9b7 | ||
|
|
bb2de53d93 | ||
|
|
e2c606e974 | ||
|
|
9ad79612fe | ||
|
|
1469a4c8df | ||
|
|
76cdef46f2 | ||
|
|
e4ce95c3a1 | ||
|
|
4951676172 | ||
|
|
b0a8888e35 | ||
|
|
833c7bd659 | ||
|
|
5944696b6d | ||
|
|
a727f0d25a | ||
|
|
0fe5c7b3e0 | ||
|
|
843d04f0e3 | ||
|
|
8a8f819d27 | ||
|
|
a8419c1425 | ||
|
|
362364fd6f | ||
|
|
b0bb1baeaa | ||
|
|
1454a711ca | ||
|
|
fa95501fe5 | ||
|
|
a069c4afcf | ||
|
|
cc8220dde8 | ||
|
|
63ceea2e21 | ||
|
|
ad68a82be1 | ||
|
|
8509cf80f0 | ||
|
|
26a1ae4808 | ||
|
|
040cfa6ae2 | ||
|
|
d0af24870e | ||
|
|
308118ce97 | ||
|
|
7535c211d5 | ||
|
|
d46e3a501e | ||
|
|
d4e47d5d64 | ||
|
|
11cf016c58 | ||
|
|
bd434427e6 | ||
|
|
4ded4277c5 | ||
|
|
b60bedafc0 | ||
|
|
9a3d743ae5 | ||
|
|
0af6f34758 | ||
|
|
bb4acc02d0 | ||
|
|
d9e6359a83 | ||
|
|
8610b191ae | ||
|
|
01ef9f12c8 | ||
|
|
24ec30b10c | ||
|
|
152a5da64d | ||
|
|
295e8c86ab | ||
|
|
5d1d778ed5 | ||
|
|
8f7f305f7c | ||
|
|
33003e5b2d | ||
|
|
8ca4d35dcc | ||
|
|
b30b6717a2 | ||
|
|
cedca57620 | ||
|
|
0d605006a3 | ||
|
|
a200e97667 | ||
|
|
2ee11c9089 | ||
|
|
01105966d9 | ||
|
|
90d33c3e51 | ||
|
|
eacd050630 | ||
|
|
0e4e0a795a | ||
|
|
ecfc40629f | ||
|
|
0006c5f3b0 | ||
|
|
3c42abe07e | ||
|
|
11cc0a4857 | ||
|
|
11f7a13971 | ||
|
|
d10e9f1157 | ||
|
|
f3eeff03c4 | ||
|
|
49eb65e925 | ||
|
|
4c509c9423 | ||
|
|
9ce5713ee4 | ||
|
|
b9cc65db61 | ||
|
|
74ecb37be6 | ||
|
|
7d54215ccb | ||
|
|
58b67fa914 | ||
|
|
f55a5e4572 | ||
|
|
a53c86f063 | ||
|
|
dead6a28f8 | ||
|
|
0682b8cfc4 | ||
|
|
4b3ff7af50 | ||
|
|
65e05d822a | ||
|
|
bce286f458 | ||
|
|
b950caa21e | ||
|
|
3a0cd55622 | ||
|
|
f7daee47a6 | ||
|
|
7486125e6d | ||
|
|
ff2e031400 | ||
|
|
2ce184d1de | ||
|
|
3844e4bca8 | ||
|
|
38f540a701 | ||
|
|
5f10cc8673 | ||
|
|
45203143c1 | ||
|
|
6b63889fcd | ||
|
|
824a67ab5a | ||
|
|
2c4647f8c6 | ||
|
|
df631e8c06 | ||
|
|
ec51cdd0f9 | ||
|
|
cdb2781b48 | ||
|
|
bb724e75c0 | ||
|
|
5259dec061 | ||
|
|
75c4c4f6b3 | ||
|
|
fa094a3fe5 | ||
|
|
31467731fa | ||
|
|
57d3dd3b80 | ||
|
|
26528d1004 | ||
|
|
df8945177a | ||
|
|
69c2965051 | ||
|
|
e8971e5f83 | ||
|
|
73dba2ac04 | ||
|
|
fd7910efc9 | ||
|
|
185547af69 | ||
|
|
c216ab325b | ||
|
|
479b9b5433 | ||
|
|
f6f1fee92f | ||
|
|
a32d6a49c0 | ||
|
|
586231067b | ||
|
|
cb8bee3a4e | ||
|
|
20b4e226fe | ||
|
|
c3e3a1891b | ||
|
|
47e7ceacd7 | ||
|
|
48fb20f540 | ||
|
|
0fc93a1197 | ||
|
|
0f966dbcfd | ||
|
|
ca094446b3 | ||
|
|
50096526bc | ||
|
|
c6e8cf5c21 | ||
|
|
c6e61a5f19 | ||
|
|
514cdacc87 | ||
|
|
96b4ac12cb | ||
|
|
e5f5671d66 | ||
|
|
427b47b4d7 | ||
|
|
c2220cffcf | ||
|
|
3e86dde31e | ||
|
|
665497f5fb | ||
|
|
dc74a1780f | ||
|
|
3cacd4b3b9 | ||
|
|
b4d66593ef | ||
|
|
cae547a7ea | ||
|
|
f2a5304d64 | ||
|
|
b64e89daec | ||
|
|
66c8c1e292 | ||
|
|
05e27d0d83 | ||
|
|
e1bb4a5baa | ||
|
|
20aff7cc70 | ||
|
|
d823c28484 | ||
|
|
a96421019f | ||
|
|
d723bea502 | ||
|
|
4b430e6ce2 | ||
|
|
19f2853a2a | ||
|
|
24b000fb24 | ||
|
|
964c550a60 | ||
|
|
650888c73b | ||
|
|
042ef42da0 | ||
|
|
42fe6c6e04 | ||
|
|
dfffa0a7f8 | ||
|
|
f3673aff28 | ||
|
|
dd6f438fd1 | ||
|
|
9a360bd574 | ||
|
|
dbcf2065b8 | ||
|
|
e4f0864e3a | ||
|
|
a42a115b8f | ||
|
|
2b77964468 | ||
|
|
fe7c0d6484 | ||
|
|
384cbadce6 | ||
|
|
827e998afe | ||
|
|
43f583d332 | ||
|
|
99dcf2ffe5 | ||
|
|
31eda0fcb2 | ||
|
|
83eed09109 | ||
|
|
25012efc9c | ||
|
|
eb371db5b9 | ||
|
|
f23daffd7d | ||
|
|
29413d6bee | ||
|
|
fc64fc3e9c | ||
|
|
a2206ab5a0 | ||
|
|
00bf5f04db | ||
|
|
780d5fa070 | ||
|
|
1c69c43293 | ||
|
|
fa969504d4 | ||
|
|
3c6ddc9cec | ||
|
|
89b349818b | ||
|
|
4967f10356 | ||
|
|
f2a058f8cf | ||
|
|
23264ec3eb | ||
|
|
1fa1f62018 | ||
|
|
8929bfca63 | ||
|
|
21c97c6a13 | ||
|
|
29348fafb7 | ||
|
|
74ed14f8a2 | ||
|
|
6db28b3899 | ||
|
|
1590ad2518 | ||
|
|
b4d9ca8875 | ||
|
|
f6fe15716e | ||
|
|
f3364b9dce | ||
|
|
7d899166c6 | ||
|
|
27d6da9457 | ||
|
|
7e4611ad31 | ||
|
|
fdf842a4c4 | ||
|
|
b812705976 | ||
|
|
98a01d62c2 | ||
|
|
422677b9b7 | ||
|
|
42db3cac06 | ||
|
|
22c5e0d614 | ||
|
|
22ad806a43 | ||
|
|
0803e6fcaa | ||
|
|
1b2e80545a | ||
|
|
8dcc041244 | ||
|
|
c27106d859 | ||
|
|
a19a0d7b92 | ||
|
|
17a3f9e44c | ||
|
|
f16ab838d8 | ||
|
|
6260892949 | ||
|
|
8a3e713f2f | ||
|
|
324b904ed5 | ||
|
|
b1cafef07a | ||
|
|
70da1c7771 | ||
|
|
3ae8c53cba | ||
|
|
eb6ab2af50 | ||
|
|
72b5cd3889 | ||
|
|
a2439f3b34 | ||
|
|
e76d153064 | ||
|
|
521f4a6ddb | ||
|
|
296b6aee5a | ||
|
|
c6ac590d17 | ||
|
|
1281d99f30 | ||
|
|
c68dac7e9a | ||
|
|
6bdc13b33d | ||
|
|
404bfce446 | ||
|
|
1187ad96ac | ||
|
|
840f18b1c7 | ||
|
|
088563db3e | ||
|
|
bd6ab74318 | ||
|
|
fc1024a52a | ||
|
|
05ff26c141 | ||
|
|
39c9874a41 | ||
|
|
317b460d96 | ||
|
|
c8b3c8dfec | ||
|
|
603e11d7a5 | ||
|
|
8da5bad295 | ||
|
|
452a20a69a | ||
|
|
edba1f692b | ||
|
|
c1eb587c6d | ||
|
|
db4781d068 | ||
|
|
4fa51992b5 | ||
|
|
b96dc97d15 | ||
|
|
0a629237fd | ||
|
|
f44f6c7876 | ||
|
|
4dad4fab50 | ||
|
|
72714d86f6 | ||
|
|
c754e017dc | ||
|
|
138566de0b | ||
|
|
1e28f7758f | ||
|
|
f601d5fb9e | ||
|
|
d1780270da | ||
|
|
00238738b1 | ||
|
|
7b366758fd | ||
|
|
a7033c8bac | ||
|
|
446889b3f0 | ||
|
|
4cedecad4d | ||
|
|
1f991c6a79 | ||
|
|
2f0edb0b61 | ||
|
|
5b35bfd434 | ||
|
|
889d50089d | ||
|
|
a5849ee044 | ||
|
|
38e0c237a4 | ||
|
|
c4239a4fd2 | ||
|
|
7379d4e2d0 | ||
|
|
f94be4f8ab | ||
|
|
3eec500320 | ||
|
|
c16e27625c | ||
|
|
5313f48ff4 | ||
|
|
0061a3f04a | ||
|
|
7e755a53b8 | ||
|
|
ecf208f660 | ||
|
|
b3f3634df3 | ||
|
|
29c623fa58 | ||
|
|
343cab8148 | ||
|
|
f179eee7a0 | ||
|
|
5b4812add8 | ||
|
|
005ce1b21d | ||
|
|
1dcf50b59a | ||
|
|
a8b202c9bc | ||
|
|
64d805b009 | ||
|
|
79b8bd0a38 | ||
|
|
cf4e216502 | ||
|
|
1eff42eda6 | ||
|
|
5478e5cbae | ||
|
|
29f25601bb | ||
|
|
e4f2e0fd37 | ||
|
|
4e65be9ed1 | ||
|
|
6862b97909 | ||
|
|
64e91b2e13 | ||
|
|
9f0ddb89a0 | ||
|
|
e9ba8a4494 | ||
|
|
58ea44a462 | ||
|
|
7681487af4 | ||
|
|
c4fee11969 | ||
|
|
5bd26ede42 | ||
|
|
3c8e7c79b6 | ||
|
|
3be226d0c4 | ||
|
|
dfaf8f7e6a | ||
|
|
acebceb1d7 | ||
|
|
2d5ac54d2e | ||
|
|
7701de9ae4 | ||
|
|
46745614b4 | ||
|
|
efbe29249c | ||
|
|
188077d634 | ||
|
|
f8da6fb679 | ||
|
|
6edfcd83c1 | ||
|
|
fcefdb22bf | ||
|
|
7363428703 | ||
|
|
25f8c64f92 | ||
|
|
fd2839c833 | ||
|
|
1cb5fc747f | ||
|
|
4670426e4e | ||
|
|
05c1888703 | ||
|
|
e94e88e3ad | ||
|
|
9c38458f8b | ||
|
|
98cf33070f | ||
|
|
5e20417e6d | ||
|
|
bf74efcd11 | ||
|
|
384aa50be3 | ||
|
|
8687401d65 | ||
|
|
7eba6786d3 | ||
|
|
65be9d3c86 | ||
|
|
87bad767c6 | ||
|
|
f816d4f378 | ||
|
|
184be9d0e3 | ||
|
|
7eb3b186c4 | ||
|
|
ba1b857197 | ||
|
|
faa3d984ab | ||
|
|
6d7a855ca2 | ||
|
|
600018d5ad | ||
|
|
ec44c94c12 | ||
|
|
48c2a690c2 | ||
|
|
1a2aee84b2 | ||
|
|
1c44600c62 | ||
|
|
5332c4362c | ||
|
|
f2acb56041 | ||
|
|
ff1343882a | ||
|
|
2dbb397818 | ||
|
|
136a2a614b | ||
|
|
a681d8bf4d | ||
|
|
438161ad1f | ||
|
|
4dddb606a6 | ||
|
|
22c7419a70 | ||
|
|
7fb03b1ca3 | ||
|
|
97f6315bd0 | ||
|
|
e7ff47cff5 | ||
|
|
4a20ece43e | ||
|
|
b2d4666bf1 | ||
|
|
515caa8f37 | ||
|
|
4cf1b68969 | ||
|
|
413247ee5b | ||
|
|
70374d084e | ||
|
|
f335e943ad | ||
|
|
f04225321c | ||
|
|
f12315075f | ||
|
|
c99da15445 | ||
|
|
ef39db234b | ||
|
|
8af6d24a36 | ||
|
|
f8ef65e8f6 | ||
|
|
6446c312be | ||
|
|
4a524ff911 | ||
|
|
9fe0dd051d | ||
|
|
3782501275 | ||
|
|
d34ea9a569 | ||
|
|
bb1fccb7b7 | ||
|
|
777c9acae8 | ||
|
|
7b13b58a2f | ||
|
|
b11dd1f213 | ||
|
|
7ca7e4bad5 | ||
|
|
bca5bd9c62 | ||
|
|
b90e84b9fe | ||
|
|
75582f80f8 | ||
|
|
270e3a4345 | ||
|
|
0fab627a3c | ||
|
|
599e49e4d0 | ||
|
|
cff3950e6b | ||
|
|
42193960f2 | ||
|
|
98d08439dc | ||
|
|
8614c00c8a | ||
|
|
df0a49ff14 | ||
|
|
50429d0819 | ||
|
|
5c88c1f50b | ||
|
|
d85f5518d9 | ||
|
|
8e24c6458d | ||
|
|
b748455d96 | ||
|
|
7eb6471559 | ||
|
|
56513a8c66 | ||
|
|
8b1455c945 | ||
|
|
b9be1d1268 | ||
|
|
71e6f22670 | ||
|
|
0dbbf776c6 | ||
|
|
3eed7e622c | ||
|
|
a6a181c70c | ||
|
|
92b02014d2 | ||
|
|
987e843cd1 | ||
|
|
5050586a9e | ||
|
|
da4fd6b71a | ||
|
|
e07c44543f | ||
|
|
78b5e57a4a | ||
|
|
10a49d476d | ||
|
|
0759212a44 | ||
|
|
7eda64e464 | ||
|
|
124cca3af0 | ||
|
|
7faf77804d | ||
|
|
d94bcd285a | ||
|
|
9af49e07f3 | ||
|
|
0f0ab74560 | ||
|
|
5288b8550b | ||
|
|
66d789229d | ||
|
|
bba9be6a4d | ||
|
|
ebe10fa645 | ||
|
|
833c5035a6 | ||
|
|
aa3445bdb6 | ||
|
|
66fe12db71 | ||
|
|
5db3396c07 | ||
|
|
c1a18a2889 | ||
|
|
89db185726 | ||
|
|
a301d0eb4e | ||
|
|
076655cdd8 | ||
|
|
8e4a5996b0 | ||
|
|
52547466f0 | ||
|
|
4967fa8733 | ||
|
|
8065001c0d | ||
|
|
72a5839931 | ||
|
|
c995be94d9 | ||
|
|
018b81a46a | ||
|
|
941a240535 | ||
|
|
ed5b5d0559 | ||
|
|
104b7d457d | ||
|
|
feb973b970 | ||
|
|
e02068eb2a | ||
|
|
eea1878a3b | ||
|
|
4499c7a030 | ||
|
|
2f1d8630f1 | ||
|
|
cf59496957 | ||
|
|
32de29ea35 | ||
|
|
8d7de50ca8 | ||
|
|
3d685f7bec | ||
|
|
05b08ae38f | ||
|
|
623d2f25b1 | ||
|
|
634d3557f2 | ||
|
|
6957eceee0 | ||
|
|
5097f6394d | ||
|
|
77cfc1cc59 | ||
|
|
5d8200b9fc | ||
|
|
18255881ca | ||
|
|
2fb84af3e9 | ||
|
|
907f906ec6 | ||
|
|
acfb87a07b | ||
|
|
c10541feb7 | ||
|
|
e72778ea84 | ||
|
|
a824017d8c | ||
|
|
d570bc5cc5 | ||
|
|
559b2069ac | ||
|
|
6c5e89ede0 | ||
|
|
6a8ddc954f | ||
|
|
8f1c0eb2dd | ||
|
|
8c01275ee9 | ||
|
|
d6f4208a15 | ||
|
|
2e78bc1bc4 | ||
|
|
20feb44564 | ||
|
|
1506d3ddab | ||
|
|
5cb64fff91 | ||
|
|
1adf56664d | ||
|
|
183ede84fd | ||
|
|
bd9a44c225 | ||
|
|
30734ba8e8 | ||
|
|
cf4651b6bb | ||
|
|
14314b77ee | ||
|
|
ef71edd331 | ||
|
|
708c3c9ec6 | ||
|
|
c1a5c5b9f8 | ||
|
|
1cc7006555 | ||
|
|
3f87f3c47a | ||
|
|
f3a1b4e38c | ||
|
|
7eb4abae80 | ||
|
|
0ea1b712be | ||
|
|
9cf96580bf | ||
|
|
46d67cb349 | ||
|
|
f7d5141251 | ||
|
|
8e11dac375 | ||
|
|
adee6de140 | ||
|
|
4ed89dc2d3 | ||
|
|
8e6d575d4e | ||
|
|
e227b92972 | ||
|
|
a9a082f05c | ||
|
|
be54cb9531 | ||
|
|
18a6b8e101 | ||
|
|
52ced19e2e | ||
|
|
1c0971b12c | ||
|
|
2db9bdf7a2 | ||
|
|
a09b2a23b9 | ||
|
|
6d2ecefca0 | ||
|
|
568c22016a | ||
|
|
6e1b9326e4 | ||
|
|
3c8a38212e | ||
|
|
eba4af7a9f | ||
|
|
f8a5725214 | ||
|
|
791077c240 | ||
|
|
bd8de9a6f8 | ||
|
|
0a82489ddc | ||
|
|
006b8716ed | ||
|
|
4ff8386e3d | ||
|
|
cb6c8bee47 | ||
|
|
3a35883250 | ||
|
|
2a00565bc4 | ||
|
|
5e0e951867 | ||
|
|
4c75bd404b | ||
|
|
2b70760594 | ||
|
|
d8ce97f766 | ||
|
|
cf221c8f75 | ||
|
|
b938c60396 | ||
|
|
3a28fa01b0 | ||
|
|
8a84884d50 | ||
|
|
b103052ff0 | ||
|
|
71b6dd232e | ||
|
|
1f7863e323 | ||
|
|
e951209d68 | ||
|
|
0ef114e006 | ||
|
|
887f11435b | ||
|
|
d7f1b873c8 | ||
|
|
16f9f50f50 | ||
|
|
6f1dcdc08f | ||
|
|
3cd50da3b0 | ||
|
|
0125ec3b48 | ||
|
|
7611f52faf | ||
|
|
669b2342ff | ||
|
|
1493c2a9b4 | ||
|
|
724ca74f51 | ||
|
|
76d4ac17a2 | ||
|
|
8d54d97007 | ||
|
|
7cf2d889d8 | ||
|
|
59a2d1c974 | ||
|
|
5108a9c6fe | ||
|
|
6e98df0e28 | ||
|
|
f3f75f557a | ||
|
|
8bf5759d26 | ||
|
|
cbf797ed95 | ||
|
|
17c4d733d0 | ||
|
|
dd52fb7e2e | ||
|
|
b1f5103c75 | ||
|
|
f19e8af33b | ||
|
|
a559c0cfc2 | ||
|
|
5132252daa | ||
|
|
dfb81dd89c | ||
|
|
59e3802c74 | ||
|
|
a1d2acd574 | ||
|
|
8bb60b6474 | ||
|
|
143be7ee02 | ||
|
|
d967bb4a54 | ||
|
|
fd37f37ee4 | ||
|
|
db3e8616c8 | ||
|
|
8fdef1f820 | ||
|
|
b481e76ee2 | ||
|
|
3477f9bfe0 | ||
|
|
10cf1ccc1a | ||
|
|
22b42dc90a | ||
|
|
e6f58e4dcc | ||
|
|
192b9008bd | ||
|
|
56d0af472d | ||
|
|
85f32b956f | ||
|
|
027bf93849 | ||
|
|
071f8e18d0 | ||
|
|
19d962c3aa | ||
|
|
dae2d4686e | ||
|
|
fc3ee67b1f | ||
|
|
a54a15523b | ||
|
|
5b135c07d0 | ||
|
|
dd83445fd7 | ||
|
|
290485b144 | ||
|
|
c514316a2e | ||
|
|
8b98ceb92c | ||
|
|
7a20a4d32b | ||
|
|
8cbb78bb1d | ||
|
|
ef84339003 | ||
|
|
909954ac34 | ||
|
|
d996643540 | ||
|
|
074a4a6e0e | ||
|
|
a6248cba19 | ||
|
|
6a875eb691 | ||
|
|
83c96d4f3e | ||
|
|
1fcc9e977f | ||
|
|
c56b95ed68 | ||
|
|
bb3a5bcfd7 | ||
|
|
35678a1c09 | ||
|
|
c622ad0b50 | ||
|
|
75324e4859 | ||
|
|
93f07c78d6 | ||
|
|
59a619ebbb | ||
|
|
77938cc11e | ||
|
|
ae998984a0 | ||
|
|
2e31311e3c | ||
|
|
32782a7f9f | ||
|
|
4f2d74e25f | ||
|
|
c9ed3fdae3 | ||
|
|
7b164b5cd4 | ||
|
|
dd54b1aacb | ||
|
|
8fa96feb1f | ||
|
|
ddd0796e40 | ||
|
|
4ef86b965b | ||
|
|
1cc6dd871b | ||
|
|
4564519a56 | ||
|
|
5a241fd12e | ||
|
|
840fcf2fa9 | ||
|
|
75e3ab737c | ||
|
|
516cedaa47 | ||
|
|
3881ade96d | ||
|
|
f4842d6eed | ||
|
|
10e77d865b | ||
|
|
92725e5803 | ||
|
|
73510949ba | ||
|
|
08ff4dfb21 | ||
|
|
2e72f2eca8 | ||
|
|
9845bbddce | ||
|
|
81b3ad5b87 | ||
|
|
6c4f196f6e | ||
|
|
022b4ae57c | ||
|
|
d185e2f9e0 | ||
|
|
2b7c31feb5 | ||
|
|
7dd312b1ac | ||
|
|
4ff7b395dd | ||
|
|
66044c620b | ||
|
|
52c1718ee8 | ||
|
|
8b180aa606 | ||
|
|
ccaf6c8df0 | ||
|
|
879a614cde | ||
|
|
8c3dc34359 | ||
|
|
f82654f158 | ||
|
|
c365614548 | ||
|
|
a3c2c4a48a | ||
|
|
8316e78667 | ||
|
|
4a988b0f92 | ||
|
|
b5e80bf90f | ||
|
|
da426fa652 | ||
|
|
39e65a41a2 | ||
|
|
1eb17b08f9 | ||
|
|
318c8717b8 | ||
|
|
7184632b84 | ||
|
|
1e4a7d55e0 | ||
|
|
5101c55e10 | ||
|
|
c1537b5291 | ||
|
|
4c767d636a | ||
|
|
aa91ca0a8d | ||
|
|
d3b831bf7b | ||
|
|
fa688d48e6 | ||
|
|
671a0fa101 | ||
|
|
99f006f2c9 | ||
|
|
f9c400a727 | ||
|
|
fe22797d69 | ||
|
|
d29ba0b80f | ||
|
|
18fd46ab6b | ||
|
|
ec7ac956e4 | ||
|
|
99c560295f | ||
|
|
90c7cf9763 | ||
|
|
3dc9ceaadf | ||
|
|
23f6185bfe | ||
|
|
1cb0294388 | ||
|
|
2d47a6d71c | ||
|
|
22c2209cf9 | ||
|
|
471679b0f0 | ||
|
|
862c9d76e6 | ||
|
|
2c187c43bf | ||
|
|
486b4e9ea2 | ||
|
|
5f361e71df | ||
|
|
13881f5a5b | ||
|
|
c38a2112c6 | ||
|
|
a9fc777b20 | ||
|
|
ab15456119 | ||
|
|
0d55613359 | ||
|
|
845460b165 | ||
|
|
7c27fb7c1d | ||
|
|
e51c20c496 | ||
|
|
190fef513f | ||
|
|
b9ef10fe3f | ||
|
|
2b9777555f | ||
|
|
1f79394ac4 | ||
|
|
e2e111f95e | ||
|
|
8985d05a66 | ||
|
|
4e03668eec | ||
|
|
2789b08dd0 | ||
|
|
66a02688ad | ||
|
|
681bbf02ae | ||
|
|
c80de840d1 | ||
|
|
bd3458da6e | ||
|
|
4ccbc65628 | ||
|
|
9a2753931b | ||
|
|
0b4d4db131 | ||
|
|
a1b12335ab | ||
|
|
a8137d5d17 | ||
|
|
1e5362b1f7 | ||
|
|
51ea8b0295 | ||
|
|
f35194e604 | ||
|
|
3ef57c1ac3 | ||
|
|
69b7f9e9a2 | ||
|
|
220641909c | ||
|
|
31bc6054a3 | ||
|
|
94391723c0 | ||
|
|
5fd3decb16 | ||
|
|
d7c015a884 | ||
|
|
8ed55e8d7a | ||
|
|
979892a109 | ||
|
|
776d5ce554 | ||
|
|
28ea323791 | ||
|
|
18787caab9 | ||
|
|
390d6023c6 | ||
|
|
e1ef9a5c72 | ||
|
|
f3babef54a | ||
|
|
2dc3850798 | ||
|
|
18001e5a5b | ||
|
|
32f6cb7c13 | ||
|
|
9f76b4d2ef | ||
|
|
a9efe82117 | ||
|
|
4ee55dc456 | ||
|
|
470ef4d11e | ||
|
|
57d4e698fe | ||
|
|
f50544bb15 | ||
|
|
e3becc7c3c | ||
|
|
e7caec6e7d | ||
|
|
6487c1803f | ||
|
|
ff65a5b22a | ||
|
|
7a03cf92ba | ||
|
|
e6fa690d65 | ||
|
|
95cc65f14e | ||
|
|
b3a3d3e2fa | ||
|
|
0820e745d6 | ||
|
|
2197fa3120 | ||
|
|
b4d4b80dcd | ||
|
|
3bfaa20c05 | ||
|
|
58f8a23d58 | ||
|
|
1f3380bfad | ||
|
|
451ec23060 | ||
|
|
4c84165aa0 | ||
|
|
a6c8feea21 | ||
|
|
718de6c7fd | ||
|
|
d81a135704 | ||
|
|
1a90fbee8b | ||
|
|
2ac30707d2 | ||
|
|
58a36e3604 | ||
|
|
676fe403ab | ||
|
|
13611bf0ab | ||
|
|
ad02b3fb7b | ||
|
|
d3600e729f | ||
|
|
6c8e1514aa | ||
|
|
bc44158501 | ||
|
|
918123cd06 | ||
|
|
2b86ef8e28 | ||
|
|
3e28dc669b | ||
|
|
bee3f353fc | ||
|
|
005f4baaa4 | ||
|
|
2b0142580f | ||
|
|
236c735d08 | ||
|
|
e5562afcd3 | ||
|
|
256eb6250e | ||
|
|
e50ba150c3 | ||
|
|
bab9c40dcc | ||
|
|
55ed70529a | ||
|
|
28c6aa4e6d | ||
|
|
ab88b27622 | ||
|
|
2c335dbf32 | ||
|
|
d6d1502200 | ||
|
|
4bb61ade27 | ||
|
|
96f83cc8f0 | ||
|
|
eabc04d836 | ||
|
|
b3be8745b0 | ||
|
|
aa28c3d7ba | ||
|
|
948e2190f8 | ||
|
|
362633d486 | ||
|
|
120e39ba80 | ||
|
|
98d4bdb7df | ||
|
|
2c6e3cb02d | ||
|
|
9c70084ea5 | ||
|
|
9b2bd72e1f | ||
|
|
707360169e | ||
|
|
418b8d861a | ||
|
|
42181112ff | ||
|
|
67e81b0ae9 | ||
|
|
51317b350c | ||
|
|
c83e794871 | ||
|
|
26ec775854 | ||
|
|
5e9e01bf7f | ||
|
|
f7df1b7d55 | ||
|
|
abb5d019cd | ||
|
|
474b5a52d6 | ||
|
|
63d3b12bb5 | ||
|
|
7136b85f21 | ||
|
|
6707034768 | ||
|
|
ef99d3c4ce | ||
|
|
4c9f27e550 | ||
|
|
55dded8e5f | ||
|
|
0778ac8c1b | ||
|
|
3628515b31 | ||
|
|
51e0989c49 | ||
|
|
79cbe8d199 | ||
|
|
a2d4ca095a | ||
|
|
7473be4072 | ||
|
|
6a0022d7a1 | ||
|
|
e4d4a12c6a | ||
|
|
4a1cfb3df9 | ||
|
|
b00769f606 | ||
|
|
6e367354e9 | ||
|
|
e5e8318c70 | ||
|
|
d9135ce1e7 | ||
|
|
aa17905081 | ||
|
|
fbafa95791 | ||
|
|
dc26a9cd39 | ||
|
|
5f185b6c05 | ||
|
|
893a433165 | ||
|
|
552d99d664 | ||
|
|
54aeec7b5f | ||
|
|
d2b89f5f9b | ||
|
|
6b08e1b315 | ||
|
|
18ee1fef41 | ||
|
|
2a96f56956 | ||
|
|
3903eddded | ||
|
|
b862c447f1 | ||
|
|
5b47d7bfcc | ||
|
|
310a0f924a | ||
|
|
7e57db1edb | ||
|
|
71c3ad642c | ||
|
|
bc51f529e9 | ||
|
|
a573da3b98 | ||
|
|
f37089f547 | ||
|
|
366ca57c36 | ||
|
|
b1ede59d02 | ||
|
|
6b7650e2f0 | ||
|
|
73e0b8f8b3 | ||
|
|
d19142e209 |
No files matched your search
File renamed without changes.
File renamed without changes.
+1
-1
@@ -43,7 +43,7 @@ class AccountController < ApplicationController
|
|||||||
self.logged_user = nil
|
self.logged_user = nil
|
||||||
else
|
else
|
||||||
# Authenticate user
|
# Authenticate user
|
||||||
user = User.try_to_login(params[:login], params[:password])
|
user = User.try_to_login(params[:username], params[:password])
|
||||||
if user
|
if user
|
||||||
self.logged_user = user
|
self.logged_user = user
|
||||||
# generate a key and set cookie if autologin
|
# generate a key and set cookie if autologin
|
||||||
File renamed without changes.
@@ -15,11 +15,7 @@
|
|||||||
# along with this program; if not, write to the Free Software
|
# along with this program; if not, write to the Free Software
|
||||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
|
||||||
require 'uri'
|
|
||||||
|
|
||||||
class ApplicationController < ActionController::Base
|
class ApplicationController < ActionController::Base
|
||||||
layout 'base'
|
|
||||||
|
|
||||||
before_filter :user_setup, :check_if_login_required, :set_localization
|
before_filter :user_setup, :check_if_login_required, :set_localization
|
||||||
filter_parameter_logging :password
|
filter_parameter_logging :password
|
||||||
|
|
||||||
@@ -65,11 +61,11 @@ class ApplicationController < ActionController::Base
|
|||||||
def set_localization
|
def set_localization
|
||||||
User.current.language = nil unless User.current.logged?
|
User.current.language = nil unless User.current.logged?
|
||||||
lang = begin
|
lang = begin
|
||||||
if !User.current.language.blank? && GLoc.valid_language?(User.current.language)
|
if !User.current.language.blank? and GLoc.valid_languages.include? User.current.language.to_sym
|
||||||
User.current.language
|
User.current.language
|
||||||
elsif request.env['HTTP_ACCEPT_LANGUAGE']
|
elsif request.env['HTTP_ACCEPT_LANGUAGE']
|
||||||
accept_lang = parse_qvalues(request.env['HTTP_ACCEPT_LANGUAGE']).first.downcase
|
accept_lang = parse_qvalues(request.env['HTTP_ACCEPT_LANGUAGE']).first.split('-').first
|
||||||
if !accept_lang.blank? && (GLoc.valid_language?(accept_lang) || GLoc.valid_language?(accept_lang = accept_lang.split('-').first))
|
if accept_lang and !accept_lang.empty? and GLoc.valid_languages.include? accept_lang.to_sym
|
||||||
User.current.language = accept_lang
|
User.current.language = accept_lang
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@@ -81,7 +77,8 @@ class ApplicationController < ActionController::Base
|
|||||||
|
|
||||||
def require_login
|
def require_login
|
||||||
if !User.current.logged?
|
if !User.current.logged?
|
||||||
redirect_to :controller => "account", :action => "login", :back_url => request.request_uri
|
store_location
|
||||||
|
redirect_to :controller => "account", :action => "login"
|
||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
true
|
true
|
||||||
@@ -118,16 +115,20 @@ class ApplicationController < ActionController::Base
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# store current uri in session.
|
||||||
|
# return to this location by calling redirect_back_or_default
|
||||||
|
def store_location
|
||||||
|
session[:return_to_params] = params
|
||||||
|
end
|
||||||
|
|
||||||
|
# move to the last store_location call or to the passed default one
|
||||||
def redirect_back_or_default(default)
|
def redirect_back_or_default(default)
|
||||||
back_url = params[:back_url]
|
if session[:return_to_params].nil?
|
||||||
if !back_url.blank?
|
redirect_to default
|
||||||
uri = URI.parse(back_url)
|
else
|
||||||
# do not redirect user to another host
|
redirect_to session[:return_to_params]
|
||||||
if uri.relative? || (uri.host == request.host)
|
session[:return_to_params] = nil
|
||||||
redirect_to(back_url) and return
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
redirect_to default
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def render_403
|
def render_403
|
||||||
+1
-1
@@ -21,7 +21,7 @@ class AttachmentsController < ApplicationController
|
|||||||
|
|
||||||
def download
|
def download
|
||||||
# images are sent inline
|
# images are sent inline
|
||||||
send_file @attachment.diskfile, :filename => @attachment.filename,
|
send_file @attachment.diskfile, :filename => filename_for_content_disposition(@attachment.filename),
|
||||||
:type => @attachment.content_type,
|
:type => @attachment.content_type,
|
||||||
:disposition => (@attachment.image? ? 'inline' : 'attachment')
|
:disposition => (@attachment.image? ? 'inline' : 'attachment')
|
||||||
rescue
|
rescue
|
||||||
File renamed without changes.
File renamed without changes.
File renamed without changes.
+4
-1
@@ -21,6 +21,8 @@ class DocumentsController < ApplicationController
|
|||||||
before_filter :find_document, :except => [:index, :new]
|
before_filter :find_document, :except => [:index, :new]
|
||||||
before_filter :authorize
|
before_filter :authorize
|
||||||
|
|
||||||
|
helper :attachments
|
||||||
|
|
||||||
def index
|
def index
|
||||||
@sort_by = %w(category date title author).include?(params[:sort_by]) ? params[:sort_by] : 'category'
|
@sort_by = %w(category date title author).include?(params[:sort_by]) ? params[:sort_by] : 'category'
|
||||||
documents = @project.documents.find :all, :include => [:attachments, :category]
|
documents = @project.documents.find :all, :include => [:attachments, :category]
|
||||||
@@ -67,7 +69,8 @@ class DocumentsController < ApplicationController
|
|||||||
def download
|
def download
|
||||||
@attachment = @document.attachments.find(params[:attachment_id])
|
@attachment = @document.attachments.find(params[:attachment_id])
|
||||||
@attachment.increment_download
|
@attachment.increment_download
|
||||||
send_file @attachment.diskfile, :filename => @attachment.filename, :type => @attachment.content_type
|
send_file @attachment.diskfile, :filename => filename_for_content_disposition(@attachment.filename),
|
||||||
|
:type => @attachment.content_type
|
||||||
rescue
|
rescue
|
||||||
render_404
|
render_404
|
||||||
end
|
end
|
||||||
File renamed without changes.
+1
@@ -16,6 +16,7 @@
|
|||||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
|
||||||
class IssueCategoriesController < ApplicationController
|
class IssueCategoriesController < ApplicationController
|
||||||
|
layout 'base'
|
||||||
menu_item :settings
|
menu_item :settings
|
||||||
before_filter :find_project, :authorize
|
before_filter :find_project, :authorize
|
||||||
|
|
||||||
File renamed without changes.
File renamed without changes.
@@ -16,9 +16,10 @@
|
|||||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
|
||||||
class IssuesController < ApplicationController
|
class IssuesController < ApplicationController
|
||||||
|
layout 'base'
|
||||||
menu_item :new_issue, :only => :new
|
menu_item :new_issue, :only => :new
|
||||||
|
|
||||||
before_filter :find_issue, :only => [:show, :edit, :reply, :destroy_attachment]
|
before_filter :find_issue, :only => [:show, :edit, :destroy_attachment]
|
||||||
before_filter :find_issues, :only => [:bulk_edit, :move, :destroy]
|
before_filter :find_issues, :only => [:bulk_edit, :move, :destroy]
|
||||||
before_filter :find_project, :only => [:new, :update_form, :preview]
|
before_filter :find_project, :only => [:new, :update_form, :preview]
|
||||||
before_filter :authorize, :except => [:index, :changes, :preview, :update_form, :context_menu]
|
before_filter :authorize, :except => [:index, :changes, :preview, :update_form, :context_menu]
|
||||||
@@ -42,7 +43,6 @@ class IssuesController < ApplicationController
|
|||||||
helper :sort
|
helper :sort
|
||||||
include SortHelper
|
include SortHelper
|
||||||
include IssuesHelper
|
include IssuesHelper
|
||||||
helper :timelog
|
|
||||||
|
|
||||||
def index
|
def index
|
||||||
sort_init "#{Issue.table_name}.id", "desc"
|
sort_init "#{Issue.table_name}.id", "desc"
|
||||||
@@ -65,7 +65,7 @@ class IssuesController < ApplicationController
|
|||||||
:offset => @issue_pages.current.offset
|
:offset => @issue_pages.current.offset
|
||||||
respond_to do |format|
|
respond_to do |format|
|
||||||
format.html { render :template => 'issues/index.rhtml', :layout => !request.xhr? }
|
format.html { render :template => 'issues/index.rhtml', :layout => !request.xhr? }
|
||||||
format.atom { render_feed(@issues, :title => "#{@project || Setting.app_title}: #{l(:label_issue_plural)}") }
|
format.atom { render_feed(@issues, :title => l(:label_issue_plural)) }
|
||||||
format.csv { send_data(issues_to_csv(@issues, @project).read, :type => 'text/csv; header=present', :filename => 'export.csv') }
|
format.csv { send_data(issues_to_csv(@issues, @project).read, :type => 'text/csv; header=present', :filename => 'export.csv') }
|
||||||
format.pdf { send_data(render(:template => 'issues/index.rfpdf', :layout => false), :type => 'application/pdf', :filename => 'export.pdf') }
|
format.pdf { send_data(render(:template => 'issues/index.rfpdf', :layout => false), :type => 'application/pdf', :filename => 'export.pdf') }
|
||||||
end
|
end
|
||||||
@@ -94,13 +94,14 @@ class IssuesController < ApplicationController
|
|||||||
end
|
end
|
||||||
|
|
||||||
def show
|
def show
|
||||||
|
@custom_values = @project.custom_fields_for_issues(@issue.tracker).collect { |x| @issue.custom_values.find_by_custom_field_id(x.id) || CustomValue.new(:custom_field => x, :customized => @issue) }
|
||||||
@journals = @issue.journals.find(:all, :include => [:user, :details], :order => "#{Journal.table_name}.created_on ASC")
|
@journals = @issue.journals.find(:all, :include => [:user, :details], :order => "#{Journal.table_name}.created_on ASC")
|
||||||
@journals.each_with_index {|j,i| j.indice = i+1}
|
@journals.each_with_index {|j,i| j.indice = i+1}
|
||||||
@journals.reverse! if User.current.wants_comments_in_reverse_order?
|
@journals.reverse! if User.current.wants_comments_in_reverse_order?
|
||||||
@allowed_statuses = @issue.new_statuses_allowed_to(User.current)
|
@allowed_statuses = @issue.new_statuses_allowed_to(User.current)
|
||||||
@edit_allowed = User.current.allowed_to?(:edit_issues, @project)
|
@edit_allowed = User.current.allowed_to?(:edit_issues, @project)
|
||||||
|
@activities = Enumeration::get_values('ACTI')
|
||||||
@priorities = Enumeration::get_values('IPRI')
|
@priorities = Enumeration::get_values('IPRI')
|
||||||
@time_entry = TimeEntry.new
|
|
||||||
respond_to do |format|
|
respond_to do |format|
|
||||||
format.html { render :template => 'issues/show.rhtml' }
|
format.html { render :template => 'issues/show.rhtml' }
|
||||||
format.atom { render :action => 'changes', :layout => false, :content_type => 'application/atom+xml' }
|
format.atom { render :action => 'changes', :layout => false, :content_type => 'application/atom+xml' }
|
||||||
@@ -111,18 +112,15 @@ class IssuesController < ApplicationController
|
|||||||
# Add a new issue
|
# Add a new issue
|
||||||
# The new issue will be created from an existing one if copy_from parameter is given
|
# The new issue will be created from an existing one if copy_from parameter is given
|
||||||
def new
|
def new
|
||||||
@issue = Issue.new
|
@issue = params[:copy_from] ? Issue.new.copy_from(params[:copy_from]) : Issue.new(params[:issue])
|
||||||
@issue.copy_from(params[:copy_from]) if params[:copy_from]
|
|
||||||
@issue.project = @project
|
@issue.project = @project
|
||||||
# Tracker must be set before custom field values
|
@issue.author = User.current
|
||||||
@issue.tracker ||= @project.trackers.find((params[:issue] && params[:issue][:tracker_id]) || params[:tracker_id] || :first)
|
@issue.tracker ||= @project.trackers.find(params[:tracker_id] ? params[:tracker_id] : :first)
|
||||||
if @issue.tracker.nil?
|
if @issue.tracker.nil?
|
||||||
flash.now[:error] = 'No tracker is associated to this project. Please check the Project settings.'
|
flash.now[:error] = 'No tracker is associated to this project. Please check the Project settings.'
|
||||||
render :nothing => true, :layout => true
|
render :nothing => true, :layout => true
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
@issue.attributes = params[:issue]
|
|
||||||
@issue.author = User.current
|
|
||||||
|
|
||||||
default_status = IssueStatus.default
|
default_status = IssueStatus.default
|
||||||
unless default_status
|
unless default_status
|
||||||
@@ -135,15 +133,20 @@ class IssuesController < ApplicationController
|
|||||||
|
|
||||||
if request.get? || request.xhr?
|
if request.get? || request.xhr?
|
||||||
@issue.start_date ||= Date.today
|
@issue.start_date ||= Date.today
|
||||||
|
@custom_values = @issue.custom_values.empty? ?
|
||||||
|
@project.custom_fields_for_issues(@issue.tracker).collect { |x| CustomValue.new(:custom_field => x, :customized => @issue) } :
|
||||||
|
@issue.custom_values
|
||||||
else
|
else
|
||||||
requested_status = IssueStatus.find_by_id(params[:issue][:status_id])
|
requested_status = IssueStatus.find_by_id(params[:issue][:status_id])
|
||||||
# Check that the user is allowed to apply the requested status
|
# Check that the user is allowed to apply the requested status
|
||||||
@issue.status = (@allowed_statuses.include? requested_status) ? requested_status : default_status
|
@issue.status = (@allowed_statuses.include? requested_status) ? requested_status : default_status
|
||||||
|
@custom_values = @project.custom_fields_for_issues(@issue.tracker).collect { |x| CustomValue.new(:custom_field => x, :customized => @issue, :value => params["custom_fields"][x.id.to_s]) }
|
||||||
|
@issue.custom_values = @custom_values
|
||||||
if @issue.save
|
if @issue.save
|
||||||
attach_files(@issue, params[:attachments])
|
attach_files(@issue, params[:attachments])
|
||||||
flash[:notice] = l(:notice_successful_create)
|
flash[:notice] = l(:notice_successful_create)
|
||||||
Mailer.deliver_issue_add(@issue) if Setting.notified_events.include?('issue_added')
|
Mailer.deliver_issue_add(@issue) if Setting.notified_events.include?('issue_added')
|
||||||
redirect_to :controller => 'issues', :action => 'show', :id => @issue
|
redirect_to :controller => 'issues', :action => 'show', :id => @issue, :project_id => @project
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@@ -157,9 +160,10 @@ class IssuesController < ApplicationController
|
|||||||
|
|
||||||
def edit
|
def edit
|
||||||
@allowed_statuses = @issue.new_statuses_allowed_to(User.current)
|
@allowed_statuses = @issue.new_statuses_allowed_to(User.current)
|
||||||
|
@activities = Enumeration::get_values('ACTI')
|
||||||
@priorities = Enumeration::get_values('IPRI')
|
@priorities = Enumeration::get_values('IPRI')
|
||||||
|
@custom_values = []
|
||||||
@edit_allowed = User.current.allowed_to?(:edit_issues, @project)
|
@edit_allowed = User.current.allowed_to?(:edit_issues, @project)
|
||||||
@time_entry = TimeEntry.new
|
|
||||||
|
|
||||||
@notes = params[:notes]
|
@notes = params[:notes]
|
||||||
journal = @issue.init_journal(User.current, @notes)
|
journal = @issue.init_journal(User.current, @notes)
|
||||||
@@ -171,14 +175,21 @@ class IssuesController < ApplicationController
|
|||||||
@issue.attributes = attrs
|
@issue.attributes = attrs
|
||||||
end
|
end
|
||||||
|
|
||||||
if request.post?
|
if request.get?
|
||||||
@time_entry = TimeEntry.new(:project => @project, :issue => @issue, :user => User.current, :spent_on => Date.today)
|
@custom_values = @project.custom_fields_for_issues(@issue.tracker).collect { |x| @issue.custom_values.find_by_custom_field_id(x.id) || CustomValue.new(:custom_field => x, :customized => @issue) }
|
||||||
@time_entry.attributes = params[:time_entry]
|
else
|
||||||
|
# Update custom fields if user has :edit permission
|
||||||
|
if @edit_allowed && params[:custom_fields]
|
||||||
|
@custom_values = @project.custom_fields_for_issues(@issue.tracker).collect { |x| CustomValue.new(:custom_field => x, :customized => @issue, :value => params["custom_fields"][x.id.to_s]) }
|
||||||
|
@issue.custom_values = @custom_values
|
||||||
|
end
|
||||||
attachments = attach_files(@issue, params[:attachments])
|
attachments = attach_files(@issue, params[:attachments])
|
||||||
attachments.each {|a| journal.details << JournalDetail.new(:property => 'attachment', :prop_key => a.id, :value => a.filename)}
|
attachments.each {|a| journal.details << JournalDetail.new(:property => 'attachment', :prop_key => a.id, :value => a.filename)}
|
||||||
if (@time_entry.hours.nil? || @time_entry.valid?) && @issue.save
|
if @issue.save
|
||||||
# Log spend time
|
# Log spend time
|
||||||
if current_role.allowed_to?(:log_time)
|
if current_role.allowed_to?(:log_time)
|
||||||
|
@time_entry = TimeEntry.new(:project => @project, :issue => @issue, :user => User.current, :spent_on => Date.today)
|
||||||
|
@time_entry.attributes = params[:time_entry]
|
||||||
@time_entry.save
|
@time_entry.save
|
||||||
end
|
end
|
||||||
if !journal.new_record?
|
if !journal.new_record?
|
||||||
@@ -194,26 +205,6 @@ class IssuesController < ApplicationController
|
|||||||
flash.now[:error] = l(:notice_locking_conflict)
|
flash.now[:error] = l(:notice_locking_conflict)
|
||||||
end
|
end
|
||||||
|
|
||||||
def reply
|
|
||||||
journal = Journal.find(params[:journal_id]) if params[:journal_id]
|
|
||||||
if journal
|
|
||||||
user = journal.user
|
|
||||||
text = journal.notes
|
|
||||||
else
|
|
||||||
user = @issue.author
|
|
||||||
text = @issue.description
|
|
||||||
end
|
|
||||||
content = "#{ll(Setting.default_language, :text_user_wrote, user)}\\n> "
|
|
||||||
content << text.to_s.strip.gsub(%r{<pre>((.|\s)*?)</pre>}m, '[...]').gsub('"', '\"').gsub(/(\r?\n|\r\n?)/, "\\n> ") + "\\n\\n"
|
|
||||||
render(:update) { |page|
|
|
||||||
page.<< "$('notes').value = \"#{content}\";"
|
|
||||||
page.show 'update'
|
|
||||||
page << "Form.Element.focus('notes');"
|
|
||||||
page << "Element.scrollTo('update');"
|
|
||||||
page << "$('notes').scrollTop = $('notes').scrollHeight - $('notes').clientHeight;"
|
|
||||||
}
|
|
||||||
end
|
|
||||||
|
|
||||||
# Bulk edit a set of issues
|
# Bulk edit a set of issues
|
||||||
def bulk_edit
|
def bulk_edit
|
||||||
if request.post?
|
if request.post?
|
||||||
@@ -233,7 +224,6 @@ class IssuesController < ApplicationController
|
|||||||
issue.start_date = params[:start_date] unless params[:start_date].blank?
|
issue.start_date = params[:start_date] unless params[:start_date].blank?
|
||||||
issue.due_date = params[:due_date] unless params[:due_date].blank?
|
issue.due_date = params[:due_date] unless params[:due_date].blank?
|
||||||
issue.done_ratio = params[:done_ratio] unless params[:done_ratio].blank?
|
issue.done_ratio = params[:done_ratio] unless params[:done_ratio].blank?
|
||||||
call_hook(:controller_issues_bulk_edit_before_save, { :params => params, :issue => issue })
|
|
||||||
# Don't save any change to the issue if the user is not authorized to apply the requested status
|
# Don't save any change to the issue if the user is not authorized to apply the requested status
|
||||||
if (status.nil? || (issue.status.new_status_allowed_to?(status, current_role, issue.tracker) && issue.status = status)) && issue.save
|
if (status.nil? || (issue.status.new_status_allowed_to?(status, current_role, issue.tracker) && issue.status = status)) && issue.save
|
||||||
# Send notification for each issue (if changed)
|
# Send notification for each issue (if changed)
|
||||||
@@ -272,7 +262,6 @@ class IssuesController < ApplicationController
|
|||||||
new_tracker = params[:new_tracker_id].blank? ? nil : @target_project.trackers.find_by_id(params[:new_tracker_id])
|
new_tracker = params[:new_tracker_id].blank? ? nil : @target_project.trackers.find_by_id(params[:new_tracker_id])
|
||||||
unsaved_issue_ids = []
|
unsaved_issue_ids = []
|
||||||
@issues.each do |issue|
|
@issues.each do |issue|
|
||||||
issue.init_journal(User.current)
|
|
||||||
unsaved_issue_ids << issue.id unless issue.move_to(@target_project, new_tracker)
|
unsaved_issue_ids << issue.id unless issue.move_to(@target_project, new_tracker)
|
||||||
end
|
end
|
||||||
if unsaved_issue_ids.empty?
|
if unsaved_issue_ids.empty?
|
||||||
@@ -334,7 +323,6 @@ class IssuesController < ApplicationController
|
|||||||
@project = projects.first if projects.size == 1
|
@project = projects.first if projects.size == 1
|
||||||
|
|
||||||
@can = {:edit => (@project && User.current.allowed_to?(:edit_issues, @project)),
|
@can = {:edit => (@project && User.current.allowed_to?(:edit_issues, @project)),
|
||||||
:log_time => (@project && User.current.allowed_to?(:log_time, @project)),
|
|
||||||
:update => (@issue && (User.current.allowed_to?(:edit_issues, @project) || (User.current.allowed_to?(:change_status, @project) && !@allowed_statuses.empty?))),
|
:update => (@issue && (User.current.allowed_to?(:edit_issues, @project) || (User.current.allowed_to?(:change_status, @project) && !@allowed_statuses.empty?))),
|
||||||
:move => (@project && User.current.allowed_to?(:move_issues, @project)),
|
:move => (@project && User.current.allowed_to?(:move_issues, @project)),
|
||||||
:copy => (@issue && @project.trackers.include?(@issue.tracker) && User.current.allowed_to?(:add_issues, @project)),
|
:copy => (@issue && @project.trackers.include?(@issue.tracker) && User.current.allowed_to?(:add_issues, @project)),
|
||||||
@@ -354,8 +342,8 @@ class IssuesController < ApplicationController
|
|||||||
end
|
end
|
||||||
|
|
||||||
def preview
|
def preview
|
||||||
@issue = @project.issues.find_by_id(params[:id]) unless params[:id].blank?
|
issue = @project.issues.find_by_id(params[:id])
|
||||||
@attachements = @issue.attachments if @issue
|
@attachements = issue.attachments if issue
|
||||||
@text = params[:notes] || (params[:issue] ? params[:issue][:description] : nil)
|
@text = params[:notes] || (params[:issue] ? params[:issue][:description] : nil)
|
||||||
render :partial => 'common/preview'
|
render :partial => 'common/preview'
|
||||||
end
|
end
|
||||||
@@ -423,7 +411,6 @@ private
|
|||||||
else
|
else
|
||||||
@query = Query.find_by_id(session[:query][:id]) if session[:query][:id]
|
@query = Query.find_by_id(session[:query][:id]) if session[:query][:id]
|
||||||
@query ||= Query.new(:name => "_", :project => @project, :filters => session[:query][:filters])
|
@query ||= Query.new(:name => "_", :project => @project, :filters => session[:query][:filters])
|
||||||
@query.project = @project
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@@ -16,6 +16,7 @@
|
|||||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
|
||||||
class JournalsController < ApplicationController
|
class JournalsController < ApplicationController
|
||||||
|
layout 'base'
|
||||||
before_filter :find_journal
|
before_filter :find_journal
|
||||||
|
|
||||||
def edit
|
def edit
|
||||||
File renamed without changes.
@@ -16,6 +16,7 @@
|
|||||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
|
||||||
class MessagesController < ApplicationController
|
class MessagesController < ApplicationController
|
||||||
|
layout 'base'
|
||||||
menu_item :boards
|
menu_item :boards
|
||||||
before_filter :find_board, :only => [:new, :preview]
|
before_filter :find_board, :only => [:new, :preview]
|
||||||
before_filter :find_message, :except => [:new, :preview]
|
before_filter :find_message, :except => [:new, :preview]
|
||||||
@@ -16,10 +16,11 @@
|
|||||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
|
||||||
class MyController < ApplicationController
|
class MyController < ApplicationController
|
||||||
before_filter :require_login
|
|
||||||
|
|
||||||
helper :issues
|
helper :issues
|
||||||
|
|
||||||
|
layout 'base'
|
||||||
|
before_filter :require_login
|
||||||
|
|
||||||
BLOCKS = { 'issuesassignedtome' => :label_assigned_to_me_issues,
|
BLOCKS = { 'issuesassignedtome' => :label_assigned_to_me_issues,
|
||||||
'issuesreportedbyme' => :label_reported_issues,
|
'issuesreportedbyme' => :label_reported_issues,
|
||||||
'issueswatched' => :label_watched_issues,
|
'issueswatched' => :label_watched_issues,
|
||||||
+2
-1
@@ -16,8 +16,9 @@
|
|||||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
|
||||||
class NewsController < ApplicationController
|
class NewsController < ApplicationController
|
||||||
|
layout 'base'
|
||||||
before_filter :find_news, :except => [:new, :index, :preview]
|
before_filter :find_news, :except => [:new, :index, :preview]
|
||||||
before_filter :find_project, :only => [:new, :preview]
|
before_filter :find_project, :only => :new
|
||||||
before_filter :authorize, :except => [:index, :preview]
|
before_filter :authorize, :except => [:index, :preview]
|
||||||
before_filter :find_optional_project, :only => :index
|
before_filter :find_optional_project, :only => :index
|
||||||
accept_key_auth :index
|
accept_key_auth :index
|
||||||
+109
-45
@@ -16,6 +16,7 @@
|
|||||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
|
||||||
class ProjectsController < ApplicationController
|
class ProjectsController < ApplicationController
|
||||||
|
layout 'base'
|
||||||
menu_item :overview
|
menu_item :overview
|
||||||
menu_item :activity, :only => :activity
|
menu_item :activity, :only => :activity
|
||||||
menu_item :roadmap, :only => :roadmap
|
menu_item :roadmap, :only => :roadmap
|
||||||
@@ -43,48 +44,50 @@ class ProjectsController < ApplicationController
|
|||||||
include RepositoriesHelper
|
include RepositoriesHelper
|
||||||
include ProjectsHelper
|
include ProjectsHelper
|
||||||
|
|
||||||
# Lists visible projects
|
|
||||||
def index
|
def index
|
||||||
|
list
|
||||||
|
render :action => 'list' unless request.xhr?
|
||||||
|
end
|
||||||
|
|
||||||
|
# Lists visible projects
|
||||||
|
def list
|
||||||
projects = Project.find :all,
|
projects = Project.find :all,
|
||||||
:conditions => Project.visible_by(User.current),
|
:conditions => Project.visible_by(User.current),
|
||||||
:include => :parent
|
:include => :parent
|
||||||
respond_to do |format|
|
@project_tree = projects.group_by {|p| p.parent || p}
|
||||||
format.html {
|
@project_tree.each_key {|p| @project_tree[p] -= [p]}
|
||||||
@project_tree = projects.group_by {|p| p.parent || p}
|
|
||||||
@project_tree.keys.each {|p| @project_tree[p] -= [p]}
|
|
||||||
}
|
|
||||||
format.atom {
|
|
||||||
render_feed(projects.sort_by(&:created_on).reverse.slice(0, Setting.feeds_limit.to_i),
|
|
||||||
:title => "#{Setting.app_title}: #{l(:label_project_latest)}")
|
|
||||||
}
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
# Add a new project
|
# Add a new project
|
||||||
def add
|
def add
|
||||||
@issue_custom_fields = IssueCustomField.find(:all, :order => "#{CustomField.table_name}.position")
|
@custom_fields = IssueCustomField.find(:all, :order => "#{CustomField.table_name}.position")
|
||||||
@trackers = Tracker.all
|
@trackers = Tracker.all
|
||||||
@root_projects = Project.find(:all,
|
@root_projects = Project.find(:all,
|
||||||
:conditions => "parent_id IS NULL AND status = #{Project::STATUS_ACTIVE}",
|
:conditions => "parent_id IS NULL AND status = #{Project::STATUS_ACTIVE}",
|
||||||
:order => 'name')
|
:order => 'name')
|
||||||
@project = Project.new(params[:project])
|
@project = Project.new(params[:project])
|
||||||
|
@project.enabled_module_names = Redmine::AccessControl.available_project_modules
|
||||||
if request.get?
|
if request.get?
|
||||||
|
@custom_values = ProjectCustomField.find(:all, :order => "#{CustomField.table_name}.position").collect { |x| CustomValue.new(:custom_field => x, :customized => @project) }
|
||||||
@project.trackers = Tracker.all
|
@project.trackers = Tracker.all
|
||||||
@project.is_public = Setting.default_projects_public?
|
@project.is_public = Setting.default_projects_public?
|
||||||
@project.enabled_module_names = Redmine::AccessControl.available_project_modules
|
|
||||||
else
|
else
|
||||||
@project.enabled_module_names = params[:enabled_modules]
|
@project.custom_fields = CustomField.find(params[:custom_field_ids]) if params[:custom_field_ids]
|
||||||
|
@custom_values = ProjectCustomField.find(:all, :order => "#{CustomField.table_name}.position").collect { |x| CustomValue.new(:custom_field => x, :customized => @project, :value => (params[:custom_fields] ? params["custom_fields"][x.id.to_s] : nil)) }
|
||||||
|
@project.custom_values = @custom_values
|
||||||
if @project.save
|
if @project.save
|
||||||
|
@project.enabled_module_names = params[:enabled_modules]
|
||||||
flash[:notice] = l(:notice_successful_create)
|
flash[:notice] = l(:notice_successful_create)
|
||||||
redirect_to :controller => 'admin', :action => 'projects'
|
redirect_to :controller => 'admin', :action => 'projects'
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
# Show @project
|
# Show @project
|
||||||
def show
|
def show
|
||||||
|
@custom_values = @project.custom_values.find(:all, :include => :custom_field, :order => "#{CustomField.table_name}.position")
|
||||||
@members_by_role = @project.members.find(:all, :include => [:user, :role], :order => 'position').group_by {|m| m.role}
|
@members_by_role = @project.members.find(:all, :include => [:user, :role], :order => 'position').group_by {|m| m.role}
|
||||||
@subprojects = @project.children.find(:all, :conditions => Project.visible_by(User.current))
|
@subprojects = @project.active_children
|
||||||
@news = @project.news.find(:all, :limit => 5, :include => [ :author, :project ], :order => "#{News.table_name}.created_on DESC")
|
@news = @project.news.find(:all, :limit => 5, :include => [ :author, :project ], :order => "#{News.table_name}.created_on DESC")
|
||||||
@trackers = @project.rolled_up_trackers
|
@trackers = @project.rolled_up_trackers
|
||||||
|
|
||||||
@@ -109,10 +112,11 @@ class ProjectsController < ApplicationController
|
|||||||
@root_projects = Project.find(:all,
|
@root_projects = Project.find(:all,
|
||||||
:conditions => ["parent_id IS NULL AND status = #{Project::STATUS_ACTIVE} AND id <> ?", @project.id],
|
:conditions => ["parent_id IS NULL AND status = #{Project::STATUS_ACTIVE} AND id <> ?", @project.id],
|
||||||
:order => 'name')
|
:order => 'name')
|
||||||
@issue_custom_fields = IssueCustomField.find(:all, :order => "#{CustomField.table_name}.position")
|
@custom_fields = IssueCustomField.find(:all)
|
||||||
@issue_category ||= IssueCategory.new
|
@issue_category ||= IssueCategory.new
|
||||||
@member ||= @project.members.new
|
@member ||= @project.members.new
|
||||||
@trackers = Tracker.all
|
@trackers = Tracker.all
|
||||||
|
@custom_values ||= ProjectCustomField.find(:all, :order => "#{CustomField.table_name}.position").collect { |x| @project.custom_values.find_by_custom_field_id(x.id) || CustomValue.new(:custom_field => x) }
|
||||||
@repository ||= @project.repository
|
@repository ||= @project.repository
|
||||||
@wiki ||= @project.wiki
|
@wiki ||= @project.wiki
|
||||||
end
|
end
|
||||||
@@ -120,6 +124,10 @@ class ProjectsController < ApplicationController
|
|||||||
# Edit @project
|
# Edit @project
|
||||||
def edit
|
def edit
|
||||||
if request.post?
|
if request.post?
|
||||||
|
if params[:custom_fields]
|
||||||
|
@custom_values = ProjectCustomField.find(:all, :order => "#{CustomField.table_name}.position").collect { |x| CustomValue.new(:custom_field => x, :customized => @project, :value => params["custom_fields"][x.id.to_s]) }
|
||||||
|
@project.custom_values = @custom_values
|
||||||
|
end
|
||||||
@project.attributes = params[:project]
|
@project.attributes = params[:project]
|
||||||
if @project.save
|
if @project.save
|
||||||
flash[:notice] = l(:notice_successful_update)
|
flash[:notice] = l(:notice_successful_update)
|
||||||
@@ -196,10 +204,7 @@ class ProjectsController < ApplicationController
|
|||||||
end
|
end
|
||||||
|
|
||||||
def list_files
|
def list_files
|
||||||
sort_init "#{Attachment.table_name}.filename", "asc"
|
@versions = @project.versions.sort.reverse
|
||||||
sort_update
|
|
||||||
@versions = @project.versions.find(:all, :include => :attachments, :order => sort_clause).sort.reverse
|
|
||||||
render :layout => !request.xhr?
|
|
||||||
end
|
end
|
||||||
|
|
||||||
# Show changelog for @project
|
# Show changelog for @project
|
||||||
@@ -225,23 +230,91 @@ class ProjectsController < ApplicationController
|
|||||||
|
|
||||||
@date_to ||= Date.today + 1
|
@date_to ||= Date.today + 1
|
||||||
@date_from = @date_to - @days
|
@date_from = @date_to - @days
|
||||||
@with_subprojects = params[:with_subprojects].nil? ? Setting.display_subprojects_issues? : (params[:with_subprojects] == '1')
|
|
||||||
|
|
||||||
@activity = Redmine::Activity::Fetcher.new(User.current, :project => @project, :with_subprojects => @with_subprojects)
|
@event_types = %w(issues news files documents changesets wiki_pages messages)
|
||||||
@activity.scope_select {|t| !params["show_#{t}"].nil?}
|
if @project
|
||||||
@activity.default_scope! if @activity.scope.empty?
|
@event_types.delete('wiki_pages') unless @project.wiki
|
||||||
|
@event_types.delete('changesets') unless @project.repository
|
||||||
|
@event_types.delete('messages') unless @project.boards.any?
|
||||||
|
# only show what the user is allowed to view
|
||||||
|
@event_types = @event_types.select {|o| User.current.allowed_to?("view_#{o}".to_sym, @project)}
|
||||||
|
@with_subprojects = params[:with_subprojects].nil? ? Setting.display_subprojects_issues? : (params[:with_subprojects] == '1')
|
||||||
|
end
|
||||||
|
@scope = @event_types.select {|t| params["show_#{t}"]}
|
||||||
|
# default events if none is specified in parameters
|
||||||
|
@scope = (@event_types - %w(wiki_pages messages))if @scope.empty?
|
||||||
|
|
||||||
events = @activity.events(@date_from, @date_to)
|
@events = []
|
||||||
|
|
||||||
|
if @scope.include?('issues')
|
||||||
|
cond = ARCondition.new(Project.allowed_to_condition(User.current, :view_issues, :project => @project, :with_subprojects => @with_subprojects))
|
||||||
|
cond.add(["#{Issue.table_name}.created_on BETWEEN ? AND ?", @date_from, @date_to])
|
||||||
|
@events += Issue.find(:all, :include => [:project, :author, :tracker], :conditions => cond.conditions)
|
||||||
|
|
||||||
|
cond = ARCondition.new(Project.allowed_to_condition(User.current, :view_issues, :project => @project, :with_subprojects => @with_subprojects))
|
||||||
|
cond.add(["#{Journal.table_name}.journalized_type = 'Issue' AND #{JournalDetail.table_name}.prop_key = 'status_id' AND #{Journal.table_name}.created_on BETWEEN ? AND ?", @date_from, @date_to])
|
||||||
|
@events += Journal.find(:all, :include => [{:issue => :project}, :details, :user], :conditions => cond.conditions)
|
||||||
|
end
|
||||||
|
|
||||||
|
if @scope.include?('news')
|
||||||
|
cond = ARCondition.new(Project.allowed_to_condition(User.current, :view_news, :project => @project, :with_subprojects => @with_subprojects))
|
||||||
|
cond.add(["#{News.table_name}.created_on BETWEEN ? AND ?", @date_from, @date_to])
|
||||||
|
@events += News.find(:all, :include => [:project, :author], :conditions => cond.conditions)
|
||||||
|
end
|
||||||
|
|
||||||
|
if @scope.include?('files')
|
||||||
|
cond = ARCondition.new(Project.allowed_to_condition(User.current, :view_files, :project => @project, :with_subprojects => @with_subprojects))
|
||||||
|
cond.add(["#{Attachment.table_name}.created_on BETWEEN ? AND ?", @date_from, @date_to])
|
||||||
|
@events += Attachment.find(:all, :select => "#{Attachment.table_name}.*",
|
||||||
|
:joins => "LEFT JOIN #{Version.table_name} ON #{Attachment.table_name}.container_type='Version' AND #{Version.table_name}.id = #{Attachment.table_name}.container_id " +
|
||||||
|
"LEFT JOIN #{Project.table_name} ON #{Version.table_name}.project_id = #{Project.table_name}.id",
|
||||||
|
:conditions => cond.conditions)
|
||||||
|
end
|
||||||
|
|
||||||
|
if @scope.include?('documents')
|
||||||
|
cond = ARCondition.new(Project.allowed_to_condition(User.current, :view_documents, :project => @project, :with_subprojects => @with_subprojects))
|
||||||
|
cond.add(["#{Document.table_name}.created_on BETWEEN ? AND ?", @date_from, @date_to])
|
||||||
|
@events += Document.find(:all, :include => :project, :conditions => cond.conditions)
|
||||||
|
|
||||||
|
cond = ARCondition.new(Project.allowed_to_condition(User.current, :view_documents, :project => @project, :with_subprojects => @with_subprojects))
|
||||||
|
cond.add(["#{Attachment.table_name}.created_on BETWEEN ? AND ?", @date_from, @date_to])
|
||||||
|
@events += Attachment.find(:all, :select => "#{Attachment.table_name}.*",
|
||||||
|
:joins => "LEFT JOIN #{Document.table_name} ON #{Attachment.table_name}.container_type='Document' AND #{Document.table_name}.id = #{Attachment.table_name}.container_id " +
|
||||||
|
"LEFT JOIN #{Project.table_name} ON #{Document.table_name}.project_id = #{Project.table_name}.id",
|
||||||
|
:conditions => cond.conditions)
|
||||||
|
end
|
||||||
|
|
||||||
|
if @scope.include?('wiki_pages')
|
||||||
|
select = "#{WikiContent.versioned_table_name}.updated_on, #{WikiContent.versioned_table_name}.comments, " +
|
||||||
|
"#{WikiContent.versioned_table_name}.#{WikiContent.version_column}, #{WikiPage.table_name}.title, " +
|
||||||
|
"#{WikiContent.versioned_table_name}.page_id, #{WikiContent.versioned_table_name}.author_id, " +
|
||||||
|
"#{WikiContent.versioned_table_name}.id"
|
||||||
|
joins = "LEFT JOIN #{WikiPage.table_name} ON #{WikiPage.table_name}.id = #{WikiContent.versioned_table_name}.page_id " +
|
||||||
|
"LEFT JOIN #{Wiki.table_name} ON #{Wiki.table_name}.id = #{WikiPage.table_name}.wiki_id " +
|
||||||
|
"LEFT JOIN #{Project.table_name} ON #{Project.table_name}.id = #{Wiki.table_name}.project_id"
|
||||||
|
|
||||||
|
cond = ARCondition.new(Project.allowed_to_condition(User.current, :view_wiki_pages, :project => @project, :with_subprojects => @with_subprojects))
|
||||||
|
cond.add(["#{WikiContent.versioned_table_name}.updated_on BETWEEN ? AND ?", @date_from, @date_to])
|
||||||
|
@events += WikiContent.versioned_class.find(:all, :select => select, :joins => joins, :conditions => cond.conditions)
|
||||||
|
end
|
||||||
|
|
||||||
|
if @scope.include?('changesets')
|
||||||
|
cond = ARCondition.new(Project.allowed_to_condition(User.current, :view_changesets, :project => @project, :with_subprojects => @with_subprojects))
|
||||||
|
cond.add(["#{Changeset.table_name}.committed_on BETWEEN ? AND ?", @date_from, @date_to])
|
||||||
|
@events += Changeset.find(:all, :include => {:repository => :project}, :conditions => cond.conditions)
|
||||||
|
end
|
||||||
|
|
||||||
|
if @scope.include?('messages')
|
||||||
|
cond = ARCondition.new(Project.allowed_to_condition(User.current, :view_messages, :project => @project, :with_subprojects => @with_subprojects))
|
||||||
|
cond.add(["#{Message.table_name}.created_on BETWEEN ? AND ?", @date_from, @date_to])
|
||||||
|
@events += Message.find(:all, :include => [{:board => :project}, :author], :conditions => cond.conditions)
|
||||||
|
end
|
||||||
|
|
||||||
|
@events_by_day = @events.group_by(&:event_date)
|
||||||
|
|
||||||
respond_to do |format|
|
respond_to do |format|
|
||||||
format.html {
|
format.html { render :layout => false if request.xhr? }
|
||||||
@events_by_day = events.group_by(&:event_date)
|
format.atom { render_feed(@events, :title => "#{@project || Setting.app_title}: #{l(:label_activity)}") }
|
||||||
render :layout => false if request.xhr?
|
|
||||||
}
|
|
||||||
format.atom {
|
|
||||||
title = (@activity.scope.size == 1) ? l("label_#{@activity.scope.first.singularize}_plural") : l(:label_activity)
|
|
||||||
render_feed(events, :title => "#{@project || Setting.app_title}: #{title}")
|
|
||||||
}
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -265,9 +338,8 @@ class ProjectsController < ApplicationController
|
|||||||
:include => [:tracker, :status, :assigned_to, :priority, :project],
|
:include => [:tracker, :status, :assigned_to, :priority, :project],
|
||||||
:conditions => ["((start_date BETWEEN ? AND ?) OR (due_date BETWEEN ? AND ?)) AND #{Issue.table_name}.tracker_id IN (#{@selected_tracker_ids.join(',')})", @calendar.startdt, @calendar.enddt, @calendar.startdt, @calendar.enddt]
|
:conditions => ["((start_date BETWEEN ? AND ?) OR (due_date BETWEEN ? AND ?)) AND #{Issue.table_name}.tracker_id IN (#{@selected_tracker_ids.join(',')})", @calendar.startdt, @calendar.enddt, @calendar.startdt, @calendar.enddt]
|
||||||
) unless @selected_tracker_ids.empty?
|
) unless @selected_tracker_ids.empty?
|
||||||
events += Version.find(:all, :include => :project,
|
|
||||||
:conditions => ["effective_date BETWEEN ? AND ?", @calendar.startdt, @calendar.enddt])
|
|
||||||
end
|
end
|
||||||
|
events += @project.versions.find(:all, :conditions => ["effective_date BETWEEN ? AND ?", @calendar.startdt, @calendar.enddt])
|
||||||
@calendar.events = events
|
@calendar.events = events
|
||||||
|
|
||||||
render :layout => false if request.xhr?
|
render :layout => false if request.xhr?
|
||||||
@@ -306,21 +378,13 @@ class ProjectsController < ApplicationController
|
|||||||
|
|
||||||
@events = []
|
@events = []
|
||||||
@project.issues_with_subprojects(@with_subprojects) do
|
@project.issues_with_subprojects(@with_subprojects) do
|
||||||
# Issues that have start and due dates
|
|
||||||
@events += Issue.find(:all,
|
@events += Issue.find(:all,
|
||||||
:order => "start_date, due_date",
|
:order => "start_date, due_date",
|
||||||
:include => [:tracker, :status, :assigned_to, :priority, :project],
|
:include => [:tracker, :status, :assigned_to, :priority, :project],
|
||||||
:conditions => ["(((start_date>=? and start_date<=?) or (due_date>=? and due_date<=?) or (start_date<? and due_date>?)) and start_date is not null and due_date is not null and #{Issue.table_name}.tracker_id in (#{@selected_tracker_ids.join(',')}))", @date_from, @date_to, @date_from, @date_to, @date_from, @date_to]
|
:conditions => ["(((start_date>=? and start_date<=?) or (due_date>=? and due_date<=?) or (start_date<? and due_date>?)) and start_date is not null and due_date is not null and #{Issue.table_name}.tracker_id in (#{@selected_tracker_ids.join(',')}))", @date_from, @date_to, @date_from, @date_to, @date_from, @date_to]
|
||||||
) unless @selected_tracker_ids.empty?
|
) unless @selected_tracker_ids.empty?
|
||||||
# Issues that don't have a due date but that are assigned to a version with a date
|
|
||||||
@events += Issue.find(:all,
|
|
||||||
:order => "start_date, effective_date",
|
|
||||||
:include => [:tracker, :status, :assigned_to, :priority, :project, :fixed_version],
|
|
||||||
:conditions => ["(((start_date>=? and start_date<=?) or (effective_date>=? and effective_date<=?) or (start_date<? and effective_date>?)) and start_date is not null and due_date is null and effective_date is not null and #{Issue.table_name}.tracker_id in (#{@selected_tracker_ids.join(',')}))", @date_from, @date_to, @date_from, @date_to, @date_from, @date_to]
|
|
||||||
) unless @selected_tracker_ids.empty?
|
|
||||||
@events += Version.find(:all, :include => :project,
|
|
||||||
:conditions => ["effective_date BETWEEN ? AND ?", @date_from, @date_to])
|
|
||||||
end
|
end
|
||||||
|
@events += @project.versions.find(:all, :conditions => ["effective_date BETWEEN ? AND ?", @date_from, @date_to])
|
||||||
@events.sort! {|x,y| x.start_date <=> y.start_date }
|
@events.sort! {|x,y| x.start_date <=> y.start_date }
|
||||||
|
|
||||||
if params[:format]=='pdf'
|
if params[:format]=='pdf'
|
||||||
+1
@@ -16,6 +16,7 @@
|
|||||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
|
||||||
class QueriesController < ApplicationController
|
class QueriesController < ApplicationController
|
||||||
|
layout 'base'
|
||||||
menu_item :issues
|
menu_item :issues
|
||||||
before_filter :find_query, :except => :new
|
before_filter :find_query, :except => :new
|
||||||
before_filter :find_optional_project, :only => :new
|
before_filter :find_optional_project, :only => :new
|
||||||
@@ -16,6 +16,7 @@
|
|||||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
|
||||||
class ReportsController < ApplicationController
|
class ReportsController < ApplicationController
|
||||||
|
layout 'base'
|
||||||
menu_item :issues
|
menu_item :issues
|
||||||
before_filter :find_project, :authorize
|
before_filter :find_project, :authorize
|
||||||
|
|
||||||
+32
-13
@@ -24,6 +24,7 @@ end
|
|||||||
|
|
||||||
class RepositoriesController < ApplicationController
|
class RepositoriesController < ApplicationController
|
||||||
layout 'base'
|
layout 'base'
|
||||||
|
menu_item :repository
|
||||||
before_filter :find_repository, :except => :edit
|
before_filter :find_repository, :except => :edit
|
||||||
before_filter :find_project, :only => :edit
|
before_filter :find_project, :only => :edit
|
||||||
before_filter :authorize
|
before_filter :authorize
|
||||||
@@ -54,7 +55,9 @@ class RepositoriesController < ApplicationController
|
|||||||
@entries = @repository.entries('')
|
@entries = @repository.entries('')
|
||||||
# latest changesets
|
# latest changesets
|
||||||
@changesets = @repository.changesets.find(:all, :limit => 10, :order => "committed_on DESC")
|
@changesets = @repository.changesets.find(:all, :limit => 10, :order => "committed_on DESC")
|
||||||
show_error and return unless @entries || @changesets.any?
|
show_error_not_found unless @entries || @changesets.any?
|
||||||
|
rescue Redmine::Scm::Adapters::CommandFailed => e
|
||||||
|
show_error_command_failed(e.message)
|
||||||
end
|
end
|
||||||
|
|
||||||
def browse
|
def browse
|
||||||
@@ -62,14 +65,18 @@ class RepositoriesController < ApplicationController
|
|||||||
if request.xhr?
|
if request.xhr?
|
||||||
@entries ? render(:partial => 'dir_list_content') : render(:nothing => true)
|
@entries ? render(:partial => 'dir_list_content') : render(:nothing => true)
|
||||||
else
|
else
|
||||||
show_error unless @entries
|
show_error_not_found unless @entries
|
||||||
end
|
end
|
||||||
|
rescue Redmine::Scm::Adapters::CommandFailed => e
|
||||||
|
show_error_command_failed(e.message)
|
||||||
end
|
end
|
||||||
|
|
||||||
def changes
|
def changes
|
||||||
@entry = @repository.scm.entry(@path, @rev)
|
@entry = @repository.scm.entry(@path, @rev)
|
||||||
show_error and return unless @entry
|
show_error_not_found and return unless @entry
|
||||||
@changesets = @repository.changesets_for_path(@path)
|
@changesets = @repository.changesets_for_path(@path)
|
||||||
|
rescue Redmine::Scm::Adapters::CommandFailed => e
|
||||||
|
show_error_command_failed(e.message)
|
||||||
end
|
end
|
||||||
|
|
||||||
def revisions
|
def revisions
|
||||||
@@ -89,18 +96,23 @@ class RepositoriesController < ApplicationController
|
|||||||
|
|
||||||
def entry
|
def entry
|
||||||
@content = @repository.scm.cat(@path, @rev)
|
@content = @repository.scm.cat(@path, @rev)
|
||||||
show_error and return unless @content
|
show_error_not_found and return unless @content
|
||||||
if 'raw' == params[:format]
|
if 'raw' == params[:format] || @content.is_binary_data?
|
||||||
|
# Force the download if it's a binary file
|
||||||
send_data @content, :filename => @path.split('/').last
|
send_data @content, :filename => @path.split('/').last
|
||||||
else
|
else
|
||||||
# Prevent empty lines when displaying a file with Windows style eol
|
# Prevent empty lines when displaying a file with Windows style eol
|
||||||
@content.gsub!("\r\n", "\n")
|
@content.gsub!("\r\n", "\n")
|
||||||
end
|
end
|
||||||
|
rescue Redmine::Scm::Adapters::CommandFailed => e
|
||||||
|
show_error_command_failed(e.message)
|
||||||
end
|
end
|
||||||
|
|
||||||
def annotate
|
def annotate
|
||||||
@annotate = @repository.scm.annotate(@path, @rev)
|
@annotate = @repository.scm.annotate(@path, @rev)
|
||||||
show_error and return if @annotate.nil? || @annotate.empty?
|
render_error l(:error_scm_annotate) and return if @annotate.nil? || @annotate.empty?
|
||||||
|
rescue Redmine::Scm::Adapters::CommandFailed => e
|
||||||
|
show_error_command_failed(e.message)
|
||||||
end
|
end
|
||||||
|
|
||||||
def revision
|
def revision
|
||||||
@@ -117,11 +129,13 @@ class RepositoriesController < ApplicationController
|
|||||||
format.js {render :layout => false}
|
format.js {render :layout => false}
|
||||||
end
|
end
|
||||||
rescue ChangesetNotFound
|
rescue ChangesetNotFound
|
||||||
show_error
|
show_error_not_found
|
||||||
|
rescue Redmine::Scm::Adapters::CommandFailed => e
|
||||||
|
show_error_command_failed(e.message)
|
||||||
end
|
end
|
||||||
|
|
||||||
def diff
|
def diff
|
||||||
@rev_to = params[:rev_to] ? params[:rev_to].to_i : (@rev - 1)
|
@rev_to = params[:rev_to]
|
||||||
@diff_type = params[:type] || User.current.pref[:diff_type] || 'inline'
|
@diff_type = params[:type] || User.current.pref[:diff_type] || 'inline'
|
||||||
@diff_type = 'inline' unless %w(inline sbs).include?(@diff_type)
|
@diff_type = 'inline' unless %w(inline sbs).include?(@diff_type)
|
||||||
|
|
||||||
@@ -134,8 +148,10 @@ class RepositoriesController < ApplicationController
|
|||||||
@cache_key = "repositories/diff/#{@repository.id}/" + Digest::MD5.hexdigest("#{@path}-#{@rev}-#{@rev_to}-#{@diff_type}")
|
@cache_key = "repositories/diff/#{@repository.id}/" + Digest::MD5.hexdigest("#{@path}-#{@rev}-#{@rev_to}-#{@diff_type}")
|
||||||
unless read_fragment(@cache_key)
|
unless read_fragment(@cache_key)
|
||||||
@diff = @repository.diff(@path, @rev, @rev_to, @diff_type)
|
@diff = @repository.diff(@path, @rev, @rev_to, @diff_type)
|
||||||
show_error and return unless @diff
|
show_error_not_found unless @diff
|
||||||
end
|
end
|
||||||
|
rescue Redmine::Scm::Adapters::CommandFailed => e
|
||||||
|
show_error_command_failed(e.message)
|
||||||
end
|
end
|
||||||
|
|
||||||
def stats
|
def stats
|
||||||
@@ -170,14 +186,17 @@ private
|
|||||||
render_404 and return false unless @repository
|
render_404 and return false unless @repository
|
||||||
@path = params[:path].join('/') unless params[:path].nil?
|
@path = params[:path].join('/') unless params[:path].nil?
|
||||||
@path ||= ''
|
@path ||= ''
|
||||||
@rev = params[:rev].to_i if params[:rev]
|
@rev = params[:rev]
|
||||||
rescue ActiveRecord::RecordNotFound
|
rescue ActiveRecord::RecordNotFound
|
||||||
render_404
|
render_404
|
||||||
end
|
end
|
||||||
|
|
||||||
def show_error
|
def show_error_not_found
|
||||||
flash.now[:error] = l(:notice_scm_error)
|
render_error l(:error_scm_not_found)
|
||||||
render :nothing => true, :layout => true
|
end
|
||||||
|
|
||||||
|
def show_error_command_failed(msg)
|
||||||
|
render_error l(:error_scm_command_failed, msg)
|
||||||
end
|
end
|
||||||
|
|
||||||
def graph_commits_per_month(repository)
|
def graph_commits_per_month(repository)
|
||||||
@@ -16,6 +16,7 @@
|
|||||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
|
||||||
class RolesController < ApplicationController
|
class RolesController < ApplicationController
|
||||||
|
layout 'base'
|
||||||
before_filter :require_admin
|
before_filter :require_admin
|
||||||
|
|
||||||
verify :method => :post, :only => [ :destroy, :move ],
|
verify :method => :post, :only => [ :destroy, :move ],
|
||||||
+5
-6
@@ -18,6 +18,8 @@
|
|||||||
class SearchController < ApplicationController
|
class SearchController < ApplicationController
|
||||||
layout 'base'
|
layout 'base'
|
||||||
|
|
||||||
|
before_filter :find_optional_project
|
||||||
|
|
||||||
helper :messages
|
helper :messages
|
||||||
include MessagesHelper
|
include MessagesHelper
|
||||||
|
|
||||||
@@ -36,11 +38,6 @@ class SearchController < ApplicationController
|
|||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
if params[:id]
|
|
||||||
find_project
|
|
||||||
return unless check_project_privacy
|
|
||||||
end
|
|
||||||
|
|
||||||
if @project
|
if @project
|
||||||
# only show what the user is allowed to view
|
# only show what the user is allowed to view
|
||||||
@object_types = %w(issues news documents changesets wiki_pages messages)
|
@object_types = %w(issues news documents changesets wiki_pages messages)
|
||||||
@@ -104,8 +101,10 @@ class SearchController < ApplicationController
|
|||||||
end
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
def find_project
|
def find_optional_project
|
||||||
|
return true unless params[:id]
|
||||||
@project = Project.find(params[:id])
|
@project = Project.find(params[:id])
|
||||||
|
check_project_privacy
|
||||||
rescue ActiveRecord::RecordNotFound
|
rescue ActiveRecord::RecordNotFound
|
||||||
render_404
|
render_404
|
||||||
end
|
end
|
||||||
+2
-2
@@ -16,6 +16,7 @@
|
|||||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
|
||||||
class SettingsController < ApplicationController
|
class SettingsController < ApplicationController
|
||||||
|
layout 'base'
|
||||||
before_filter :require_admin
|
before_filter :require_admin
|
||||||
|
|
||||||
def index
|
def index
|
||||||
@@ -38,7 +39,6 @@ class SettingsController < ApplicationController
|
|||||||
end
|
end
|
||||||
@options = {}
|
@options = {}
|
||||||
@options[:user_format] = User::USER_FORMATS.keys.collect {|f| [User.current.name(f), f.to_s] }
|
@options[:user_format] = User::USER_FORMATS.keys.collect {|f| [User.current.name(f), f.to_s] }
|
||||||
@deliveries = ActionMailer::Base.perform_deliveries
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def plugin
|
def plugin
|
||||||
@@ -49,7 +49,7 @@ class SettingsController < ApplicationController
|
|||||||
flash[:notice] = l(:notice_successful_update)
|
flash[:notice] = l(:notice_successful_update)
|
||||||
redirect_to :action => 'plugin', :id => params[:id]
|
redirect_to :action => 'plugin', :id => params[:id]
|
||||||
end
|
end
|
||||||
@partial = @plugin.settings[:partial]
|
@partial = "../../vendor/plugins/#{plugin_id}/app/views/" + @plugin.settings[:partial]
|
||||||
@settings = Setting["plugin_#{plugin_id}"]
|
@settings = Setting["plugin_#{plugin_id}"]
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
File renamed without changes.
+110
-136
@@ -16,6 +16,7 @@
|
|||||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
|
||||||
class TimelogController < ApplicationController
|
class TimelogController < ApplicationController
|
||||||
|
layout 'base'
|
||||||
menu_item :issues
|
menu_item :issues
|
||||||
before_filter :find_project, :authorize
|
before_filter :find_project, :authorize
|
||||||
|
|
||||||
@@ -25,8 +26,6 @@ class TimelogController < ApplicationController
|
|||||||
include SortHelper
|
include SortHelper
|
||||||
helper :issues
|
helper :issues
|
||||||
include TimelogHelper
|
include TimelogHelper
|
||||||
helper :custom_fields
|
|
||||||
include CustomFieldsHelper
|
|
||||||
|
|
||||||
def report
|
def report
|
||||||
@available_criterias = { 'project' => {:sql => "#{TimeEntry.table_name}.project_id",
|
@available_criterias = { 'project' => {:sql => "#{TimeEntry.table_name}.project_id",
|
||||||
@@ -46,47 +45,37 @@ class TimelogController < ApplicationController
|
|||||||
:label => :label_tracker},
|
:label => :label_tracker},
|
||||||
'activity' => {:sql => "#{TimeEntry.table_name}.activity_id",
|
'activity' => {:sql => "#{TimeEntry.table_name}.activity_id",
|
||||||
:klass => Enumeration,
|
:klass => Enumeration,
|
||||||
:label => :label_activity},
|
:label => :label_activity}
|
||||||
'issue' => {:sql => "#{TimeEntry.table_name}.issue_id",
|
|
||||||
:klass => Issue,
|
|
||||||
:label => :label_issue}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
# Add list and boolean custom fields as available criterias
|
|
||||||
@project.all_issue_custom_fields.select {|cf| %w(list bool).include? cf.field_format }.each do |cf|
|
|
||||||
@available_criterias["cf_#{cf.id}"] = {:sql => "(SELECT c.value FROM #{CustomValue.table_name} c WHERE c.custom_field_id = #{cf.id} AND c.customized_type = 'Issue' AND c.customized_id = #{Issue.table_name}.id)",
|
|
||||||
:format => cf.field_format,
|
|
||||||
:label => cf.name}
|
|
||||||
end
|
|
||||||
|
|
||||||
# Add list and boolean time entry custom fields
|
|
||||||
TimeEntryCustomField.find(:all).select {|cf| %w(list bool).include? cf.field_format }.each do |cf|
|
|
||||||
@available_criterias["cf_#{cf.id}"] = {:sql => "(SELECT c.value FROM #{CustomValue.table_name} c WHERE c.custom_field_id = #{cf.id} AND c.customized_type = 'TimeEntry' AND c.customized_id = #{TimeEntry.table_name}.id)",
|
|
||||||
:format => cf.field_format,
|
|
||||||
:label => cf.name}
|
|
||||||
end
|
|
||||||
|
|
||||||
@criterias = params[:criterias] || []
|
@criterias = params[:criterias] || []
|
||||||
@criterias = @criterias.select{|criteria| @available_criterias.has_key? criteria}
|
@criterias = @criterias.select{|criteria| @available_criterias.has_key? criteria}
|
||||||
@criterias.uniq!
|
@criterias.uniq!
|
||||||
@criterias = @criterias[0,3]
|
@criterias = @criterias[0,3]
|
||||||
|
|
||||||
@columns = (params[:columns] && %w(year month week day).include?(params[:columns])) ? params[:columns] : 'month'
|
@columns = (params[:period] && %w(year month week).include?(params[:period])) ? params[:period] : 'month'
|
||||||
|
|
||||||
retrieve_date_range
|
if params[:date_from]
|
||||||
|
begin; @date_from = params[:date_from].to_date; rescue; end
|
||||||
|
end
|
||||||
|
if params[:date_to]
|
||||||
|
begin; @date_to = params[:date_to].to_date; rescue; end
|
||||||
|
end
|
||||||
|
@date_from ||= Date.civil(Date.today.year, 1, 1)
|
||||||
|
@date_to ||= (Date.civil(Date.today.year, Date.today.month, 1) >> 1) - 1
|
||||||
|
|
||||||
unless @criterias.empty?
|
unless @criterias.empty?
|
||||||
sql_select = @criterias.collect{|criteria| @available_criterias[criteria][:sql] + " AS " + criteria}.join(', ')
|
sql_select = @criterias.collect{|criteria| @available_criterias[criteria][:sql] + " AS " + criteria}.join(', ')
|
||||||
sql_group_by = @criterias.collect{|criteria| @available_criterias[criteria][:sql]}.join(', ')
|
sql_group_by = @criterias.collect{|criteria| @available_criterias[criteria][:sql]}.join(', ')
|
||||||
|
|
||||||
sql = "SELECT #{sql_select}, tyear, tmonth, tweek, spent_on, SUM(hours) AS hours"
|
sql = "SELECT #{sql_select}, tyear, tmonth, tweek, SUM(hours) AS hours"
|
||||||
sql << " FROM #{TimeEntry.table_name}"
|
sql << " FROM #{TimeEntry.table_name}"
|
||||||
sql << " LEFT JOIN #{Issue.table_name} ON #{TimeEntry.table_name}.issue_id = #{Issue.table_name}.id"
|
sql << " LEFT JOIN #{Issue.table_name} ON #{TimeEntry.table_name}.issue_id = #{Issue.table_name}.id"
|
||||||
sql << " LEFT JOIN #{Project.table_name} ON #{TimeEntry.table_name}.project_id = #{Project.table_name}.id"
|
sql << " LEFT JOIN #{Project.table_name} ON #{TimeEntry.table_name}.project_id = #{Project.table_name}.id"
|
||||||
sql << " WHERE (%s)" % @project.project_condition(Setting.display_subprojects_issues?)
|
sql << " WHERE (%s)" % @project.project_condition(Setting.display_subprojects_issues?)
|
||||||
sql << " AND (%s)" % Project.allowed_to_condition(User.current, :view_time_entries)
|
sql << " AND (%s)" % Project.allowed_to_condition(User.current, :view_time_entries)
|
||||||
sql << " AND spent_on BETWEEN '%s' AND '%s'" % [ActiveRecord::Base.connection.quoted_date(@from.to_time), ActiveRecord::Base.connection.quoted_date(@to.to_time)]
|
sql << " AND spent_on BETWEEN '%s' AND '%s'" % [ActiveRecord::Base.connection.quoted_date(@date_from.to_time), ActiveRecord::Base.connection.quoted_date(@date_to.to_time)]
|
||||||
sql << " GROUP BY #{sql_group_by}, tyear, tmonth, tweek, spent_on"
|
sql << " GROUP BY #{sql_group_by}, tyear, tmonth, tweek"
|
||||||
|
|
||||||
@hours = ActiveRecord::Base.connection.select_all(sql)
|
@hours = ActiveRecord::Base.connection.select_all(sql)
|
||||||
|
|
||||||
@@ -98,129 +87,36 @@ class TimelogController < ApplicationController
|
|||||||
row['month'] = "#{row['tyear']}-#{row['tmonth']}"
|
row['month'] = "#{row['tyear']}-#{row['tmonth']}"
|
||||||
when 'week'
|
when 'week'
|
||||||
row['week'] = "#{row['tyear']}-#{row['tweek']}"
|
row['week'] = "#{row['tyear']}-#{row['tweek']}"
|
||||||
when 'day'
|
|
||||||
row['day'] = "#{row['spent_on']}"
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@total_hours = @hours.inject(0) {|s,k| s = s + k['hours'].to_f}
|
@total_hours = @hours.inject(0) {|s,k| s = s + k['hours'].to_f}
|
||||||
|
end
|
||||||
|
|
||||||
@periods = []
|
@periods = []
|
||||||
# Date#at_beginning_of_ not supported in Rails 1.2.x
|
date_from = @date_from
|
||||||
date_from = @from.to_time
|
# 100 columns max
|
||||||
# 100 columns max
|
while date_from < @date_to && @periods.length < 100
|
||||||
while date_from <= @to.to_time && @periods.length < 100
|
case @columns
|
||||||
case @columns
|
when 'year'
|
||||||
when 'year'
|
@periods << "#{date_from.year}"
|
||||||
@periods << "#{date_from.year}"
|
date_from = date_from >> 12
|
||||||
date_from = (date_from + 1.year).at_beginning_of_year
|
when 'month'
|
||||||
when 'month'
|
@periods << "#{date_from.year}-#{date_from.month}"
|
||||||
@periods << "#{date_from.year}-#{date_from.month}"
|
date_from = date_from >> 1
|
||||||
date_from = (date_from + 1.month).at_beginning_of_month
|
when 'week'
|
||||||
when 'week'
|
@periods << "#{date_from.year}-#{date_from.cweek}"
|
||||||
@periods << "#{date_from.year}-#{date_from.to_date.cweek}"
|
date_from = date_from + 7
|
||||||
date_from = (date_from + 7.day).at_beginning_of_week
|
|
||||||
when 'day'
|
|
||||||
@periods << "#{date_from.to_date}"
|
|
||||||
date_from = date_from + 1.day
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
respond_to do |format|
|
render :layout => false if request.xhr?
|
||||||
format.html { render :layout => !request.xhr? }
|
|
||||||
format.csv { send_data(report_to_csv(@criterias, @periods, @hours).read, :type => 'text/csv; header=present', :filename => 'timelog.csv') }
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def details
|
def details
|
||||||
sort_init 'spent_on', 'desc'
|
sort_init 'spent_on', 'desc'
|
||||||
sort_update
|
sort_update
|
||||||
|
|
||||||
cond = ARCondition.new
|
|
||||||
cond << (@issue.nil? ? @project.project_condition(Setting.display_subprojects_issues?) :
|
|
||||||
["#{TimeEntry.table_name}.issue_id = ?", @issue.id])
|
|
||||||
|
|
||||||
retrieve_date_range
|
|
||||||
cond << ['spent_on BETWEEN ? AND ?', @from, @to]
|
|
||||||
|
|
||||||
TimeEntry.visible_by(User.current) do
|
|
||||||
respond_to do |format|
|
|
||||||
format.html {
|
|
||||||
# Paginate results
|
|
||||||
@entry_count = TimeEntry.count(:include => :project, :conditions => cond.conditions)
|
|
||||||
@entry_pages = Paginator.new self, @entry_count, per_page_option, params['page']
|
|
||||||
@entries = TimeEntry.find(:all,
|
|
||||||
:include => [:project, :activity, :user, {:issue => :tracker}],
|
|
||||||
:conditions => cond.conditions,
|
|
||||||
:order => sort_clause,
|
|
||||||
:limit => @entry_pages.items_per_page,
|
|
||||||
:offset => @entry_pages.current.offset)
|
|
||||||
@total_hours = TimeEntry.sum(:hours, :include => :project, :conditions => cond.conditions).to_f
|
|
||||||
|
|
||||||
render :layout => !request.xhr?
|
|
||||||
}
|
|
||||||
format.atom {
|
|
||||||
entries = TimeEntry.find(:all,
|
|
||||||
:include => [:project, :activity, :user, {:issue => :tracker}],
|
|
||||||
:conditions => cond.conditions,
|
|
||||||
:order => "#{TimeEntry.table_name}.created_on DESC",
|
|
||||||
:limit => Setting.feeds_limit.to_i)
|
|
||||||
render_feed(entries, :title => l(:label_spent_time))
|
|
||||||
}
|
|
||||||
format.csv {
|
|
||||||
# Export all entries
|
|
||||||
@entries = TimeEntry.find(:all,
|
|
||||||
:include => [:project, :activity, :user, {:issue => [:tracker, :assigned_to, :priority]}],
|
|
||||||
:conditions => cond.conditions,
|
|
||||||
:order => sort_clause)
|
|
||||||
send_data(entries_to_csv(@entries).read, :type => 'text/csv; header=present', :filename => 'timelog.csv')
|
|
||||||
}
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def edit
|
|
||||||
render_403 and return if @time_entry && !@time_entry.editable_by?(User.current)
|
|
||||||
@time_entry ||= TimeEntry.new(:project => @project, :issue => @issue, :user => User.current, :spent_on => Date.today)
|
|
||||||
@time_entry.attributes = params[:time_entry]
|
|
||||||
if request.post? and @time_entry.save
|
|
||||||
flash[:notice] = l(:notice_successful_update)
|
|
||||||
redirect_to(params[:back_url].blank? ? {:action => 'details', :project_id => @time_entry.project} : params[:back_url])
|
|
||||||
return
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def destroy
|
|
||||||
render_404 and return unless @time_entry
|
|
||||||
render_403 and return unless @time_entry.editable_by?(User.current)
|
|
||||||
@time_entry.destroy
|
|
||||||
flash[:notice] = l(:notice_successful_delete)
|
|
||||||
redirect_to :back
|
|
||||||
rescue RedirectBackError
|
|
||||||
redirect_to :action => 'details', :project_id => @time_entry.project
|
|
||||||
end
|
|
||||||
|
|
||||||
private
|
|
||||||
def find_project
|
|
||||||
if params[:id]
|
|
||||||
@time_entry = TimeEntry.find(params[:id])
|
|
||||||
@project = @time_entry.project
|
|
||||||
elsif params[:issue_id]
|
|
||||||
@issue = Issue.find(params[:issue_id])
|
|
||||||
@project = @issue.project
|
|
||||||
elsif params[:project_id]
|
|
||||||
@project = Project.find(params[:project_id])
|
|
||||||
else
|
|
||||||
render_404
|
|
||||||
return false
|
|
||||||
end
|
|
||||||
rescue ActiveRecord::RecordNotFound
|
|
||||||
render_404
|
|
||||||
end
|
|
||||||
|
|
||||||
# Retrieves the date range based on predefined ranges or specific from/to param dates
|
|
||||||
def retrieve_date_range
|
|
||||||
@free_period = false
|
@free_period = false
|
||||||
@from, @to = nil, nil
|
@from, @to = nil, nil
|
||||||
|
|
||||||
@@ -261,7 +157,85 @@ private
|
|||||||
end
|
end
|
||||||
|
|
||||||
@from, @to = @to, @from if @from && @to && @from > @to
|
@from, @to = @to, @from if @from && @to && @from > @to
|
||||||
@from ||= (TimeEntry.minimum(:spent_on, :include => :project, :conditions => @project.project_condition(Setting.display_subprojects_issues?)) || Date.today) - 1
|
|
||||||
@to ||= (TimeEntry.maximum(:spent_on, :include => :project, :conditions => @project.project_condition(Setting.display_subprojects_issues?)) || Date.today)
|
cond = ARCondition.new
|
||||||
|
cond << (@issue.nil? ? @project.project_condition(Setting.display_subprojects_issues?) :
|
||||||
|
["#{TimeEntry.table_name}.issue_id = ?", @issue.id])
|
||||||
|
|
||||||
|
if @from
|
||||||
|
if @to
|
||||||
|
cond << ['spent_on BETWEEN ? AND ?', @from, @to]
|
||||||
|
else
|
||||||
|
cond << ['spent_on >= ?', @from]
|
||||||
|
end
|
||||||
|
elsif @to
|
||||||
|
cond << ['spent_on <= ?', @to]
|
||||||
|
end
|
||||||
|
|
||||||
|
TimeEntry.visible_by(User.current) do
|
||||||
|
respond_to do |format|
|
||||||
|
format.html {
|
||||||
|
# Paginate results
|
||||||
|
@entry_count = TimeEntry.count(:include => :project, :conditions => cond.conditions)
|
||||||
|
@entry_pages = Paginator.new self, @entry_count, per_page_option, params['page']
|
||||||
|
@entries = TimeEntry.find(:all,
|
||||||
|
:include => [:project, :activity, :user, {:issue => :tracker}],
|
||||||
|
:conditions => cond.conditions,
|
||||||
|
:order => sort_clause,
|
||||||
|
:limit => @entry_pages.items_per_page,
|
||||||
|
:offset => @entry_pages.current.offset)
|
||||||
|
@total_hours = TimeEntry.sum(:hours, :include => :project, :conditions => cond.conditions).to_f
|
||||||
|
render :layout => !request.xhr?
|
||||||
|
}
|
||||||
|
format.csv {
|
||||||
|
# Export all entries
|
||||||
|
@entries = TimeEntry.find(:all,
|
||||||
|
:include => [:project, :activity, :user, {:issue => [:tracker, :assigned_to, :priority]}],
|
||||||
|
:conditions => cond.conditions,
|
||||||
|
:order => sort_clause)
|
||||||
|
send_data(entries_to_csv(@entries).read, :type => 'text/csv; header=present', :filename => 'timelog.csv')
|
||||||
|
}
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def edit
|
||||||
|
render_403 and return if @time_entry && !@time_entry.editable_by?(User.current)
|
||||||
|
@time_entry ||= TimeEntry.new(:project => @project, :issue => @issue, :user => User.current, :spent_on => Date.today)
|
||||||
|
@time_entry.attributes = params[:time_entry]
|
||||||
|
if request.post? and @time_entry.save
|
||||||
|
flash[:notice] = l(:notice_successful_update)
|
||||||
|
redirect_to :action => 'details', :project_id => @time_entry.project
|
||||||
|
return
|
||||||
|
end
|
||||||
|
@activities = Enumeration::get_values('ACTI')
|
||||||
|
end
|
||||||
|
|
||||||
|
def destroy
|
||||||
|
render_404 and return unless @time_entry
|
||||||
|
render_403 and return unless @time_entry.editable_by?(User.current)
|
||||||
|
@time_entry.destroy
|
||||||
|
flash[:notice] = l(:notice_successful_delete)
|
||||||
|
redirect_to :back
|
||||||
|
rescue RedirectBackError
|
||||||
|
redirect_to :action => 'details', :project_id => @time_entry.project
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
def find_project
|
||||||
|
if params[:id]
|
||||||
|
@time_entry = TimeEntry.find(params[:id])
|
||||||
|
@project = @time_entry.project
|
||||||
|
elsif params[:issue_id]
|
||||||
|
@issue = Issue.find(params[:issue_id])
|
||||||
|
@project = @issue.project
|
||||||
|
elsif params[:project_id]
|
||||||
|
@project = Project.find(params[:project_id])
|
||||||
|
else
|
||||||
|
render_404
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
rescue ActiveRecord::RecordNotFound
|
||||||
|
render_404
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
+1
@@ -16,6 +16,7 @@
|
|||||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
|
||||||
class TrackersController < ApplicationController
|
class TrackersController < ApplicationController
|
||||||
|
layout 'base'
|
||||||
before_filter :require_admin
|
before_filter :require_admin
|
||||||
|
|
||||||
def index
|
def index
|
||||||
+1
-1
@@ -34,7 +34,7 @@ class UsersController < ApplicationController
|
|||||||
sort_update
|
sort_update
|
||||||
|
|
||||||
@status = params[:status] ? params[:status].to_i : 1
|
@status = params[:status] ? params[:status].to_i : 1
|
||||||
conditions = nil
|
conditions = "status <> 0"
|
||||||
conditions = ["status=?", @status] unless @status == 0
|
conditions = ["status=?", @status] unless @status == 0
|
||||||
|
|
||||||
@user_count = User.count(:conditions => conditions)
|
@user_count = User.count(:conditions => conditions)
|
||||||
+3
-3
@@ -17,10 +17,9 @@
|
|||||||
|
|
||||||
class VersionsController < ApplicationController
|
class VersionsController < ApplicationController
|
||||||
layout 'base'
|
layout 'base'
|
||||||
|
menu_item :roadmap
|
||||||
before_filter :find_project, :authorize
|
before_filter :find_project, :authorize
|
||||||
|
|
||||||
cache_sweeper :version_sweeper, :only => [ :edit, :destroy ]
|
|
||||||
|
|
||||||
def show
|
def show
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -42,7 +41,8 @@ class VersionsController < ApplicationController
|
|||||||
def download
|
def download
|
||||||
@attachment = @version.attachments.find(params[:attachment_id])
|
@attachment = @version.attachments.find(params[:attachment_id])
|
||||||
@attachment.increment_download
|
@attachment.increment_download
|
||||||
send_file @attachment.diskfile, :filename => @attachment.filename, :type => @attachment.content_type
|
send_file @attachment.diskfile, :filename => filename_for_content_disposition(@attachment.filename),
|
||||||
|
:type => @attachment.content_type
|
||||||
rescue
|
rescue
|
||||||
render_404
|
render_404
|
||||||
end
|
end
|
||||||
File renamed without changes.
File renamed without changes.
File renamed without changes.
@@ -16,6 +16,7 @@
|
|||||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
|
||||||
class WikisController < ApplicationController
|
class WikisController < ApplicationController
|
||||||
|
layout 'base'
|
||||||
menu_item :settings
|
menu_item :settings
|
||||||
before_filter :find_project, :authorize
|
before_filter :find_project, :authorize
|
||||||
|
|
||||||
File renamed without changes.
File renamed without changes.
@@ -15,9 +15,6 @@
|
|||||||
# along with this program; if not, write to the Free Software
|
# along with this program; if not, write to the Free Software
|
||||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
|
||||||
require 'coderay'
|
|
||||||
require 'coderay/helpers/file_type'
|
|
||||||
|
|
||||||
module ApplicationHelper
|
module ApplicationHelper
|
||||||
include Redmine::WikiFormatting::Macros::Definitions
|
include Redmine::WikiFormatting::Macros::Definitions
|
||||||
|
|
||||||
@@ -41,23 +38,9 @@ module ApplicationHelper
|
|||||||
end
|
end
|
||||||
|
|
||||||
def link_to_issue(issue, options={})
|
def link_to_issue(issue, options={})
|
||||||
options[:class] ||= ''
|
|
||||||
options[:class] << ' issue'
|
|
||||||
options[:class] << ' closed' if issue.closed?
|
|
||||||
link_to "#{issue.tracker.name} ##{issue.id}", {:controller => "issues", :action => "show", :id => issue}, options
|
link_to "#{issue.tracker.name} ##{issue.id}", {:controller => "issues", :action => "show", :id => issue}, options
|
||||||
end
|
end
|
||||||
|
|
||||||
# Generates a link to an attachment.
|
|
||||||
# Options:
|
|
||||||
# * :text - Link text (default to attachment filename)
|
|
||||||
# * :download - Force download (default: false)
|
|
||||||
def link_to_attachment(attachment, options={})
|
|
||||||
text = options.delete(:text) || attachment.filename
|
|
||||||
action = options.delete(:download) ? 'download' : 'show'
|
|
||||||
|
|
||||||
link_to(h(text), {:controller => 'attachments', :action => action, :id => attachment, :filename => attachment.filename }, options)
|
|
||||||
end
|
|
||||||
|
|
||||||
def toggle_link(name, id, options={})
|
def toggle_link(name, id, options={})
|
||||||
onclick = "Element.toggle('#{id}'); "
|
onclick = "Element.toggle('#{id}'); "
|
||||||
onclick << (options[:focus] ? "Form.Element.focus('#{options[:focus]}'); " : "this.blur(); ")
|
onclick << (options[:focus] ? "Form.Element.focus('#{options[:focus]}'); " : "this.blur(); ")
|
||||||
@@ -65,6 +48,14 @@ module ApplicationHelper
|
|||||||
link_to(name, "#", :onclick => onclick)
|
link_to(name, "#", :onclick => onclick)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def show_and_goto_link(name, id, options={})
|
||||||
|
onclick = "Element.show('#{id}'); "
|
||||||
|
onclick << (options[:focus] ? "Form.Element.focus('#{options[:focus]}'); " : "this.blur(); ")
|
||||||
|
onclick << "Element.scrollTo('#{id}'); "
|
||||||
|
onclick << "return false;"
|
||||||
|
link_to(name, "#", options.merge(:onclick => onclick))
|
||||||
|
end
|
||||||
|
|
||||||
def image_to_function(name, function, html_options = {})
|
def image_to_function(name, function, html_options = {})
|
||||||
html_options.symbolize_keys!
|
html_options.symbolize_keys!
|
||||||
tag(:input, html_options.merge({
|
tag(:input, html_options.merge({
|
||||||
@@ -89,25 +80,23 @@ module ApplicationHelper
|
|||||||
return nil unless time
|
return nil unless time
|
||||||
time = time.to_time if time.is_a?(String)
|
time = time.to_time if time.is_a?(String)
|
||||||
zone = User.current.time_zone
|
zone = User.current.time_zone
|
||||||
local = zone ? time.in_time_zone(zone) : (time.utc? ? time.utc_to_local : time)
|
if time.utc?
|
||||||
|
local = zone ? zone.adjust(time) : time.getlocal
|
||||||
|
else
|
||||||
|
local = zone ? zone.adjust(time.getutc) : time
|
||||||
|
end
|
||||||
@date_format ||= (Setting.date_format.blank? || Setting.date_format.size < 2 ? l(:general_fmt_date) : Setting.date_format)
|
@date_format ||= (Setting.date_format.blank? || Setting.date_format.size < 2 ? l(:general_fmt_date) : Setting.date_format)
|
||||||
@time_format ||= (Setting.time_format.blank? ? l(:general_fmt_time) : Setting.time_format)
|
@time_format ||= (Setting.time_format.blank? ? l(:general_fmt_time) : Setting.time_format)
|
||||||
include_date ? local.strftime("#{@date_format} #{@time_format}") : local.strftime(@time_format)
|
include_date ? local.strftime("#{@date_format} #{@time_format}") : local.strftime(@time_format)
|
||||||
end
|
end
|
||||||
|
|
||||||
# Truncates and returns the string as a single line
|
|
||||||
def truncate_single_line(string, *args)
|
|
||||||
truncate(string, *args).gsub(%r{[\r\n]+}m, ' ')
|
|
||||||
end
|
|
||||||
|
|
||||||
def html_hours(text)
|
def html_hours(text)
|
||||||
text.gsub(%r{(\d+)\.(\d+)}, '<span class="hours hours-int">\1</span><span class="hours hours-dec">.\2</span>')
|
text.gsub(%r{(\d+)\.(\d+)}, '<span class="hours hours-int">\1</span><span class="hours hours-dec">.\2</span>')
|
||||||
end
|
end
|
||||||
|
|
||||||
def authoring(created, author)
|
def authoring(created, author)
|
||||||
time_tag = content_tag('acronym', distance_of_time_in_words(Time.now, created), :title => format_time(created))
|
time_tag = content_tag('acronym', distance_of_time_in_words(Time.now, created), :title => format_time(created))
|
||||||
author_tag = (author.is_a?(User) && !author.anonymous?) ? link_to(h(author), :controller => 'account', :action => 'show', :id => author) : h(author || 'Anonymous')
|
l(:label_added_time_by, author || 'Anonymous', time_tag)
|
||||||
l(:label_added_time_by, author_tag, time_tag)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def l_or_humanize(s)
|
def l_or_humanize(s)
|
||||||
@@ -122,15 +111,6 @@ module ApplicationHelper
|
|||||||
l(:actionview_datehelper_select_month_names).split(',')[month-1]
|
l(:actionview_datehelper_select_month_names).split(',')[month-1]
|
||||||
end
|
end
|
||||||
|
|
||||||
def syntax_highlight(name, content)
|
|
||||||
type = CodeRay::FileType[name]
|
|
||||||
type ? CodeRay.scan(content, type).html : h(content)
|
|
||||||
end
|
|
||||||
|
|
||||||
def to_path_param(path)
|
|
||||||
path.to_s.split(%r{[/\\]}).select {|p| !p.blank?}
|
|
||||||
end
|
|
||||||
|
|
||||||
def pagination_links_full(paginator, count=nil, options={})
|
def pagination_links_full(paginator, count=nil, options={})
|
||||||
page_param = options.delete(:page_param) || :page
|
page_param = options.delete(:page_param) || :page
|
||||||
url_param = params.dup
|
url_param = params.dup
|
||||||
@@ -177,8 +157,7 @@ module ApplicationHelper
|
|||||||
end
|
end
|
||||||
|
|
||||||
def breadcrumb(*args)
|
def breadcrumb(*args)
|
||||||
elements = args.flatten
|
content_tag('p', args.join(' » ') + ' » ', :class => 'breadcrumb')
|
||||||
elements.any? ? content_tag('p', args.join(' » ') + ' » ', :class => 'breadcrumb') : nil
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def html_title(*args)
|
def html_title(*args)
|
||||||
@@ -206,7 +185,7 @@ module ApplicationHelper
|
|||||||
options = args.last.is_a?(Hash) ? args.pop : {}
|
options = args.last.is_a?(Hash) ? args.pop : {}
|
||||||
case args.size
|
case args.size
|
||||||
when 1
|
when 1
|
||||||
obj = options[:object]
|
obj = nil
|
||||||
text = args.shift
|
text = args.shift
|
||||||
when 2
|
when 2
|
||||||
obj = args.shift
|
obj = args.shift
|
||||||
@@ -228,10 +207,8 @@ module ApplicationHelper
|
|||||||
rf = Regexp.new(filename, Regexp::IGNORECASE)
|
rf = Regexp.new(filename, Regexp::IGNORECASE)
|
||||||
# search for the picture in attachments
|
# search for the picture in attachments
|
||||||
if found = attachments.detect { |att| att.filename =~ rf }
|
if found = attachments.detect { |att| att.filename =~ rf }
|
||||||
image_url = url_for :only_path => only_path, :controller => 'attachments', :action => 'download', :id => found
|
image_url = url_for :only_path => only_path, :controller => 'attachments', :action => 'download', :id => found.id
|
||||||
desc = found.description.to_s.gsub(/^([^\(\)]*).*$/, "\\1")
|
"!#{style}#{image_url}!"
|
||||||
alt = desc.blank? ? nil : "(#{desc})"
|
|
||||||
"!#{style}#{image_url}#{alt}!"
|
|
||||||
else
|
else
|
||||||
"!#{style}#{filename}!"
|
"!#{style}#{filename}!"
|
||||||
end
|
end
|
||||||
@@ -246,12 +223,12 @@ module ApplicationHelper
|
|||||||
case options[:wiki_links]
|
case options[:wiki_links]
|
||||||
when :local
|
when :local
|
||||||
# used for local links to html files
|
# used for local links to html files
|
||||||
format_wiki_link = Proc.new {|project, title, anchor| "#{title}.html" }
|
format_wiki_link = Proc.new {|project, title| "#{title}.html" }
|
||||||
when :anchor
|
when :anchor
|
||||||
# used for single-file wiki export
|
# used for single-file wiki export
|
||||||
format_wiki_link = Proc.new {|project, title, anchor| "##{title}" }
|
format_wiki_link = Proc.new {|project, title| "##{title}" }
|
||||||
else
|
else
|
||||||
format_wiki_link = Proc.new {|project, title, anchor| url_for(:only_path => only_path, :controller => 'wiki', :action => 'index', :id => project, :page => title, :anchor => anchor) }
|
format_wiki_link = Proc.new {|project, title| url_for(:only_path => only_path, :controller => 'wiki', :action => 'index', :id => project, :page => title) }
|
||||||
end
|
end
|
||||||
|
|
||||||
project = options[:project] || @project || (obj && obj.respond_to?(:project) ? obj.project : nil)
|
project = options[:project] || @project || (obj && obj.respond_to?(:project) ? obj.project : nil)
|
||||||
@@ -277,14 +254,9 @@ module ApplicationHelper
|
|||||||
end
|
end
|
||||||
|
|
||||||
if link_project && link_project.wiki
|
if link_project && link_project.wiki
|
||||||
# extract anchor
|
|
||||||
anchor = nil
|
|
||||||
if page =~ /^(.+?)\#(.+)$/
|
|
||||||
page, anchor = $1, $2
|
|
||||||
end
|
|
||||||
# check if page exists
|
# check if page exists
|
||||||
wiki_page = link_project.wiki.find_page(page)
|
wiki_page = link_project.wiki.find_page(page)
|
||||||
link_to((title || page), format_wiki_link.call(link_project, Wiki.titleize(page), anchor),
|
link_to((title || page), format_wiki_link.call(link_project, Wiki.titleize(page)),
|
||||||
:class => ('wiki-page' + (wiki_page ? '' : ' new')))
|
:class => ('wiki-page' + (wiki_page ? '' : ' new')))
|
||||||
else
|
else
|
||||||
# project or wiki doesn't exist
|
# project or wiki doesn't exist
|
||||||
@@ -319,9 +291,7 @@ module ApplicationHelper
|
|||||||
# source:some/file#L120 -> Link to line 120 of the file
|
# source:some/file#L120 -> Link to line 120 of the file
|
||||||
# source:some/file@52#L120 -> Link to line 120 of the file's revision 52
|
# source:some/file@52#L120 -> Link to line 120 of the file's revision 52
|
||||||
# export:some/file -> Force the download of the file
|
# export:some/file -> Force the download of the file
|
||||||
# Forum messages:
|
text = text.gsub(%r{([\s\(,-^])(!)?(attachment|document|version|commit|source|export)?((#|r)(\d+)|(:)([^"\s<>][^\s<>]*|"[^"]+"))(?=[[:punct:]]|\s|<|$)}) do |m|
|
||||||
# message#1218 -> Link to message with id 1218
|
|
||||||
text = text.gsub(%r{([\s\(,\-\>]|^)(!)?(attachment|document|version|commit|source|export|message)?((#|r)(\d+)|(:)([^"\s<>][^\s<>]*?|"[^"]+?"))(?=(?=[[:punct:]]\W)|\s|<|$)}) do |m|
|
|
||||||
leading, esc, prefix, sep, oid = $1, $2, $3, $5 || $7, $6 || $8
|
leading, esc, prefix, sep, oid = $1, $2, $3, $5 || $7, $6 || $8
|
||||||
link = nil
|
link = nil
|
||||||
if esc.nil?
|
if esc.nil?
|
||||||
@@ -329,7 +299,7 @@ module ApplicationHelper
|
|||||||
if project && (changeset = project.changesets.find_by_revision(oid))
|
if project && (changeset = project.changesets.find_by_revision(oid))
|
||||||
link = link_to("r#{oid}", {:only_path => only_path, :controller => 'repositories', :action => 'revision', :id => project, :rev => oid},
|
link = link_to("r#{oid}", {:only_path => only_path, :controller => 'repositories', :action => 'revision', :id => project, :rev => oid},
|
||||||
:class => 'changeset',
|
:class => 'changeset',
|
||||||
:title => truncate_single_line(changeset.comments, 100))
|
:title => truncate(changeset.comments, 100))
|
||||||
end
|
end
|
||||||
elsif sep == '#'
|
elsif sep == '#'
|
||||||
oid = oid.to_i
|
oid = oid.to_i
|
||||||
@@ -351,16 +321,6 @@ module ApplicationHelper
|
|||||||
link = link_to h(version.name), {:only_path => only_path, :controller => 'versions', :action => 'show', :id => version},
|
link = link_to h(version.name), {:only_path => only_path, :controller => 'versions', :action => 'show', :id => version},
|
||||||
:class => 'version'
|
:class => 'version'
|
||||||
end
|
end
|
||||||
when 'message'
|
|
||||||
if message = Message.find_by_id(oid, :include => [:parent, {:board => :project}], :conditions => Project.visible_by(User.current))
|
|
||||||
link = link_to h(truncate(message.subject, 60)), {:only_path => only_path,
|
|
||||||
:controller => 'messages',
|
|
||||||
:action => 'show',
|
|
||||||
:board_id => message.board,
|
|
||||||
:id => message.root,
|
|
||||||
:anchor => (message.parent ? "message-#{message.id}" : nil)},
|
|
||||||
:class => 'message'
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
elsif sep == ':'
|
elsif sep == ':'
|
||||||
# removes the double quotes if any
|
# removes the double quotes if any
|
||||||
@@ -378,16 +338,13 @@ module ApplicationHelper
|
|||||||
end
|
end
|
||||||
when 'commit'
|
when 'commit'
|
||||||
if project && (changeset = project.changesets.find(:first, :conditions => ["scmid LIKE ?", "#{name}%"]))
|
if project && (changeset = project.changesets.find(:first, :conditions => ["scmid LIKE ?", "#{name}%"]))
|
||||||
link = link_to h("#{name}"), {:only_path => only_path, :controller => 'repositories', :action => 'revision', :id => project, :rev => changeset.revision},
|
link = link_to h("#{name}"), {:only_path => only_path, :controller => 'repositories', :action => 'revision', :id => project, :rev => changeset.revision}, :class => 'changeset', :title => truncate(changeset.comments, 100)
|
||||||
:class => 'changeset',
|
|
||||||
:title => truncate_single_line(changeset.comments, 100)
|
|
||||||
end
|
end
|
||||||
when 'source', 'export'
|
when 'source', 'export'
|
||||||
if project && project.repository
|
if project && project.repository
|
||||||
name =~ %r{^[/\\]*(.*?)(@([0-9a-f]+))?(#(L\d+))?$}
|
name =~ %r{^[/\\]*(.*?)(@([0-9a-f]+))?(#(L\d+))?$}
|
||||||
path, rev, anchor = $1, $3, $5
|
path, rev, anchor = $1, $3, $5
|
||||||
link = link_to h("#{prefix}:#{name}"), {:controller => 'repositories', :action => 'entry', :id => project,
|
link = link_to h("#{prefix}:#{name}"), {:controller => 'repositories', :action => 'entry', :id => project, :path => path,
|
||||||
:path => to_path_param(path),
|
|
||||||
:rev => rev,
|
:rev => rev,
|
||||||
:anchor => anchor,
|
:anchor => anchor,
|
||||||
:format => (prefix == 'export' ? 'raw' : nil)},
|
:format => (prefix == 'export' ? 'raw' : nil)},
|
||||||
@@ -468,11 +425,6 @@ module ApplicationHelper
|
|||||||
form_for(name, object, options.merge({ :builder => TabularFormBuilder, :lang => current_language}), &proc)
|
form_for(name, object, options.merge({ :builder => TabularFormBuilder, :lang => current_language}), &proc)
|
||||||
end
|
end
|
||||||
|
|
||||||
def back_url_hidden_field_tag
|
|
||||||
back_url = params[:back_url] || request.env['HTTP_REFERER']
|
|
||||||
hidden_field_tag('back_url', back_url) unless back_url.blank?
|
|
||||||
end
|
|
||||||
|
|
||||||
def check_all_links(form_name)
|
def check_all_links(form_name)
|
||||||
link_to_function(l(:button_check_all), "checkAll('#{form_name}', true)") +
|
link_to_function(l(:button_check_all), "checkAll('#{form_name}', true)") +
|
||||||
" | " +
|
" | " +
|
||||||
@@ -511,23 +463,10 @@ module ApplicationHelper
|
|||||||
end
|
end
|
||||||
|
|
||||||
def calendar_for(field_id)
|
def calendar_for(field_id)
|
||||||
include_calendar_headers_tags
|
|
||||||
image_tag("calendar.png", {:id => "#{field_id}_trigger",:class => "calendar-trigger"}) +
|
image_tag("calendar.png", {:id => "#{field_id}_trigger",:class => "calendar-trigger"}) +
|
||||||
javascript_tag("Calendar.setup({inputField : '#{field_id}', ifFormat : '%Y-%m-%d', button : '#{field_id}_trigger' });")
|
javascript_tag("Calendar.setup({inputField : '#{field_id}', ifFormat : '%Y-%m-%d', button : '#{field_id}_trigger' });")
|
||||||
end
|
end
|
||||||
|
|
||||||
def include_calendar_headers_tags
|
|
||||||
unless @calendar_headers_tags_included
|
|
||||||
@calendar_headers_tags_included = true
|
|
||||||
content_for :header_tags do
|
|
||||||
javascript_include_tag('calendar/calendar') +
|
|
||||||
javascript_include_tag("calendar/lang/calendar-#{current_language}.js") +
|
|
||||||
javascript_include_tag('calendar/calendar-setup') +
|
|
||||||
stylesheet_link_tag('calendar')
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def wikitoolbar_for(field_id)
|
def wikitoolbar_for(field_id)
|
||||||
return '' unless Setting.text_formatting == 'textile'
|
return '' unless Setting.text_formatting == 'textile'
|
||||||
|
|
||||||
File renamed without changes.
File renamed without changes.
File renamed without changes.
+9
-2
@@ -17,6 +17,13 @@
|
|||||||
|
|
||||||
module CustomFieldsHelper
|
module CustomFieldsHelper
|
||||||
|
|
||||||
|
def custom_fields_tabs
|
||||||
|
tabs = [{:name => 'IssueCustomField', :label => :label_issue_plural},
|
||||||
|
{:name => 'ProjectCustomField', :label => :label_project_plural},
|
||||||
|
{:name => 'UserCustomField', :label => :label_user_plural}
|
||||||
|
]
|
||||||
|
end
|
||||||
|
|
||||||
# Return custom field html tag corresponding to its format
|
# Return custom field html tag corresponding to its format
|
||||||
def custom_field_tag(custom_value)
|
def custom_field_tag(custom_value)
|
||||||
custom_field = custom_value.custom_field
|
custom_field = custom_value.custom_field
|
||||||
@@ -28,7 +35,7 @@ module CustomFieldsHelper
|
|||||||
text_field('custom_value', 'value', :name => field_name, :id => field_id, :size => 10) +
|
text_field('custom_value', 'value', :name => field_name, :id => field_id, :size => 10) +
|
||||||
calendar_for(field_id)
|
calendar_for(field_id)
|
||||||
when "text"
|
when "text"
|
||||||
text_area 'custom_value', 'value', :name => field_name, :id => field_id, :cols => 60, :rows => 3
|
text_area 'custom_value', 'value', :name => field_name, :id => field_id, :rows => 3, :style => 'width:99%'
|
||||||
when "bool"
|
when "bool"
|
||||||
check_box 'custom_value', 'value', :name => field_name, :id => field_id
|
check_box 'custom_value', 'value', :name => field_name, :id => field_id
|
||||||
when "list"
|
when "list"
|
||||||
@@ -62,7 +69,7 @@ module CustomFieldsHelper
|
|||||||
return "" unless value && !value.empty?
|
return "" unless value && !value.empty?
|
||||||
case field_format
|
case field_format
|
||||||
when "date"
|
when "date"
|
||||||
begin; l_date(value.to_date); rescue; value end
|
begin; format_date(value.to_date); rescue; value end
|
||||||
when "bool"
|
when "bool"
|
||||||
l_YesNo(value == "1")
|
l_YesNo(value == "1")
|
||||||
else
|
else
|
||||||
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
@@ -54,15 +54,9 @@ module IssuesHelper
|
|||||||
when 'due_date', 'start_date'
|
when 'due_date', 'start_date'
|
||||||
value = format_date(detail.value.to_date) if detail.value
|
value = format_date(detail.value.to_date) if detail.value
|
||||||
old_value = format_date(detail.old_value.to_date) if detail.old_value
|
old_value = format_date(detail.old_value.to_date) if detail.old_value
|
||||||
when 'project_id'
|
|
||||||
p = Project.find_by_id(detail.value) and value = p.name if detail.value
|
|
||||||
p = Project.find_by_id(detail.old_value) and old_value = p.name if detail.old_value
|
|
||||||
when 'status_id'
|
when 'status_id'
|
||||||
s = IssueStatus.find_by_id(detail.value) and value = s.name if detail.value
|
s = IssueStatus.find_by_id(detail.value) and value = s.name if detail.value
|
||||||
s = IssueStatus.find_by_id(detail.old_value) and old_value = s.name if detail.old_value
|
s = IssueStatus.find_by_id(detail.old_value) and old_value = s.name if detail.old_value
|
||||||
when 'tracker_id'
|
|
||||||
t = Tracker.find_by_id(detail.value) and value = t.name if detail.value
|
|
||||||
t = Tracker.find_by_id(detail.old_value) and old_value = t.name if detail.old_value
|
|
||||||
when 'assigned_to_id'
|
when 'assigned_to_id'
|
||||||
u = User.find_by_id(detail.value) and value = u.name if detail.value
|
u = User.find_by_id(detail.value) and value = u.name if detail.value
|
||||||
u = User.find_by_id(detail.old_value) and old_value = u.name if detail.old_value
|
u = User.find_by_id(detail.old_value) and old_value = u.name if detail.old_value
|
||||||
@@ -86,7 +80,6 @@ module IssuesHelper
|
|||||||
when 'attachment'
|
when 'attachment'
|
||||||
label = l(:label_attachment)
|
label = l(:label_attachment)
|
||||||
end
|
end
|
||||||
call_hook(:helper_issues_show_detail_after_setting, {:detail => detail, :label => label, :value => value, :old_value => old_value })
|
|
||||||
|
|
||||||
label ||= detail.prop_key
|
label ||= detail.prop_key
|
||||||
value ||= detail.value
|
value ||= detail.value
|
||||||
@@ -96,9 +89,9 @@ module IssuesHelper
|
|||||||
label = content_tag('strong', label)
|
label = content_tag('strong', label)
|
||||||
old_value = content_tag("i", h(old_value)) if detail.old_value
|
old_value = content_tag("i", h(old_value)) if detail.old_value
|
||||||
old_value = content_tag("strike", old_value) if detail.old_value and (!detail.value or detail.value.empty?)
|
old_value = content_tag("strike", old_value) if detail.old_value and (!detail.value or detail.value.empty?)
|
||||||
if detail.property == 'attachment' && !value.blank? && a = Attachment.find_by_id(detail.prop_key)
|
if detail.property == 'attachment' && !value.blank? && Attachment.find_by_id(detail.prop_key)
|
||||||
# Link to the attachment if it has not been removed
|
# Link to the attachment if it has not been removed
|
||||||
value = link_to_attachment(a)
|
value = link_to(value, :controller => 'attachments', :action => 'download', :id => detail.prop_key)
|
||||||
else
|
else
|
||||||
value = content_tag("i", h(value)) if value
|
value = content_tag("i", h(value)) if value
|
||||||
end
|
end
|
||||||
@@ -127,7 +120,6 @@ module IssuesHelper
|
|||||||
|
|
||||||
def issues_to_csv(issues, project = nil)
|
def issues_to_csv(issues, project = nil)
|
||||||
ic = Iconv.new(l(:general_csv_encoding), 'UTF-8')
|
ic = Iconv.new(l(:general_csv_encoding), 'UTF-8')
|
||||||
decimal_separator = l(:general_csv_decimal_separator)
|
|
||||||
export = StringIO.new
|
export = StringIO.new
|
||||||
CSV::Writer.generate(export, l(:general_csv_separator)) do |csv|
|
CSV::Writer.generate(export, l(:general_csv_separator)) do |csv|
|
||||||
# csv header fields
|
# csv header fields
|
||||||
@@ -150,7 +142,7 @@ module IssuesHelper
|
|||||||
]
|
]
|
||||||
# Export project custom fields if project is given
|
# Export project custom fields if project is given
|
||||||
# otherwise export custom fields marked as "For all projects"
|
# otherwise export custom fields marked as "For all projects"
|
||||||
custom_fields = project.nil? ? IssueCustomField.for_all : project.all_issue_custom_fields
|
custom_fields = project.nil? ? IssueCustomField.for_all : project.all_custom_fields
|
||||||
custom_fields.each {|f| headers << f.name}
|
custom_fields.each {|f| headers << f.name}
|
||||||
# Description in the last column
|
# Description in the last column
|
||||||
headers << l(:field_description)
|
headers << l(:field_description)
|
||||||
@@ -170,7 +162,7 @@ module IssuesHelper
|
|||||||
format_date(issue.start_date),
|
format_date(issue.start_date),
|
||||||
format_date(issue.due_date),
|
format_date(issue.due_date),
|
||||||
issue.done_ratio,
|
issue.done_ratio,
|
||||||
issue.estimated_hours.to_s.gsub('.', decimal_separator),
|
issue.estimated_hours,
|
||||||
format_time(issue.created_on),
|
format_time(issue.created_on),
|
||||||
format_time(issue.updated_on)
|
format_time(issue.updated_on)
|
||||||
]
|
]
|
||||||
@@ -19,16 +19,13 @@ module JournalsHelper
|
|||||||
def render_notes(journal, options={})
|
def render_notes(journal, options={})
|
||||||
content = ''
|
content = ''
|
||||||
editable = journal.editable_by?(User.current)
|
editable = journal.editable_by?(User.current)
|
||||||
links = []
|
if editable && !journal.notes.blank?
|
||||||
if !journal.notes.blank?
|
links = []
|
||||||
links << link_to_in_place_notes_editor(image_tag('edit.png'), "journal-#{journal.id}-notes",
|
links << link_to_in_place_notes_editor(image_tag('edit.png'), "journal-#{journal.id}-notes",
|
||||||
{ :controller => 'journals', :action => 'edit', :id => journal },
|
{ :controller => 'journals', :action => 'edit', :id => journal },
|
||||||
:title => l(:button_edit)) if editable
|
:title => l(:button_edit))
|
||||||
links << link_to_remote(image_tag('comment.png'),
|
content << content_tag('div', links.join(' '), :class => 'contextual')
|
||||||
{ :url => {:controller => 'issues', :action => 'reply', :id => journal.journalized, :journal_id => journal} },
|
|
||||||
:title => l(:button_reply)) if options[:reply_links]
|
|
||||||
end
|
end
|
||||||
content << content_tag('div', links.join(' '), :class => 'contextual') unless links.empty?
|
|
||||||
content << textilizable(journal, :notes)
|
content << textilizable(journal, :notes)
|
||||||
content_tag('div', content, :id => "journal-#{journal.id}-notes", :class => (editable ? 'wiki editable' : 'wiki'))
|
content_tag('div', content, :id => "journal-#{journal.id}-notes", :class => (editable ? 'wiki editable' : 'wiki'))
|
||||||
end
|
end
|
||||||
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
@@ -21,16 +21,12 @@ module ProjectsHelper
|
|||||||
link_to h(version.name), { :controller => 'versions', :action => 'show', :id => version }, options
|
link_to h(version.name), { :controller => 'versions', :action => 'show', :id => version }, options
|
||||||
end
|
end
|
||||||
|
|
||||||
def format_activity_title(text)
|
|
||||||
h(truncate_single_line(text, 100))
|
|
||||||
end
|
|
||||||
|
|
||||||
def format_activity_day(date)
|
def format_activity_day(date)
|
||||||
date == Date.today ? l(:label_today).titleize : format_date(date)
|
date == Date.today ? l(:label_today).titleize : format_date(date)
|
||||||
end
|
end
|
||||||
|
|
||||||
def format_activity_description(text)
|
def format_activity_description(text)
|
||||||
h(truncate(text.to_s, 250).gsub(%r{<(pre|code)>.*$}m, '...'))
|
h(truncate(text, 250))
|
||||||
end
|
end
|
||||||
|
|
||||||
def project_settings_tabs
|
def project_settings_tabs
|
||||||
File renamed without changes.
File renamed without changes.
+8
@@ -25,6 +25,10 @@ module RepositoriesHelper
|
|||||||
type ? CodeRay.scan(content, type).html : h(content)
|
type ? CodeRay.scan(content, type).html : h(content)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def format_revision(txt)
|
||||||
|
txt.to_s[0,8]
|
||||||
|
end
|
||||||
|
|
||||||
def to_utf8(str)
|
def to_utf8(str)
|
||||||
return str if /\A[\r\n\t\x20-\x7e]*\Z/n.match(str) # for us-ascii
|
return str if /\A[\r\n\t\x20-\x7e]*\Z/n.match(str) # for us-ascii
|
||||||
@encodings ||= Setting.repositories_encodings.split(',').collect(&:strip)
|
@encodings ||= Setting.repositories_encodings.split(',').collect(&:strip)
|
||||||
@@ -76,6 +80,10 @@ module RepositoriesHelper
|
|||||||
content_tag('p', form.text_field(:url, :label => 'Root directory', :size => 60, :required => true, :disabled => (repository && !repository.root_url.blank?)))
|
content_tag('p', form.text_field(:url, :label => 'Root directory', :size => 60, :required => true, :disabled => (repository && !repository.root_url.blank?)))
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def git_field_tags(form, repository)
|
||||||
|
content_tag('p', form.text_field(:url, :label => 'Path to .git directory', :size => 60, :required => true, :disabled => (repository && !repository.root_url.blank?)))
|
||||||
|
end
|
||||||
|
|
||||||
def cvs_field_tags(form, repository)
|
def cvs_field_tags(form, repository)
|
||||||
content_tag('p', form.text_field(:root_url, :label => 'CVSROOT', :size => 60, :required => true, :disabled => !repository.new_record?)) +
|
content_tag('p', form.text_field(:root_url, :label => 'CVSROOT', :size => 60, :required => true, :disabled => !repository.new_record?)) +
|
||||||
content_tag('p', form.text_field(:url, :label => 'Module', :size => 30, :required => true, :disabled => !repository.new_record?))
|
content_tag('p', form.text_field(:url, :label => 'Module', :size => 30, :required => true, :disabled => !repository.new_record?))
|
||||||
File renamed without changes.
File renamed without changes.
@@ -19,7 +19,6 @@ module SettingsHelper
|
|||||||
def administration_settings_tabs
|
def administration_settings_tabs
|
||||||
tabs = [{:name => 'general', :partial => 'settings/general', :label => :label_general},
|
tabs = [{:name => 'general', :partial => 'settings/general', :label => :label_general},
|
||||||
{:name => 'authentication', :partial => 'settings/authentication', :label => :label_authentication},
|
{:name => 'authentication', :partial => 'settings/authentication', :label => :label_authentication},
|
||||||
{:name => 'projects', :partial => 'settings/projects', :label => :label_project_plural},
|
|
||||||
{:name => 'issues', :partial => 'settings/issues', :label => :label_issue_tracking},
|
{:name => 'issues', :partial => 'settings/issues', :label => :label_issue_tracking},
|
||||||
{:name => 'notifications', :partial => 'settings/notifications', :label => l(:field_mail_notification)},
|
{:name => 'notifications', :partial => 'settings/notifications', :label => l(:field_mail_notification)},
|
||||||
{:name => 'repositories', :partial => 'settings/repositories', :label => :label_repository_plural}
|
{:name => 'repositories', :partial => 'settings/repositories', :label => :label_repository_plural}
|
||||||
@@ -83,7 +83,7 @@ module SortHelper
|
|||||||
# Use this to sort the controller's table items collection.
|
# Use this to sort the controller's table items collection.
|
||||||
#
|
#
|
||||||
def sort_clause()
|
def sort_clause()
|
||||||
session[@sort_name][:key] + ' ' + (session[@sort_name][:order] || 'ASC')
|
session[@sort_name][:key] + ' ' + session[@sort_name][:order]
|
||||||
end
|
end
|
||||||
|
|
||||||
# Returns a link which sorts by the named column.
|
# Returns a link which sorts by the named column.
|
||||||
@@ -16,14 +16,6 @@
|
|||||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
|
||||||
module TimelogHelper
|
module TimelogHelper
|
||||||
def activity_collection_for_select_options
|
|
||||||
activities = Enumeration::get_values('ACTI')
|
|
||||||
collection = []
|
|
||||||
collection << [ "--- #{l(:actionview_instancetag_blank_option)} ---", '' ] unless activities.detect(&:is_default)
|
|
||||||
activities.each { |a| collection << [a.name, a.id] }
|
|
||||||
collection
|
|
||||||
end
|
|
||||||
|
|
||||||
def select_hours(data, criteria, value)
|
def select_hours(data, criteria, value)
|
||||||
data.select {|row| row[criteria] == value}
|
data.select {|row| row[criteria] == value}
|
||||||
end
|
end
|
||||||
@@ -52,8 +44,6 @@ module TimelogHelper
|
|||||||
|
|
||||||
def entries_to_csv(entries)
|
def entries_to_csv(entries)
|
||||||
ic = Iconv.new(l(:general_csv_encoding), 'UTF-8')
|
ic = Iconv.new(l(:general_csv_encoding), 'UTF-8')
|
||||||
decimal_separator = l(:general_csv_decimal_separator)
|
|
||||||
custom_fields = TimeEntryCustomField.find(:all)
|
|
||||||
export = StringIO.new
|
export = StringIO.new
|
||||||
CSV::Writer.generate(export, l(:general_csv_separator)) do |csv|
|
CSV::Writer.generate(export, l(:general_csv_separator)) do |csv|
|
||||||
# csv header fields
|
# csv header fields
|
||||||
@@ -67,9 +57,6 @@ module TimelogHelper
|
|||||||
l(:field_hours),
|
l(:field_hours),
|
||||||
l(:field_comments)
|
l(:field_comments)
|
||||||
]
|
]
|
||||||
# Export custom fields
|
|
||||||
headers += custom_fields.collect(&:name)
|
|
||||||
|
|
||||||
csv << headers.collect {|c| begin; ic.iconv(c.to_s); rescue; c.to_s; end }
|
csv << headers.collect {|c| begin; ic.iconv(c.to_s); rescue; c.to_s; end }
|
||||||
# csv lines
|
# csv lines
|
||||||
entries.each do |entry|
|
entries.each do |entry|
|
||||||
@@ -80,71 +67,13 @@ module TimelogHelper
|
|||||||
(entry.issue ? entry.issue.id : nil),
|
(entry.issue ? entry.issue.id : nil),
|
||||||
(entry.issue ? entry.issue.tracker : nil),
|
(entry.issue ? entry.issue.tracker : nil),
|
||||||
(entry.issue ? entry.issue.subject : nil),
|
(entry.issue ? entry.issue.subject : nil),
|
||||||
entry.hours.to_s.gsub('.', decimal_separator),
|
entry.hours,
|
||||||
entry.comments
|
entry.comments
|
||||||
]
|
]
|
||||||
fields += custom_fields.collect {|f| show_value(entry.custom_value_for(f)) }
|
|
||||||
|
|
||||||
csv << fields.collect {|c| begin; ic.iconv(c.to_s); rescue; c.to_s; end }
|
csv << fields.collect {|c| begin; ic.iconv(c.to_s); rescue; c.to_s; end }
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
export.rewind
|
export.rewind
|
||||||
export
|
export
|
||||||
end
|
end
|
||||||
|
|
||||||
def format_criteria_value(criteria, value)
|
|
||||||
value.blank? ? l(:label_none) : ((k = @available_criterias[criteria][:klass]) ? k.find_by_id(value.to_i) : format_value(value, @available_criterias[criteria][:format]))
|
|
||||||
end
|
|
||||||
|
|
||||||
def report_to_csv(criterias, periods, hours)
|
|
||||||
export = StringIO.new
|
|
||||||
CSV::Writer.generate(export, l(:general_csv_separator)) do |csv|
|
|
||||||
# Column headers
|
|
||||||
headers = criterias.collect {|criteria| l(@available_criterias[criteria][:label]) }
|
|
||||||
headers += periods
|
|
||||||
headers << l(:label_total)
|
|
||||||
csv << headers.collect {|c| to_utf8(c) }
|
|
||||||
# Content
|
|
||||||
report_criteria_to_csv(csv, criterias, periods, hours)
|
|
||||||
# Total row
|
|
||||||
row = [ l(:label_total) ] + [''] * (criterias.size - 1)
|
|
||||||
total = 0
|
|
||||||
periods.each do |period|
|
|
||||||
sum = sum_hours(select_hours(hours, @columns, period.to_s))
|
|
||||||
total += sum
|
|
||||||
row << (sum > 0 ? "%.2f" % sum : '')
|
|
||||||
end
|
|
||||||
row << "%.2f" %total
|
|
||||||
csv << row
|
|
||||||
end
|
|
||||||
export.rewind
|
|
||||||
export
|
|
||||||
end
|
|
||||||
|
|
||||||
def report_criteria_to_csv(csv, criterias, periods, hours, level=0)
|
|
||||||
hours.collect {|h| h[criterias[level]].to_s}.uniq.each do |value|
|
|
||||||
hours_for_value = select_hours(hours, criterias[level], value)
|
|
||||||
next if hours_for_value.empty?
|
|
||||||
row = [''] * level
|
|
||||||
row << to_utf8(format_criteria_value(criterias[level], value))
|
|
||||||
row += [''] * (criterias.length - level - 1)
|
|
||||||
total = 0
|
|
||||||
periods.each do |period|
|
|
||||||
sum = sum_hours(select_hours(hours_for_value, @columns, period.to_s))
|
|
||||||
total += sum
|
|
||||||
row << (sum > 0 ? "%.2f" % sum : '')
|
|
||||||
end
|
|
||||||
row << "%.2f" %total
|
|
||||||
csv << row
|
|
||||||
|
|
||||||
if criterias.length > level + 1
|
|
||||||
report_criteria_to_csv(csv, criterias, periods, hours_for_value, level + 1)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def to_utf8(s)
|
|
||||||
@ic ||= Iconv.new(l(:general_csv_encoding), 'UTF-8')
|
|
||||||
begin; @ic.iconv(s.to_s); rescue; s.to_s; end
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
File renamed without changes.
@@ -17,7 +17,7 @@
|
|||||||
|
|
||||||
module UsersHelper
|
module UsersHelper
|
||||||
def status_options_for_select(selected)
|
def status_options_for_select(selected)
|
||||||
options_for_select([[l(:label_all), "*"],
|
options_for_select([[l(:label_all), ''],
|
||||||
[l(:status_active), 1],
|
[l(:status_active), 1],
|
||||||
[l(:status_registered), 2],
|
[l(:status_registered), 2],
|
||||||
[l(:status_locked), 3]], selected)
|
[l(:status_locked), 3]], selected)
|
||||||
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
@@ -26,7 +26,6 @@ class Attachment < ActiveRecord::Base
|
|||||||
validates_length_of :disk_filename, :maximum => 255
|
validates_length_of :disk_filename, :maximum => 255
|
||||||
|
|
||||||
acts_as_event :title => :filename,
|
acts_as_event :title => :filename,
|
||||||
:description => :filename,
|
|
||||||
:url => Proc.new {|o| {:controller => 'attachments', :action => 'download', :id => o.id}}
|
:url => Proc.new {|o| {:controller => 'attachments', :action => 'download', :id => o.id}}
|
||||||
|
|
||||||
cattr_accessor :storage_path
|
cattr_accessor :storage_path
|
||||||
@@ -42,7 +41,7 @@ class Attachment < ActiveRecord::Base
|
|||||||
if @temp_file.size > 0
|
if @temp_file.size > 0
|
||||||
self.filename = sanitize_filename(@temp_file.original_filename)
|
self.filename = sanitize_filename(@temp_file.original_filename)
|
||||||
self.disk_filename = DateTime.now.strftime("%y%m%d%H%M%S") + "_" + self.filename
|
self.disk_filename = DateTime.now.strftime("%y%m%d%H%M%S") + "_" + self.filename
|
||||||
self.content_type = @temp_file.content_type.chomp
|
self.content_type = @temp_file.content_type.to_s.chomp
|
||||||
self.filesize = @temp_file.size
|
self.filesize = @temp_file.size
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
File renamed without changes.
@@ -20,10 +20,7 @@ require 'iconv'
|
|||||||
|
|
||||||
class AuthSourceLdap < AuthSource
|
class AuthSourceLdap < AuthSource
|
||||||
validates_presence_of :host, :port, :attr_login
|
validates_presence_of :host, :port, :attr_login
|
||||||
validates_length_of :name, :host, :account_password, :maximum => 60, :allow_nil => true
|
validates_presence_of :attr_firstname, :attr_lastname, :attr_mail, :if => Proc.new { |a| a.onthefly_register? }
|
||||||
validates_length_of :account, :base_dn, :maximum => 255, :allow_nil => true
|
|
||||||
validates_length_of :attr_login, :attr_firstname, :attr_lastname, :attr_mail, :maximum => 30, :allow_nil => true
|
|
||||||
validates_numericality_of :port, :only_integer => true
|
|
||||||
|
|
||||||
def after_initialize
|
def after_initialize
|
||||||
self.port = 389 if self.port == 0
|
self.port = 389 if self.port == 0
|
||||||
File renamed without changes.
File renamed without changes.
@@ -27,21 +27,14 @@ class Changeset < ActiveRecord::Base
|
|||||||
:url => Proc.new {|o| {:controller => 'repositories', :action => 'revision', :id => o.repository.project_id, :rev => o.revision}}
|
:url => Proc.new {|o| {:controller => 'repositories', :action => 'revision', :id => o.repository.project_id, :rev => o.revision}}
|
||||||
|
|
||||||
acts_as_searchable :columns => 'comments',
|
acts_as_searchable :columns => 'comments',
|
||||||
:include => {:repository => :project},
|
:include => :repository,
|
||||||
:project_key => "#{Repository.table_name}.project_id",
|
:project_key => "#{Repository.table_name}.project_id",
|
||||||
:date_column => 'committed_on'
|
:date_column => 'committed_on'
|
||||||
|
|
||||||
acts_as_activity_provider :timestamp => "#{table_name}.committed_on",
|
|
||||||
:find_options => {:include => {:repository => :project}}
|
|
||||||
|
|
||||||
validates_presence_of :repository_id, :revision, :committed_on, :commit_date
|
validates_presence_of :repository_id, :revision, :committed_on, :commit_date
|
||||||
validates_uniqueness_of :revision, :scope => :repository_id
|
validates_uniqueness_of :revision, :scope => :repository_id
|
||||||
validates_uniqueness_of :scmid, :scope => :repository_id, :allow_nil => true
|
validates_uniqueness_of :scmid, :scope => :repository_id, :allow_nil => true
|
||||||
|
|
||||||
def revision=(r)
|
|
||||||
write_attribute :revision, (r.nil? ? nil : r.to_s)
|
|
||||||
end
|
|
||||||
|
|
||||||
def comments=(comment)
|
def comments=(comment)
|
||||||
write_attribute(:comments, comment.strip)
|
write_attribute(:comments, comment.strip)
|
||||||
end
|
end
|
||||||
@@ -78,7 +71,7 @@ class Changeset < ActiveRecord::Base
|
|||||||
if ref_keywords.delete('*')
|
if ref_keywords.delete('*')
|
||||||
# find any issue ID in the comments
|
# find any issue ID in the comments
|
||||||
target_issue_ids = []
|
target_issue_ids = []
|
||||||
comments.scan(%r{([\s\(,-]|^)#(\d+)(?=[[:punct:]]|\s|<|$)}).each { |m| target_issue_ids << m[1] }
|
comments.scan(%r{([\s\(,-^])#(\d+)(?=[[:punct:]]|\s|<|$)}).each { |m| target_issue_ids << m[1] }
|
||||||
referenced_issues += repository.project.issues.find_all_by_id(target_issue_ids)
|
referenced_issues += repository.project.issues.find_all_by_id(target_issue_ids)
|
||||||
end
|
end
|
||||||
|
|
||||||
File renamed without changes.
@@ -30,7 +30,7 @@ class CustomField < ActiveRecord::Base
|
|||||||
}.freeze
|
}.freeze
|
||||||
|
|
||||||
validates_presence_of :name, :field_format
|
validates_presence_of :name, :field_format
|
||||||
validates_uniqueness_of :name, :scope => :type
|
validates_uniqueness_of :name
|
||||||
validates_length_of :name, :maximum => 30
|
validates_length_of :name, :maximum => 30
|
||||||
validates_format_of :name, :with => /^[\w\s\'\-]*$/i
|
validates_format_of :name, :with => /^[\w\s\'\-]*$/i
|
||||||
validates_inclusion_of :field_format, :in => FIELD_FORMATS.keys
|
validates_inclusion_of :field_format, :in => FIELD_FORMATS.keys
|
||||||
@@ -66,7 +66,7 @@ class CustomField < ActiveRecord::Base
|
|||||||
|
|
||||||
# to move in project_custom_field
|
# to move in project_custom_field
|
||||||
def self.for_all
|
def self.for_all
|
||||||
find(:all, :conditions => ["is_for_all=?", true], :order => 'position')
|
find(:all, :conditions => ["is_for_all=?", true])
|
||||||
end
|
end
|
||||||
|
|
||||||
def type_name
|
def type_name
|
||||||
@@ -25,11 +25,6 @@ class CustomValue < ActiveRecord::Base
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
# Returns true if the boolean custom value is true
|
|
||||||
def true?
|
|
||||||
self.value == '1'
|
|
||||||
end
|
|
||||||
|
|
||||||
protected
|
protected
|
||||||
def validate
|
def validate
|
||||||
if value.blank?
|
if value.blank?
|
||||||
File renamed without changes.
File renamed without changes.
File renamed without changes.
@@ -27,7 +27,7 @@ class Issue < ActiveRecord::Base
|
|||||||
|
|
||||||
has_many :journals, :as => :journalized, :dependent => :destroy
|
has_many :journals, :as => :journalized, :dependent => :destroy
|
||||||
has_many :attachments, :as => :container, :dependent => :destroy
|
has_many :attachments, :as => :container, :dependent => :destroy
|
||||||
has_many :time_entries, :dependent => :nullify
|
has_many :time_entries, :dependent => :delete_all
|
||||||
has_many :custom_values, :dependent => :delete_all, :as => :customized
|
has_many :custom_values, :dependent => :delete_all, :as => :customized
|
||||||
has_many :custom_fields, :through => :custom_values
|
has_many :custom_fields, :through => :custom_values
|
||||||
has_and_belongs_to_many :changesets, :order => "revision ASC"
|
has_and_belongs_to_many :changesets, :order => "revision ASC"
|
||||||
@@ -66,8 +66,10 @@ class Issue < ActiveRecord::Base
|
|||||||
transaction do
|
transaction do
|
||||||
if new_project && project_id != new_project.id
|
if new_project && project_id != new_project.id
|
||||||
# delete issue relations
|
# delete issue relations
|
||||||
self.relations_from.clear
|
unless Setting.cross_project_issue_relations?
|
||||||
self.relations_to.clear
|
self.relations_from.clear
|
||||||
|
self.relations_to.clear
|
||||||
|
end
|
||||||
# issue is moved to another project
|
# issue is moved to another project
|
||||||
self.category = nil
|
self.category = nil
|
||||||
self.fixed_version = nil
|
self.fixed_version = nil
|
||||||
@@ -142,6 +144,9 @@ class Issue < ActiveRecord::Base
|
|||||||
end
|
end
|
||||||
|
|
||||||
def after_save
|
def after_save
|
||||||
|
# Reload is needed in order to get the right status
|
||||||
|
reload
|
||||||
|
|
||||||
# Update start/due dates of following issues
|
# Update start/due dates of following issues
|
||||||
relations_from.each(&:set_issue_to_dates)
|
relations_from.each(&:set_issue_to_dates)
|
||||||
|
|
||||||
@@ -165,6 +170,7 @@ class Issue < ActiveRecord::Base
|
|||||||
def init_journal(user, notes = "")
|
def init_journal(user, notes = "")
|
||||||
@current_journal ||= Journal.new(:journalized => self, :user => user, :notes => notes)
|
@current_journal ||= Journal.new(:journalized => self, :user => user, :notes => notes)
|
||||||
@issue_before_change = self.clone
|
@issue_before_change = self.clone
|
||||||
|
@issue_before_change.status = self.status
|
||||||
@custom_values_before_change = {}
|
@custom_values_before_change = {}
|
||||||
self.custom_values.each {|c| @custom_values_before_change.store c.custom_field_id, c.value }
|
self.custom_values.each {|c| @custom_values_before_change.store c.custom_field_id, c.value }
|
||||||
@current_journal
|
@current_journal
|
||||||
@@ -190,9 +196,9 @@ class Issue < ActiveRecord::Base
|
|||||||
# Returns the mail adresses of users that should be notified for the issue
|
# Returns the mail adresses of users that should be notified for the issue
|
||||||
def recipients
|
def recipients
|
||||||
recipients = project.recipients
|
recipients = project.recipients
|
||||||
# Author and assignee are always notified
|
# Author and assignee are always notified unless they have been locked
|
||||||
recipients << author.mail if author
|
recipients << author.mail if author && author.active?
|
||||||
recipients << assigned_to.mail if assigned_to
|
recipients << assigned_to.mail if assigned_to && assigned_to.active?
|
||||||
recipients.compact.uniq
|
recipients.compact.uniq
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -225,4 +231,10 @@ class Issue < ActiveRecord::Base
|
|||||||
def soonest_start
|
def soonest_start
|
||||||
@soonest_start ||= relations_to.collect{|relation| relation.successor_soonest_start}.compact.min
|
@soonest_start ||= relations_to.collect{|relation| relation.successor_soonest_start}.compact.min
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def self.visible_by(usr)
|
||||||
|
with_scope(:find => { :conditions => Project.visible_by(usr) }) do
|
||||||
|
yield
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
@@ -23,6 +23,7 @@ class Journal < ActiveRecord::Base
|
|||||||
|
|
||||||
belongs_to :user
|
belongs_to :user
|
||||||
has_many :details, :class_name => "JournalDetail", :dependent => :delete_all
|
has_many :details, :class_name => "JournalDetail", :dependent => :delete_all
|
||||||
|
attr_accessor :indice
|
||||||
|
|
||||||
acts_as_searchable :columns => 'notes',
|
acts_as_searchable :columns => 'notes',
|
||||||
:include => :issue,
|
:include => :issue,
|
||||||
@@ -32,7 +33,7 @@ class Journal < ActiveRecord::Base
|
|||||||
acts_as_event :title => Proc.new {|o| "#{o.issue.tracker.name} ##{o.issue.id}: #{o.issue.subject}" + ((s = o.new_status) ? " (#{s})" : '') },
|
acts_as_event :title => Proc.new {|o| "#{o.issue.tracker.name} ##{o.issue.id}: #{o.issue.subject}" + ((s = o.new_status) ? " (#{s})" : '') },
|
||||||
:description => :notes,
|
:description => :notes,
|
||||||
:author => :user,
|
:author => :user,
|
||||||
:url => Proc.new {|o| {:controller => 'issues', :action => 'show', :id => o.issue.id}}
|
:url => Proc.new {|o| {:controller => 'issues', :action => 'show', :id => o.issue.id, :anchor => "change-#{o.id}"}}
|
||||||
|
|
||||||
def save
|
def save
|
||||||
# Do not save an empty journal
|
# Do not save an empty journal
|
||||||
@@ -44,4 +45,21 @@ class Journal < ActiveRecord::Base
|
|||||||
c = details.detect {|detail| detail.prop_key == 'status_id'}
|
c = details.detect {|detail| detail.prop_key == 'status_id'}
|
||||||
(c && c.value) ? IssueStatus.find_by_id(c.value.to_i) : nil
|
(c && c.value) ? IssueStatus.find_by_id(c.value.to_i) : nil
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def new_value_for(prop)
|
||||||
|
c = details.detect {|detail| detail.prop_key == prop}
|
||||||
|
c ? c.value : nil
|
||||||
|
end
|
||||||
|
|
||||||
|
def editable_by?(usr)
|
||||||
|
usr && usr.logged? && (usr.allowed_to?(:edit_issue_notes, project) || (self.user == usr && usr.allowed_to?(:edit_own_issue_notes, project)))
|
||||||
|
end
|
||||||
|
|
||||||
|
def project
|
||||||
|
journalized.respond_to?(:project) ? journalized.project : nil
|
||||||
|
end
|
||||||
|
|
||||||
|
def attachments
|
||||||
|
journalized.respond_to?(:attachments) ? journalized.attachments : nil
|
||||||
|
end
|
||||||
end
|
end
|
||||||
File renamed without changes.
File renamed without changes.
@@ -51,15 +51,6 @@ class Mailer < ActionMailer::Base
|
|||||||
:issue_url => url_for(:controller => 'issues', :action => 'show', :id => issue)
|
:issue_url => url_for(:controller => 'issues', :action => 'show', :id => issue)
|
||||||
end
|
end
|
||||||
|
|
||||||
def reminder(user, issues, days)
|
|
||||||
set_language_if_valid user.language
|
|
||||||
recipients user.mail
|
|
||||||
subject l(:mail_subject_reminder, issues.size)
|
|
||||||
body :issues => issues,
|
|
||||||
:days => days,
|
|
||||||
:issues_url => url_for(:controller => 'issues', :action => 'index', :set_filter => 1, :assigned_to_id => user.id, :sort_key => 'issues.due_date', :sort_order => 'asc')
|
|
||||||
end
|
|
||||||
|
|
||||||
def document_added(document)
|
def document_added(document)
|
||||||
redmine_headers 'Project' => document.project.identifier
|
redmine_headers 'Project' => document.project.identifier
|
||||||
recipients document.project.recipients
|
recipients document.project.recipients
|
||||||
@@ -154,30 +145,6 @@ class Mailer < ActionMailer::Base
|
|||||||
super
|
super
|
||||||
end
|
end
|
||||||
|
|
||||||
# Sends reminders to issue assignees
|
|
||||||
# Available options:
|
|
||||||
# * :days => how many days in the future to remind about (defaults to 7)
|
|
||||||
# * :tracker => id of tracker for filtering issues (defaults to all trackers)
|
|
||||||
# * :project => id or identifier of project to process (defaults to all projects)
|
|
||||||
def self.reminders(options={})
|
|
||||||
days = options[:days] || 7
|
|
||||||
project = options[:project] ? Project.find(options[:project]) : nil
|
|
||||||
tracker = options[:tracker] ? Tracker.find(options[:tracker]) : nil
|
|
||||||
|
|
||||||
s = ARCondition.new ["#{IssueStatus.table_name}.is_closed = ? AND #{Issue.table_name}.due_date <= ?", false, days.day.from_now.to_date]
|
|
||||||
s << "#{Issue.table_name}.assigned_to_id IS NOT NULL"
|
|
||||||
s << "#{Project.table_name}.status = #{Project::STATUS_ACTIVE}"
|
|
||||||
s << "#{Issue.table_name}.project_id = #{project.id}" if project
|
|
||||||
s << "#{Issue.table_name}.tracker_id = #{tracker.id}" if tracker
|
|
||||||
|
|
||||||
issues_by_assignee = Issue.find(:all, :include => [:status, :assigned_to, :project, :tracker],
|
|
||||||
:conditions => s.conditions
|
|
||||||
).group_by(&:assigned_to)
|
|
||||||
issues_by_assignee.each do |assignee, issues|
|
|
||||||
deliver_reminder(assignee, issues, days) unless assignee.nil?
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
private
|
private
|
||||||
def initialize_defaults(method_name)
|
def initialize_defaults(method_name)
|
||||||
super
|
super
|
||||||
File renamed without changes.
@@ -36,7 +36,7 @@ class Message < ActiveRecord::Base
|
|||||||
|
|
||||||
def validate_on_create
|
def validate_on_create
|
||||||
# Can not reply to a locked topic
|
# Can not reply to a locked topic
|
||||||
errors.add_to_base 'Topic is locked' if root.locked?
|
errors.add_to_base 'Topic is locked' if root.locked? && self != root
|
||||||
end
|
end
|
||||||
|
|
||||||
def after_create
|
def after_create
|
||||||
@@ -18,7 +18,7 @@
|
|||||||
class MessageObserver < ActiveRecord::Observer
|
class MessageObserver < ActiveRecord::Observer
|
||||||
def after_create(message)
|
def after_create(message)
|
||||||
# send notification to the authors of the thread
|
# send notification to the authors of the thread
|
||||||
recipients = ([message.root] + message.root.children).collect {|m| m.author.mail if m.author}
|
recipients = ([message.root] + message.root.children).collect {|m| m.author.mail if m.author && m.author.active?}
|
||||||
# send notification to the board watchers
|
# send notification to the board watchers
|
||||||
recipients += message.board.watcher_recipients
|
recipients += message.board.watcher_recipients
|
||||||
recipients = recipients.compact.uniq
|
recipients = recipients.compact.uniq
|
||||||
File renamed without changes.
@@ -22,6 +22,7 @@ class Project < ActiveRecord::Base
|
|||||||
|
|
||||||
has_many :members, :include => :user, :conditions => "#{User.table_name}.status=#{User::STATUS_ACTIVE}"
|
has_many :members, :include => :user, :conditions => "#{User.table_name}.status=#{User::STATUS_ACTIVE}"
|
||||||
has_many :users, :through => :members
|
has_many :users, :through => :members
|
||||||
|
has_many :custom_values, :dependent => :delete_all, :as => :customized
|
||||||
has_many :enabled_modules, :dependent => :delete_all
|
has_many :enabled_modules, :dependent => :delete_all
|
||||||
has_and_belongs_to_many :trackers, :order => "#{Tracker.table_name}.position"
|
has_and_belongs_to_many :trackers, :order => "#{Tracker.table_name}.position"
|
||||||
has_many :issues, :dependent => :destroy, :order => "#{Issue.table_name}.created_on DESC", :include => [:status, :tracker]
|
has_many :issues, :dependent => :destroy, :order => "#{Issue.table_name}.created_on DESC", :include => [:status, :tracker]
|
||||||
@@ -32,12 +33,12 @@ class Project < ActiveRecord::Base
|
|||||||
has_many :documents, :dependent => :destroy
|
has_many :documents, :dependent => :destroy
|
||||||
has_many :news, :dependent => :delete_all, :include => :author
|
has_many :news, :dependent => :delete_all, :include => :author
|
||||||
has_many :issue_categories, :dependent => :delete_all, :order => "#{IssueCategory.table_name}.name"
|
has_many :issue_categories, :dependent => :delete_all, :order => "#{IssueCategory.table_name}.name"
|
||||||
has_many :boards, :dependent => :destroy, :order => "position ASC"
|
has_many :boards, :order => "position ASC"
|
||||||
has_one :repository, :dependent => :destroy
|
has_one :repository, :dependent => :destroy
|
||||||
has_many :changesets, :through => :repository
|
has_many :changesets, :through => :repository
|
||||||
has_one :wiki, :dependent => :destroy
|
has_one :wiki, :dependent => :destroy
|
||||||
# Custom field for the project issues
|
# Custom field for the project issues
|
||||||
has_and_belongs_to_many :issue_custom_fields,
|
has_and_belongs_to_many :custom_fields,
|
||||||
:class_name => 'IssueCustomField',
|
:class_name => 'IssueCustomField',
|
||||||
:order => "#{CustomField.table_name}.position",
|
:order => "#{CustomField.table_name}.position",
|
||||||
:join_table => "#{table_name_prefix}custom_fields_projects#{table_name_suffix}",
|
:join_table => "#{table_name_prefix}custom_fields_projects#{table_name_suffix}",
|
||||||
@@ -45,19 +46,18 @@ class Project < ActiveRecord::Base
|
|||||||
|
|
||||||
acts_as_tree :order => "name", :counter_cache => true
|
acts_as_tree :order => "name", :counter_cache => true
|
||||||
|
|
||||||
acts_as_customizable
|
acts_as_searchable :columns => ['name', 'description'], :project_key => 'id'
|
||||||
acts_as_searchable :columns => ['name', 'description'], :project_key => 'id', :permission => nil
|
|
||||||
acts_as_event :title => Proc.new {|o| "#{l(:label_project)}: #{o.name}"},
|
acts_as_event :title => Proc.new {|o| "#{l(:label_project)}: #{o.name}"},
|
||||||
:url => Proc.new {|o| {:controller => 'projects', :action => 'show', :id => o.id}},
|
:url => Proc.new {|o| {:controller => 'projects', :action => 'show', :id => o.id}}
|
||||||
:author => nil
|
|
||||||
|
|
||||||
attr_protected :status, :enabled_module_names
|
attr_protected :status, :enabled_module_names
|
||||||
|
|
||||||
validates_presence_of :name, :identifier
|
validates_presence_of :name, :identifier
|
||||||
validates_uniqueness_of :name, :identifier
|
validates_uniqueness_of :name, :identifier
|
||||||
|
validates_associated :custom_values, :on => :update
|
||||||
validates_associated :repository, :wiki
|
validates_associated :repository, :wiki
|
||||||
validates_length_of :name, :maximum => 30
|
validates_length_of :name, :maximum => 30
|
||||||
validates_length_of :homepage, :maximum => 255
|
validates_length_of :homepage, :maximum => 60
|
||||||
validates_length_of :identifier, :in => 3..20
|
validates_length_of :identifier, :in => 3..20
|
||||||
validates_format_of :identifier, :with => /^[a-z0-9\-]*$/
|
validates_format_of :identifier, :with => /^[a-z0-9\-]*$/
|
||||||
|
|
||||||
@@ -73,16 +73,14 @@ class Project < ActiveRecord::Base
|
|||||||
|
|
||||||
def issues_with_subprojects(include_subprojects=false)
|
def issues_with_subprojects(include_subprojects=false)
|
||||||
conditions = nil
|
conditions = nil
|
||||||
if include_subprojects
|
if include_subprojects && !active_children.empty?
|
||||||
ids = [id] + child_ids
|
ids = [id] + active_children.collect {|c| c.id}
|
||||||
conditions = ["#{Project.table_name}.id IN (#{ids.join(',')}) AND #{Project.visible_by}"]
|
conditions = ["#{Issue.table_name}.project_id IN (#{ids.join(',')})"]
|
||||||
end
|
end
|
||||||
conditions ||= ["#{Project.table_name}.id = ?", id]
|
conditions ||= ["#{Issue.table_name}.project_id = ?", id]
|
||||||
# Quick and dirty fix for Rails 2 compatibility
|
# Quick and dirty fix for Rails 2 compatibility
|
||||||
Issue.send(:with_scope, :find => { :conditions => conditions }) do
|
Issue.send(:with_scope, :find => { :conditions => conditions }) do
|
||||||
Version.send(:with_scope, :find => { :conditions => conditions }) do
|
yield
|
||||||
yield
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -93,7 +91,6 @@ class Project < ActiveRecord::Base
|
|||||||
end
|
end
|
||||||
|
|
||||||
def self.visible_by(user=nil)
|
def self.visible_by(user=nil)
|
||||||
user ||= User.current
|
|
||||||
if user && user.admin?
|
if user && user.admin?
|
||||||
return "#{Project.table_name}.status=#{Project::STATUS_ACTIVE}"
|
return "#{Project.table_name}.status=#{Project::STATUS_ACTIVE}"
|
||||||
elsif user && user.memberships.any?
|
elsif user && user.memberships.any?
|
||||||
@@ -113,18 +110,16 @@ class Project < ActiveRecord::Base
|
|||||||
end
|
end
|
||||||
if user.admin?
|
if user.admin?
|
||||||
# no restriction
|
# no restriction
|
||||||
|
elsif user.logged?
|
||||||
|
statements << "#{Project.table_name}.is_public = #{connection.quoted_true}" if Role.non_member.allowed_to?(permission)
|
||||||
|
allowed_project_ids = user.memberships.select {|m| m.role.allowed_to?(permission)}.collect {|m| m.project_id}
|
||||||
|
statements << "#{Project.table_name}.id IN (#{allowed_project_ids.join(',')})" if allowed_project_ids.any?
|
||||||
|
elsif Role.anonymous.allowed_to?(permission)
|
||||||
|
# anonymous user allowed on public project
|
||||||
|
statements << "#{Project.table_name}.is_public = #{connection.quoted_true}"
|
||||||
else
|
else
|
||||||
|
# anonymous user is not authorized
|
||||||
statements << "1=0"
|
statements << "1=0"
|
||||||
if user.logged?
|
|
||||||
statements << "#{Project.table_name}.is_public = #{connection.quoted_true}" if Role.non_member.allowed_to?(permission)
|
|
||||||
allowed_project_ids = user.memberships.select {|m| m.role.allowed_to?(permission)}.collect {|m| m.project_id}
|
|
||||||
statements << "#{Project.table_name}.id IN (#{allowed_project_ids.join(',')})" if allowed_project_ids.any?
|
|
||||||
elsif Role.anonymous.allowed_to?(permission)
|
|
||||||
# anonymous user allowed on public project
|
|
||||||
statements << "#{Project.table_name}.is_public = #{connection.quoted_true}"
|
|
||||||
else
|
|
||||||
# anonymous user is not authorized
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
statements.empty? ? base_statement : "((#{base_statement}) AND (#{statements.join(' OR ')}))"
|
statements.empty? ? base_statement : "((#{base_statement}) AND (#{statements.join(' OR ')}))"
|
||||||
end
|
end
|
||||||
@@ -146,8 +141,7 @@ class Project < ActiveRecord::Base
|
|||||||
end
|
end
|
||||||
|
|
||||||
def to_param
|
def to_param
|
||||||
# id is used for projects with a numeric identifier (compatibility)
|
identifier
|
||||||
@to_param ||= (identifier.to_s =~ %r{^\d*$} ? id : identifier)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def active?
|
def active?
|
||||||
@@ -197,12 +191,12 @@ class Project < ActiveRecord::Base
|
|||||||
|
|
||||||
# Returns an array of all custom fields enabled for project issues
|
# Returns an array of all custom fields enabled for project issues
|
||||||
# (explictly associated custom fields and custom fields enabled for all projects)
|
# (explictly associated custom fields and custom fields enabled for all projects)
|
||||||
def all_issue_custom_fields
|
def custom_fields_for_issues(tracker)
|
||||||
@all_issue_custom_fields ||= (IssueCustomField.for_all + issue_custom_fields).uniq.sort
|
all_custom_fields.select {|c| tracker.custom_fields.include? c }
|
||||||
end
|
end
|
||||||
|
|
||||||
def project
|
def all_custom_fields
|
||||||
self
|
@all_custom_fields ||= (IssueCustomField.for_all + custom_fields).uniq
|
||||||
end
|
end
|
||||||
|
|
||||||
def <=>(project)
|
def <=>(project)
|
||||||
File renamed without changes.
@@ -88,7 +88,7 @@ class Query < ActiveRecord::Base
|
|||||||
:date_past => [ ">t-", "<t-", "t-", "t", "w" ],
|
:date_past => [ ">t-", "<t-", "t-", "t", "w" ],
|
||||||
:string => [ "=", "~", "!", "!~" ],
|
:string => [ "=", "~", "!", "!~" ],
|
||||||
:text => [ "~", "!~" ],
|
:text => [ "~", "!~" ],
|
||||||
:integer => [ "=", ">=", "<=", "!*", "*" ] }
|
:integer => [ "=", ">=", "<=" ] }
|
||||||
|
|
||||||
cattr_reader :operators_by_filter_type
|
cattr_reader :operators_by_filter_type
|
||||||
|
|
||||||
@@ -125,7 +125,7 @@ class Query < ActiveRecord::Base
|
|||||||
filters.each_key do |field|
|
filters.each_key do |field|
|
||||||
errors.add label_for(field), :activerecord_error_blank unless
|
errors.add label_for(field), :activerecord_error_blank unless
|
||||||
# filter requires one or more values
|
# filter requires one or more values
|
||||||
(values_for(field) and !values_for(field).first.blank?) or
|
(values_for(field) and !values_for(field).first.empty?) or
|
||||||
# filter doesn't require any value
|
# filter doesn't require any value
|
||||||
["o", "c", "!*", "*", "t", "w"].include? operator_for(field)
|
["o", "c", "!*", "*", "t", "w"].include? operator_for(field)
|
||||||
end if filters
|
end if filters
|
||||||
@@ -152,8 +152,7 @@ class Query < ActiveRecord::Base
|
|||||||
"updated_on" => { :type => :date_past, :order => 10 },
|
"updated_on" => { :type => :date_past, :order => 10 },
|
||||||
"start_date" => { :type => :date, :order => 11 },
|
"start_date" => { :type => :date, :order => 11 },
|
||||||
"due_date" => { :type => :date, :order => 12 },
|
"due_date" => { :type => :date, :order => 12 },
|
||||||
"estimated_hours" => { :type => :integer, :order => 13 },
|
"done_ratio" => { :type => :integer, :order => 13 }}
|
||||||
"done_ratio" => { :type => :integer, :order => 14 }}
|
|
||||||
|
|
||||||
user_values = []
|
user_values = []
|
||||||
user_values << ["<< #{l(:label_me)} >>", "me"] if User.current.logged?
|
user_values << ["<< #{l(:label_me)} >>", "me"] if User.current.logged?
|
||||||
@@ -168,19 +167,28 @@ class Query < ActiveRecord::Base
|
|||||||
|
|
||||||
if project
|
if project
|
||||||
# project specific filters
|
# project specific filters
|
||||||
unless @project.issue_categories.empty?
|
@available_filters["category_id"] = { :type => :list_optional, :order => 6, :values => @project.issue_categories.collect{|s| [s.name, s.id.to_s] } }
|
||||||
@available_filters["category_id"] = { :type => :list_optional, :order => 6, :values => @project.issue_categories.collect{|s| [s.name, s.id.to_s] } }
|
@available_filters["fixed_version_id"] = { :type => :list_optional, :order => 7, :values => @project.versions.sort.collect{|s| [s.name, s.id.to_s] } }
|
||||||
end
|
|
||||||
unless @project.versions.empty?
|
|
||||||
@available_filters["fixed_version_id"] = { :type => :list_optional, :order => 7, :values => @project.versions.sort.collect{|s| [s.name, s.id.to_s] } }
|
|
||||||
end
|
|
||||||
unless @project.active_children.empty?
|
unless @project.active_children.empty?
|
||||||
@available_filters["subproject_id"] = { :type => :list_subprojects, :order => 13, :values => @project.active_children.collect{|s| [s.name, s.id.to_s] } }
|
@available_filters["subproject_id"] = { :type => :list_subprojects, :order => 13, :values => @project.active_children.collect{|s| [s.name, s.id.to_s] } }
|
||||||
end
|
end
|
||||||
add_custom_fields_filters(@project.all_issue_custom_fields)
|
@project.all_custom_fields.select(&:is_filter?).each do |field|
|
||||||
else
|
case field.field_format
|
||||||
# global filters for cross project issue list
|
when "text"
|
||||||
add_custom_fields_filters(IssueCustomField.find(:all, :conditions => {:is_filter => true, :is_for_all => true}))
|
options = { :type => :text, :order => 20 }
|
||||||
|
when "list"
|
||||||
|
options = { :type => :list_optional, :values => field.possible_values, :order => 20}
|
||||||
|
when "date"
|
||||||
|
options = { :type => :date, :order => 20 }
|
||||||
|
when "bool"
|
||||||
|
options = { :type => :list, :values => [[l(:general_text_yes), "1"], [l(:general_text_no), "0"]], :order => 20 }
|
||||||
|
else
|
||||||
|
options = { :type => :string, :order => 20 }
|
||||||
|
end
|
||||||
|
@available_filters["cf_#{field.id}"] = options.merge({ :name => field.name })
|
||||||
|
end
|
||||||
|
# remove category filter if no category defined
|
||||||
|
@available_filters.delete "category_id" if @available_filters["category_id"][:values].empty?
|
||||||
end
|
end
|
||||||
@available_filters
|
@available_filters
|
||||||
end
|
end
|
||||||
@@ -219,7 +227,7 @@ class Query < ActiveRecord::Base
|
|||||||
end
|
end
|
||||||
|
|
||||||
def label_for(field)
|
def label_for(field)
|
||||||
label = available_filters[field][:name] if available_filters.has_key?(field)
|
label = @available_filters[field][:name] if @available_filters.has_key?(field)
|
||||||
label ||= field.gsub(/\_id$/, "")
|
label ||= field.gsub(/\_id$/, "")
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -227,7 +235,7 @@ class Query < ActiveRecord::Base
|
|||||||
return @available_columns if @available_columns
|
return @available_columns if @available_columns
|
||||||
@available_columns = Query.available_columns
|
@available_columns = Query.available_columns
|
||||||
@available_columns += (project ?
|
@available_columns += (project ?
|
||||||
project.all_issue_custom_fields :
|
project.all_custom_fields :
|
||||||
IssueCustomField.find(:all, :conditions => {:is_for_all => true})
|
IssueCustomField.find(:all, :conditions => {:is_for_all => true})
|
||||||
).collect {|cf| QueryCustomFieldColumn.new(cf) }
|
).collect {|cf| QueryCustomFieldColumn.new(cf) }
|
||||||
end
|
end
|
||||||
@@ -257,7 +265,7 @@ class Query < ActiveRecord::Base
|
|||||||
|
|
||||||
def statement
|
def statement
|
||||||
# project/subprojects clause
|
# project/subprojects clause
|
||||||
project_clauses = []
|
clause = ''
|
||||||
if project && !@project.active_children.empty?
|
if project && !@project.active_children.empty?
|
||||||
ids = [project.id]
|
ids = [project.id]
|
||||||
if has_filter?("subproject_id")
|
if has_filter?("subproject_id")
|
||||||
@@ -269,16 +277,17 @@ class Query < ActiveRecord::Base
|
|||||||
# main project only
|
# main project only
|
||||||
else
|
else
|
||||||
# all subprojects
|
# all subprojects
|
||||||
ids += project.child_ids
|
ids += project.active_children.collect{|p| p.id}
|
||||||
end
|
end
|
||||||
elsif Setting.display_subprojects_issues?
|
elsif Setting.display_subprojects_issues?
|
||||||
ids += project.child_ids
|
ids += project.active_children.collect{|p| p.id}
|
||||||
end
|
end
|
||||||
project_clauses << "#{Issue.table_name}.project_id IN (%s)" % ids.join(',')
|
clause << "#{Issue.table_name}.project_id IN (%s)" % ids.join(',')
|
||||||
elsif project
|
elsif project
|
||||||
project_clauses << "#{Issue.table_name}.project_id = %d" % project.id
|
clause << "#{Issue.table_name}.project_id = %d" % project.id
|
||||||
|
else
|
||||||
|
clause << Project.visible_by(User.current)
|
||||||
end
|
end
|
||||||
project_clauses << Project.visible_by(User.current)
|
|
||||||
|
|
||||||
# filters clauses
|
# filters clauses
|
||||||
filters_clauses = []
|
filters_clauses = []
|
||||||
@@ -288,13 +297,11 @@ class Query < ActiveRecord::Base
|
|||||||
next unless v and !v.empty?
|
next unless v and !v.empty?
|
||||||
|
|
||||||
sql = ''
|
sql = ''
|
||||||
is_custom_filter = false
|
|
||||||
if field =~ /^cf_(\d+)$/
|
if field =~ /^cf_(\d+)$/
|
||||||
# custom field
|
# custom field
|
||||||
db_table = CustomValue.table_name
|
db_table = CustomValue.table_name
|
||||||
db_field = 'value'
|
db_field = 'value'
|
||||||
is_custom_filter = true
|
sql << "#{Issue.table_name}.id IN (SELECT #{db_table}.customized_id FROM #{db_table} where #{db_table}.customized_type='Issue' AND #{db_table}.customized_id=#{Issue.table_name}.id AND #{db_table}.custom_field_id=#{$1} AND "
|
||||||
sql << "#{Issue.table_name}.id IN (SELECT #{Issue.table_name}.id FROM #{Issue.table_name} LEFT OUTER JOIN #{db_table} ON #{db_table}.customized_type='Issue' AND #{db_table}.customized_id=#{Issue.table_name}.id AND #{db_table}.custom_field_id=#{$1} WHERE "
|
|
||||||
else
|
else
|
||||||
# regular field
|
# regular field
|
||||||
db_table = Issue.table_name
|
db_table = Issue.table_name
|
||||||
@@ -314,10 +321,8 @@ class Query < ActiveRecord::Base
|
|||||||
sql = sql + "(#{db_table}.#{db_field} IS NULL OR #{db_table}.#{db_field} NOT IN (" + v.collect{|val| "'#{connection.quote_string(val)}'"}.join(",") + "))"
|
sql = sql + "(#{db_table}.#{db_field} IS NULL OR #{db_table}.#{db_field} NOT IN (" + v.collect{|val| "'#{connection.quote_string(val)}'"}.join(",") + "))"
|
||||||
when "!*"
|
when "!*"
|
||||||
sql = sql + "#{db_table}.#{db_field} IS NULL"
|
sql = sql + "#{db_table}.#{db_field} IS NULL"
|
||||||
sql << " OR #{db_table}.#{db_field} = ''" if is_custom_filter
|
|
||||||
when "*"
|
when "*"
|
||||||
sql = sql + "#{db_table}.#{db_field} IS NOT NULL"
|
sql = sql + "#{db_table}.#{db_field} IS NOT NULL"
|
||||||
sql << " AND #{db_table}.#{db_field} <> ''" if is_custom_filter
|
|
||||||
when ">="
|
when ">="
|
||||||
sql = sql + "#{db_table}.#{db_field} >= #{v.first.to_i}"
|
sql = sql + "#{db_table}.#{db_field} >= #{v.first.to_i}"
|
||||||
when "<="
|
when "<="
|
||||||
@@ -356,28 +361,8 @@ class Query < ActiveRecord::Base
|
|||||||
filters_clauses << sql
|
filters_clauses << sql
|
||||||
end if filters and valid?
|
end if filters and valid?
|
||||||
|
|
||||||
(project_clauses + filters_clauses).join(' AND ')
|
clause << ' AND ' unless clause.empty?
|
||||||
end
|
clause << filters_clauses.join(' AND ') unless filters_clauses.empty?
|
||||||
|
clause
|
||||||
private
|
|
||||||
|
|
||||||
def add_custom_fields_filters(custom_fields)
|
|
||||||
@available_filters ||= {}
|
|
||||||
|
|
||||||
custom_fields.select(&:is_filter?).each do |field|
|
|
||||||
case field.field_format
|
|
||||||
when "text"
|
|
||||||
options = { :type => :text, :order => 20 }
|
|
||||||
when "list"
|
|
||||||
options = { :type => :list_optional, :values => field.possible_values, :order => 20}
|
|
||||||
when "date"
|
|
||||||
options = { :type => :date, :order => 20 }
|
|
||||||
when "bool"
|
|
||||||
options = { :type => :list, :values => [[l(:general_text_yes), "1"], [l(:general_text_no), "0"]], :order => 20 }
|
|
||||||
else
|
|
||||||
options = { :type => :string, :order => 20 }
|
|
||||||
end
|
|
||||||
@available_filters["cf_#{field.id}"] = options.merge({ :name => field.name })
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@@ -17,9 +17,19 @@
|
|||||||
|
|
||||||
class Repository < ActiveRecord::Base
|
class Repository < ActiveRecord::Base
|
||||||
belongs_to :project
|
belongs_to :project
|
||||||
has_many :changesets, :dependent => :destroy, :order => "#{Changeset.table_name}.revision DESC"
|
has_many :changesets, :dependent => :destroy, :order => "#{Changeset.table_name}.committed_on DESC, #{Changeset.table_name}.id DESC"
|
||||||
has_many :changes, :through => :changesets
|
has_many :changes, :through => :changesets
|
||||||
|
|
||||||
|
# Removes leading and trailing whitespace
|
||||||
|
def url=(arg)
|
||||||
|
write_attribute(:url, arg ? arg.to_s.strip : nil)
|
||||||
|
end
|
||||||
|
|
||||||
|
# Removes leading and trailing whitespace
|
||||||
|
def root_url=(arg)
|
||||||
|
write_attribute(:root_url, arg ? arg.to_s.strip : nil)
|
||||||
|
end
|
||||||
|
|
||||||
def scm
|
def scm
|
||||||
@scm ||= self.scm_adapter.new url, root_url, login, password
|
@scm ||= self.scm_adapter.new url, root_url, login, password
|
||||||
update_attribute(:root_url, @scm.root_url) if root_url.blank?
|
update_attribute(:root_url, @scm.root_url) if root_url.blank?
|
||||||
@@ -51,7 +61,7 @@ class Repository < ActiveRecord::Base
|
|||||||
path = "/#{path}" unless path.starts_with?('/')
|
path = "/#{path}" unless path.starts_with?('/')
|
||||||
Change.find(:all, :include => :changeset,
|
Change.find(:all, :include => :changeset,
|
||||||
:conditions => ["repository_id = ? AND path = ?", id, path],
|
:conditions => ["repository_id = ? AND path = ?", id, path],
|
||||||
:order => "committed_on DESC, #{Changeset.table_name}.revision DESC").collect(&:changeset)
|
:order => "committed_on DESC, #{Changeset.table_name}.id DESC").collect(&:changeset)
|
||||||
end
|
end
|
||||||
|
|
||||||
def latest_changeset
|
def latest_changeset
|
||||||
@@ -88,4 +98,13 @@ class Repository < ActiveRecord::Base
|
|||||||
rescue
|
rescue
|
||||||
nil
|
nil
|
||||||
end
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def before_save
|
||||||
|
# Strips url and root_url
|
||||||
|
url.strip!
|
||||||
|
root_url.strip!
|
||||||
|
true
|
||||||
|
end
|
||||||
end
|
end
|
||||||
+1
-1
@@ -51,7 +51,7 @@ class Repository::Bazaar < Repository
|
|||||||
scm_info = scm.info
|
scm_info = scm.info
|
||||||
if scm_info
|
if scm_info
|
||||||
# latest revision found in database
|
# latest revision found in database
|
||||||
db_revision = latest_changeset ? latest_changeset.revision : 0
|
db_revision = latest_changeset ? latest_changeset.revision.to_i : 0
|
||||||
# latest revision in the repository
|
# latest revision in the repository
|
||||||
scm_revision = scm_info.lastrev.identifier.to_i
|
scm_revision = scm_info.lastrev.identifier.to_i
|
||||||
if db_revision < scm_revision
|
if db_revision < scm_revision
|
||||||
Loaded 100 of 4760 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user