mirror of
https://git.code.sf.net/p/seeddms/code
synced 2026-01-17 14:56:43 +00:00
Compare commits
3203 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a825bb43fb | ||
|
|
00c3a63ff1 | ||
|
|
4972929258 | ||
|
|
2ec29e3336 | ||
|
|
c638258a10 | ||
|
|
637fd66210 | ||
|
|
e1f976e646 | ||
|
|
31aa18606f | ||
|
|
04e9402094 | ||
|
|
abc8df5939 | ||
|
|
00d5d8b334 | ||
|
|
4ed83488ba | ||
|
|
2288be497c | ||
|
|
d50247ba09 | ||
|
|
e8c0ebbf4f | ||
|
|
133fc5d570 | ||
|
|
5fdd83de3c | ||
|
|
904e4b8657 | ||
|
|
fb59582a56 | ||
|
|
fc555555d2 | ||
|
|
28ba7b59b9 | ||
|
|
b7e075cdba | ||
|
|
c4c37becf6 | ||
|
|
287753b7bc | ||
|
|
52401dce05 | ||
|
|
bfe17bcc46 | ||
|
|
2e6d25873c | ||
|
|
3bbdf680de | ||
|
|
d7f1e899ba | ||
|
|
1d62de5213 | ||
|
|
ddab6e2b57 | ||
|
|
128a57a9c5 | ||
|
|
5ed5476106 | ||
|
|
789b5daaf8 | ||
|
|
2eb19048ab | ||
|
|
b30c4a7a66 | ||
|
|
b5d32f3d53 | ||
|
|
304db26698 | ||
|
|
71d5154945 | ||
|
|
157c033f2a | ||
|
|
9f39b639c6 | ||
|
|
3fec498ce5 | ||
|
|
ae34e29fed | ||
|
|
0eff90974e | ||
|
|
327d65c7e0 | ||
|
|
a8f52db542 | ||
|
|
15fc9bf312 | ||
|
|
bef2fb0786 | ||
|
|
1510acc606 | ||
|
|
ddcc6d6841 | ||
|
|
d9278b5600 | ||
|
|
0d7f9e674a | ||
|
|
052fee8222 | ||
|
|
12979afcbc | ||
|
|
728d162bc2 | ||
|
|
28e01b577a | ||
|
|
c620ec8f15 | ||
|
|
0a1f2ea418 | ||
|
|
b646333c37 | ||
|
|
a4462cdb6a | ||
|
|
1af377b268 | ||
|
|
6ddf3c3cfe | ||
|
|
c62abbcd06 | ||
|
|
5b611a425a | ||
|
|
992afe8e7c | ||
|
|
895dbf1b29 | ||
|
|
2b0c3241ed | ||
|
|
fe88895808 | ||
|
|
ec6c4855fc | ||
|
|
1033fee1b3 | ||
|
|
ceddf4d5bf | ||
|
|
30682237e9 | ||
|
|
5f4b1dde54 | ||
|
|
adeae90695 | ||
|
|
53cbe64222 | ||
|
|
ee143ad5d4 | ||
|
|
3c2f8f6013 | ||
|
|
7cb75bf518 | ||
|
|
d189443b29 | ||
|
|
2576001ad1 | ||
|
|
9f5528b7c2 | ||
|
|
5a5f5657a9 | ||
|
|
0abffe1f3d | ||
|
|
ab5411c44f | ||
|
|
8bb4f80032 | ||
|
|
3113c59796 | ||
|
|
faaf6d2fbb | ||
|
|
1307bb74cd | ||
|
|
e6c7ebaaec | ||
|
|
27110c06a9 | ||
|
|
ea5d4651e5 | ||
|
|
ca79b730ff | ||
|
|
a2a39ce946 | ||
|
|
1922899d7e | ||
|
|
58a29b675b | ||
|
|
d1d348deb9 | ||
|
|
b9abff5c55 | ||
|
|
b4d0761824 | ||
|
|
e43168059e | ||
|
|
36acb63ebe | ||
|
|
c2f69ce491 | ||
|
|
588d150c39 | ||
|
|
32b6445904 | ||
|
|
012977d606 | ||
|
|
d80009e484 | ||
|
|
4ace32c927 | ||
|
|
79560a8164 | ||
|
|
f89011f2ee | ||
|
|
e71fccbb1e | ||
|
|
43b1bb6fd8 | ||
|
|
cc41763a96 | ||
|
|
1c7b4b0466 | ||
|
|
2d4d4c59a3 | ||
|
|
dfe73c8cb1 | ||
|
|
dcf448072d | ||
|
|
74e65c9e0c | ||
|
|
a14ea507fc | ||
|
|
9db0985495 | ||
|
|
6f11dc6dc2 | ||
|
|
e6042e8538 | ||
|
|
eefbd18e5e | ||
|
|
8039a0f479 | ||
|
|
ae72faab11 | ||
|
|
7c01e94015 | ||
|
|
41a438754a | ||
|
|
9e3bb361ae | ||
|
|
8870ca5c5d | ||
|
|
17351584d5 | ||
|
|
ac841494a9 | ||
|
|
ce0de15ce1 | ||
|
|
1b163e90e1 | ||
|
|
791c23befa | ||
|
|
d552047b0b | ||
|
|
e1a970fb02 | ||
|
|
e9d953eed6 | ||
|
|
3a5886b64a | ||
|
|
14d79d58e7 | ||
|
|
56e15e5125 | ||
|
|
76b9b3c2d6 | ||
|
|
44621c0bb6 | ||
|
|
0d0fc4e50a | ||
|
|
dc14fc5217 | ||
|
|
1edb468877 | ||
|
|
2107955b7e | ||
|
|
a0e906a067 | ||
|
|
da69c19a1a | ||
|
|
9e16e54aaa | ||
|
|
b51749e631 | ||
|
|
f230cd6918 | ||
|
|
4f44241850 | ||
|
|
72a4a05bb2 | ||
|
|
409b86461b | ||
|
|
0d2cc403da | ||
|
|
f5073ffd4f | ||
|
|
4ed40bff78 | ||
|
|
478c385d13 | ||
|
|
7a06b50e92 | ||
|
|
0da2308ee3 | ||
|
|
4275072338 | ||
|
|
d3ab3e7069 | ||
|
|
cf786e749a | ||
|
|
06f0e1423b | ||
|
|
55aa6fe170 | ||
|
|
15ee5357a5 | ||
|
|
7f16340a26 | ||
|
|
50b25a59ec | ||
|
|
593b6359d2 | ||
|
|
416df6c846 | ||
|
|
0da7e0f655 | ||
|
|
c9286b75a0 | ||
|
|
bd80e96c92 | ||
|
|
9c81a10109 | ||
|
|
74e5be95c2 | ||
|
|
2f8e3fbb51 | ||
|
|
f73bdb8388 | ||
|
|
35873391c8 | ||
|
|
3914b76919 | ||
|
|
e1c7e27a69 | ||
|
|
4e9901161f | ||
|
|
aae9422e30 | ||
|
|
ad84609a49 | ||
|
|
0b4afff149 | ||
|
|
01837f6c5c | ||
|
|
1999206af0 | ||
|
|
d36636be55 | ||
|
|
e0b421dcca | ||
|
|
038e929778 | ||
|
|
246ba45c52 | ||
|
|
08cac16ecf | ||
|
|
66114a653c | ||
|
|
eded3365b1 | ||
|
|
7998c9d7e0 | ||
|
|
8b2db5376c | ||
|
|
3e8a494f1a | ||
|
|
9fad6c6e61 | ||
|
|
c1b736022d | ||
|
|
8e834e8898 | ||
|
|
69b61b1a75 | ||
|
|
f65af1741c | ||
|
|
fc4d2edb57 | ||
|
|
37478ecd89 | ||
|
|
6a7d596806 | ||
|
|
ceaa62f16c | ||
|
|
ac2ade6b6e | ||
|
|
36dbc1f825 | ||
|
|
43f078a153 | ||
|
|
a1a20a4c25 | ||
|
|
12a4a6446f | ||
|
|
a0b3d9da27 | ||
|
|
f4003f72e9 | ||
|
|
18e4874a77 | ||
|
|
c6243813bf | ||
|
|
3345155e5e | ||
|
|
0224793366 | ||
|
|
4eba2e3283 | ||
|
|
3347b8e4f5 | ||
|
|
9300d92311 | ||
|
|
192e750f00 | ||
|
|
fb37e526cc | ||
|
|
00d71f4c2e | ||
|
|
5d2d80b0af | ||
|
|
0fa5ffae48 | ||
|
|
192daaec69 | ||
|
|
89ce934164 | ||
|
|
61dd316e09 | ||
|
|
81ee0beeae | ||
|
|
c66637ce6c | ||
|
|
eb95f7999a | ||
|
|
2009e59629 | ||
|
|
22aaa5608f | ||
|
|
6b562477aa | ||
|
|
a03b96330a | ||
|
|
6c84787027 | ||
|
|
ba8aebb24b | ||
|
|
023e2c3edf | ||
|
|
3af7ce8177 | ||
|
|
d872b68efe | ||
|
|
699e1bcfad | ||
|
|
c23c5845ad | ||
|
|
00c1efffac | ||
|
|
ddfe87a82c | ||
|
|
79aa8098e9 | ||
|
|
98f5cee2eb | ||
|
|
07bfdca11e | ||
|
|
ac656d4da0 | ||
|
|
1115d08d2f | ||
|
|
cd0a5c9844 | ||
|
|
8432340154 | ||
|
|
1a5dbfef51 | ||
|
|
0f258d81ac | ||
|
|
bcf2239334 | ||
|
|
f69c9ad9d0 | ||
|
|
46f5b630d6 | ||
|
|
d7e780493f | ||
|
|
8a148daa42 | ||
|
|
46371b2cf2 | ||
|
|
31fa1d505c | ||
|
|
b118b00536 | ||
|
|
ab16c6b539 | ||
|
|
b34b37189a | ||
|
|
c10d2f403a | ||
|
|
8b4c01e339 | ||
|
|
ee568bb916 | ||
|
|
000f1e2c44 | ||
|
|
e06aa0a286 | ||
|
|
568718f023 | ||
|
|
1085401ccf | ||
|
|
ac69311242 | ||
|
|
f1183cd4d2 | ||
|
|
878f7e559a | ||
|
|
5ebbaa9336 | ||
|
|
04b63531c7 | ||
|
|
f02ba8ddc5 | ||
|
|
0139beb33f | ||
|
|
11301f1955 | ||
|
|
d120b9eb7d | ||
|
|
c721c05d6d | ||
|
|
bd396e1c69 | ||
|
|
b5dbadfb66 | ||
|
|
0e86608cbc | ||
|
|
4f00481f1e | ||
|
|
2b0d45c68c | ||
|
|
6ea76aa00e | ||
|
|
0638776bc5 | ||
|
|
153796b82c | ||
|
|
6b6410997f | ||
|
|
52fdbb8c16 | ||
|
|
deb2aeea57 | ||
|
|
0bd625ca20 | ||
|
|
0092f359bd | ||
|
|
681ce9090f | ||
|
|
fc8bef612e | ||
|
|
5bb70b82aa | ||
|
|
2bb27b5b8e | ||
|
|
23c73ed578 | ||
|
|
e5390d0dbe | ||
|
|
7d575b2d11 | ||
|
|
4a1a3c6bfe | ||
|
|
9f23cc37d7 | ||
|
|
c3094ce87f | ||
|
|
ef42fcac07 | ||
|
|
0c99740d25 | ||
|
|
1d74863f81 | ||
|
|
c117b9a590 | ||
|
|
52b43ba8c6 | ||
|
|
0f46a7cd6a | ||
|
|
5f00ebd852 | ||
|
|
918af9b2e3 | ||
|
|
bd9c9e8e3b | ||
|
|
54bdbfdc56 | ||
|
|
d92acf86a9 | ||
|
|
7c0634f272 | ||
|
|
0e66c6457a | ||
|
|
77474bdaee | ||
|
|
64a7d341eb | ||
|
|
0fd0293f35 | ||
|
|
5bd93d4efe | ||
|
|
403d391d72 | ||
|
|
076e5bc5c2 | ||
|
|
2ccbe2b9c7 | ||
|
|
eebe9d48d3 | ||
|
|
c865927fe4 | ||
|
|
d4add8b343 | ||
|
|
23568c0a6a | ||
|
|
40f86da41d | ||
|
|
24595a234d | ||
|
|
199fd57151 | ||
|
|
1103324e89 | ||
|
|
bb2ccf05a0 | ||
|
|
b6dce79936 | ||
|
|
424d279c7f | ||
|
|
6178252e56 | ||
|
|
1e699147ff | ||
|
|
fa19503ab2 | ||
|
|
497d1e1ca3 | ||
|
|
775a785525 | ||
|
|
f97124d694 | ||
|
|
d7eeacdc74 | ||
|
|
f42d4d38b1 | ||
|
|
fab8276b0d | ||
|
|
337c0ed41f | ||
|
|
efa587493e | ||
|
|
fde112e2d9 | ||
|
|
a1520299a2 | ||
|
|
de53c5159c | ||
|
|
ff64e76213 | ||
|
|
c4c36735b6 | ||
|
|
80ecac5710 | ||
|
|
eb2296f814 | ||
|
|
300bcb2514 | ||
|
|
e6312db48f | ||
|
|
ca706753bc | ||
|
|
048c56f3a3 | ||
|
|
55c7a32a05 | ||
|
|
e14bfd9326 | ||
|
|
337f9f2ce4 | ||
|
|
6e489dc80a | ||
|
|
32c93f5494 | ||
|
|
3fce0d58b6 | ||
|
|
e51e7cd758 | ||
|
|
835b330331 | ||
|
|
a25de1eea5 | ||
|
|
752653a2b3 | ||
|
|
e3cc28916d | ||
|
|
6211ab6b32 | ||
|
|
00f7a0ee35 | ||
|
|
f63f7847f0 | ||
|
|
3bef98756a | ||
|
|
626e521bc7 | ||
|
|
e88321c577 | ||
|
|
c44aaae446 | ||
|
|
b71467b8c8 | ||
|
|
d612220ad5 | ||
|
|
2b2d9ef7de | ||
|
|
f4097c6831 | ||
|
|
1f92a47c30 | ||
|
|
10a3aaf212 | ||
|
|
c83bcf9877 | ||
|
|
c04eb28ac1 | ||
|
|
173ecb00b3 | ||
|
|
3fb9d140fa | ||
|
|
cb808e0e66 | ||
|
|
8609fdee74 | ||
|
|
dc642fa898 | ||
|
|
7fb0acb562 | ||
|
|
7c292986f5 | ||
|
|
b25776eaad | ||
|
|
d8e38c2825 | ||
|
|
668ee243b2 | ||
|
|
9616a540c2 | ||
|
|
f4ee945ab1 | ||
|
|
057abec09c | ||
|
|
8218b752f5 | ||
|
|
b7b9acbe7e | ||
|
|
db5b242cbc | ||
|
|
c383ca0625 | ||
|
|
f1211f6c80 | ||
|
|
33fe05fc6e | ||
|
|
1c5977fca5 | ||
|
|
5ae461a157 | ||
|
|
836a2b50a1 | ||
|
|
2b900b5e06 | ||
|
|
ab72673379 | ||
|
|
a7579f47ae | ||
|
|
67d6191024 | ||
|
|
00fe788571 | ||
|
|
7ae5749bcf | ||
|
|
fe0fd30971 | ||
|
|
658351a4d3 | ||
|
|
20686bccbd | ||
|
|
63adb75fbc | ||
|
|
3f6719e7aa | ||
|
|
5d2ace6a14 | ||
|
|
359cdedfdb | ||
|
|
102a5603c0 | ||
|
|
97778d3e2b | ||
|
|
8bfe9e92db | ||
|
|
61b7620ab0 | ||
|
|
737e69876d | ||
|
|
df6a2e79bc | ||
|
|
bc4362c196 | ||
|
|
e88aa870db | ||
|
|
4c3218bc0f | ||
|
|
cb1cb46cfe | ||
|
|
1463f00faf | ||
|
|
0ffc8c78f7 | ||
|
|
513343c89a | ||
|
|
0b7d3cad2d | ||
|
|
9c8c9616d5 | ||
|
|
7c973d9f37 | ||
|
|
8cb7e22bf9 | ||
|
|
d86b2cc883 | ||
|
|
45e1d47e8f | ||
|
|
9dfc6e8b1e | ||
|
|
1934cdd7c5 | ||
|
|
22463fdb40 | ||
|
|
ef9e685f55 | ||
|
|
458252f531 | ||
|
|
11030fad52 | ||
|
|
bdcaf2b5f3 | ||
|
|
23f17e291e | ||
|
|
42a81b6b0e | ||
|
|
1ab07d53f7 | ||
|
|
845317e27d | ||
|
|
0788c29c4a | ||
|
|
57bbc06577 | ||
|
|
335c7bbf98 | ||
|
|
c56a92b395 | ||
|
|
77ce7554a8 | ||
|
|
22802c4abd | ||
|
|
e34830a53e | ||
|
|
97feb24466 | ||
|
|
0c30b97f2d | ||
|
|
cb1d55e413 | ||
|
|
3d880be30c | ||
|
|
c3e415ff7a | ||
|
|
6dc9cc8b8e | ||
|
|
3bf13c9e03 | ||
|
|
4f6261321f | ||
|
|
21a787aa21 | ||
|
|
ef61f16f95 | ||
|
|
f6ae2c3868 | ||
|
|
f0a3d7d60c | ||
|
|
fb43a82818 | ||
|
|
1506cef2ab | ||
|
|
83d11651b3 | ||
|
|
ace30334a8 | ||
|
|
795b0e08d3 | ||
|
|
d628b01ede | ||
|
|
fa683ba65f | ||
|
|
48eebee92a | ||
|
|
b351a05aba | ||
|
|
328cbd9eb9 | ||
|
|
6d6bbca94b | ||
|
|
aa733c7531 | ||
|
|
41b2ae91e1 | ||
|
|
244a5da6d8 | ||
|
|
9461f2c24d | ||
|
|
1374c7fda3 | ||
|
|
927e5acdc2 | ||
|
|
8f07c2fd1f | ||
|
|
99bb9e5e20 | ||
|
|
12ffb0174e | ||
|
|
b5c773a4a3 | ||
|
|
c4f1019afb | ||
|
|
2f868c4f44 | ||
|
|
e141892934 | ||
|
|
9e9c0c8ac5 | ||
|
|
de7d1c005e | ||
|
|
c786635f9c | ||
|
|
082a6a8af0 | ||
|
|
5694bf9501 | ||
|
|
aeb0e4f1de | ||
|
|
8a01102cf5 | ||
|
|
182418c856 | ||
|
|
1488cdcfca | ||
|
|
e4be5465be | ||
|
|
0c28f47481 | ||
|
|
53f350c2fa | ||
|
|
9e4eae8206 | ||
|
|
cfc23e0ddf | ||
|
|
baa3010b43 | ||
|
|
9dbe4e25aa | ||
|
|
330073f52a | ||
|
|
4888082cda | ||
|
|
1667187613 | ||
|
|
9850b2d8f9 | ||
|
|
9c740db936 | ||
|
|
938126c19c | ||
|
|
3b473edd25 | ||
|
|
b6a0b45867 | ||
|
|
863c3f971c | ||
|
|
fbbc79815d | ||
|
|
e2e52d61b1 | ||
|
|
b786e42bb3 | ||
|
|
a97fcbc67a | ||
|
|
3b74689c9c | ||
|
|
971dc536f7 | ||
|
|
b8449289ac | ||
|
|
3e733b91cd | ||
|
|
e422fcf67a | ||
|
|
2ce2fd07fe | ||
|
|
f0cd33d110 | ||
|
|
dc6b153df8 | ||
|
|
04211bd09c | ||
|
|
6bb4eeb926 | ||
|
|
d48af54737 | ||
|
|
97c6b19c1f | ||
|
|
5278732456 | ||
|
|
df659c52d9 | ||
|
|
7012580476 | ||
|
|
54c6d63a2d | ||
|
|
4b9844262c | ||
|
|
6dbcf2a172 | ||
|
|
c3058176f3 | ||
|
|
dbd43d5877 | ||
|
|
18a5306d3c | ||
|
|
3add16e06a | ||
|
|
d9e6472fff | ||
|
|
ff1c29561f | ||
|
|
43e114101a | ||
|
|
3e2e8e2591 | ||
|
|
c2a8b4bbc6 | ||
|
|
3721fcfc22 | ||
|
|
94d6dd0511 | ||
|
|
4329729ae0 | ||
|
|
a453c0e6ef | ||
|
|
2ee4773357 | ||
|
|
c4d5ebd24d | ||
|
|
56a0b14fe9 | ||
|
|
ea2173b4ed | ||
|
|
b8c94556ca | ||
|
|
620a5ff99d | ||
|
|
ad35601bf2 | ||
|
|
57a90d93a6 | ||
|
|
589b213fe7 | ||
|
|
fdf7126a68 | ||
|
|
5cd59a7a84 | ||
|
|
3ccdf862bf | ||
|
|
607251e02d | ||
|
|
e76df4c71f | ||
|
|
04ce8ea28f | ||
|
|
446f04c775 | ||
|
|
225817d468 | ||
|
|
f4b621de36 | ||
|
|
9a22f0390a | ||
|
|
da3946adc6 | ||
|
|
9a08430d5b | ||
|
|
e5ad205169 | ||
|
|
80067393f1 | ||
|
|
0539945bf1 | ||
|
|
dc7cf3ce86 | ||
|
|
3a9abc5009 | ||
|
|
fe419f4857 | ||
|
|
20ac984a64 | ||
|
|
751918ef17 | ||
|
|
6211976f3c | ||
|
|
73d748a025 | ||
|
|
e5057d8223 | ||
|
|
6d9cc4039b | ||
|
|
f12a9094db | ||
|
|
365661afb8 | ||
|
|
f3e7d04674 | ||
|
|
a0db4bcc6d | ||
|
|
87a9db64f8 | ||
|
|
b8fd313e2d | ||
|
|
85c190aad2 | ||
|
|
995f7a5bad | ||
|
|
6557d2edc9 | ||
|
|
3e45d6a13f | ||
|
|
502ea86d8d | ||
|
|
418c42ae59 | ||
|
|
16cdb8a323 | ||
|
|
d991978144 | ||
|
|
40bd123fe3 | ||
|
|
2bc5b26175 | ||
|
|
7deddf8f4e | ||
|
|
2c42fd6a23 | ||
|
|
6b5826ded4 | ||
|
|
dee7977016 | ||
|
|
8bc93eac03 | ||
|
|
7a7fca84b4 | ||
|
|
6af82069e8 | ||
|
|
821d9b1470 | ||
|
|
38dd38d7c6 | ||
|
|
6254c8a41a | ||
|
|
490fe09390 | ||
|
|
a91003d5fa | ||
|
|
7ba81f50e3 | ||
|
|
c6470efc6f | ||
|
|
d2c680280b | ||
|
|
6d5d1a7703 | ||
|
|
c52abe7198 | ||
|
|
93f6b01c7f | ||
|
|
d641a8d2ed | ||
|
|
4ffe010d06 | ||
|
|
332a7b2f3d | ||
|
|
bf5aedf1b5 | ||
|
|
1f6a3c7f77 | ||
|
|
987cc5d164 | ||
|
|
369dc80110 | ||
|
|
eb4b28ea8c | ||
|
|
20b03dcbe0 | ||
|
|
af93db836e | ||
|
|
1b15008870 | ||
|
|
ecc70bc99a | ||
|
|
cc341f6ed3 | ||
|
|
1ae35ca6ad | ||
|
|
983af33300 | ||
|
|
9b07f6e943 | ||
|
|
30c2b8a493 | ||
|
|
9a76df52bd | ||
|
|
307b524d11 | ||
|
|
dfedd201dd | ||
|
|
6fd868c5a7 | ||
|
|
c9e93c329c | ||
|
|
87fe831973 | ||
|
|
5dab792dba | ||
|
|
21989fadbb | ||
|
|
17d1f2bffe | ||
|
|
7c1c81f7fc | ||
|
|
bef41ad838 | ||
|
|
939a7dbce2 | ||
|
|
b412f113bf | ||
|
|
7370eebba7 | ||
|
|
d13f37cfec | ||
|
|
49c2e54e94 | ||
|
|
8c43c709b0 | ||
|
|
16c560d549 | ||
|
|
8907c2f20a | ||
|
|
e383434a3d | ||
|
|
b854d64757 | ||
|
|
2014eae334 | ||
|
|
34c7132847 | ||
|
|
24146db478 | ||
|
|
6c3ecaf9a1 | ||
|
|
15182713ea | ||
|
|
7c29d1d4e8 | ||
|
|
58e8306bb4 | ||
|
|
eca2701da1 | ||
|
|
9cab1880a7 | ||
|
|
202e607959 | ||
|
|
b558844841 | ||
|
|
b48318d1da | ||
|
|
f8ac9090fb | ||
|
|
d80d1be9de | ||
|
|
f24330740a | ||
|
|
d90b01111e | ||
|
|
43fe015049 | ||
|
|
6f4a1bab68 | ||
|
|
7a1836d33a | ||
|
|
687d7eb0dd | ||
|
|
9e92524fdb | ||
|
|
283d051d3a | ||
|
|
988dc9deff | ||
|
|
f5148c00c2 | ||
|
|
6de426bbc3 | ||
|
|
11942c825d | ||
|
|
48613b5897 | ||
|
|
a5a2b877ce | ||
|
|
b65d940259 | ||
|
|
b88e05fe22 | ||
|
|
a4f96c76d6 | ||
|
|
1e8da679b5 | ||
|
|
a156932843 | ||
|
|
0652faf7c3 | ||
|
|
eca5f3608f | ||
|
|
dafa4813c1 | ||
|
|
b64ee6012c | ||
|
|
95547cf6b8 | ||
|
|
aa9a30a98a | ||
|
|
0869e97a1a | ||
|
|
aa61028f08 | ||
|
|
673bc9ec7d | ||
|
|
275e81874a | ||
|
|
98936632b2 | ||
|
|
830f0258df | ||
|
|
f095e252ad | ||
|
|
68bb7bcfaf | ||
|
|
659cdb4e6c | ||
|
|
535a0b1b67 | ||
|
|
0f417a2d7b | ||
|
|
87ee71a1a1 | ||
|
|
96933bb30d | ||
|
|
b9c613ff83 | ||
|
|
b57dc78e2a | ||
|
|
f93af56f52 | ||
|
|
b2fd7bb383 | ||
|
|
3e63f1ffc0 | ||
|
|
27b5af8ada | ||
|
|
9889bbe639 | ||
|
|
3bdb215adf | ||
|
|
056dd8bd09 | ||
|
|
2b0351325c | ||
|
|
5e386597c3 | ||
|
|
5ec5bab294 | ||
|
|
b91745626a | ||
|
|
7b87cc355d | ||
|
|
29a6882106 | ||
|
|
6fbc6043eb | ||
|
|
e78c8174d8 | ||
|
|
d4f4d5cfcd | ||
|
|
f7f0721dba | ||
|
|
a1b4b3b081 | ||
|
|
f7683f2176 | ||
|
|
fa946be140 | ||
|
|
6a54f7dac7 | ||
|
|
050aff4798 | ||
|
|
58434abf10 | ||
|
|
6e124f73f1 | ||
|
|
b01e2aa666 | ||
|
|
36110a85e7 | ||
|
|
684c316f86 | ||
|
|
622b7a13bb | ||
|
|
f635d0e546 | ||
|
|
9ae7a54183 | ||
|
|
45d0d0b9d7 | ||
|
|
4ef64199ab | ||
|
|
611be01cce | ||
|
|
e6766a3607 | ||
|
|
efdb37399d | ||
|
|
25e12c5f5e | ||
|
|
542a6cb045 | ||
|
|
31fda7e60e | ||
|
|
f727843720 | ||
|
|
4e5fefa4ba | ||
|
|
ea5a9f499f | ||
|
|
df94bc0c1a | ||
|
|
07f50b4b95 | ||
|
|
fdda22b58d | ||
|
|
adde8afc84 | ||
|
|
e40afa452c | ||
|
|
da1bf3fb97 | ||
|
|
9260382ef2 | ||
|
|
4c8a2496b6 | ||
|
|
b46795cbfe | ||
|
|
e7303b6371 | ||
|
|
b2b61eb990 | ||
|
|
3cd4763c0e | ||
|
|
8e6828e36d | ||
|
|
a830b18fc3 | ||
|
|
77a606cebe | ||
|
|
768631bf55 | ||
|
|
3487a27f9d | ||
|
|
43f7a94aa6 | ||
|
|
19266f1647 | ||
|
|
2d3ec59c2d | ||
|
|
ab5aec99ba | ||
|
|
cce3899688 | ||
|
|
39ec44cd41 | ||
|
|
b6a308e630 | ||
|
|
d05a200ed6 | ||
|
|
8b68402bec | ||
|
|
0c1a795113 | ||
|
|
3b55c458c2 | ||
|
|
825ae7bfeb | ||
|
|
24ae96b9fa | ||
|
|
5904d22394 | ||
|
|
753d808d2a | ||
|
|
a343c4cc1c | ||
|
|
7a1b03951e | ||
|
|
1398b614cd | ||
|
|
9ea8a02893 | ||
|
|
5cf3b5fc3e | ||
|
|
6ccabf1c68 | ||
|
|
4f3a7f6512 | ||
|
|
6fbfe15baf | ||
|
|
43c1385e0f | ||
|
|
11c97f4c41 | ||
|
|
ef551e6923 | ||
|
|
ada2730636 | ||
|
|
7b807f8d67 | ||
|
|
40ce4a74e1 | ||
|
|
f19ed34d25 | ||
|
|
bbcf7cb979 | ||
|
|
99bc6becb6 | ||
|
|
0a6ce976c7 | ||
|
|
ef1113490d | ||
|
|
5ddfa0e297 | ||
|
|
73d27bc82b | ||
|
|
be7aa1b4a8 | ||
|
|
749f7a2fb1 | ||
|
|
9e9995241d | ||
|
|
46040dce7e | ||
|
|
8b34c4f82e | ||
|
|
8bc9ab8f3c | ||
|
|
9f20268d3b | ||
|
|
cb0c51234e | ||
|
|
58a46497f0 | ||
|
|
93c88a6f87 | ||
|
|
50d528a831 | ||
|
|
20dd55840e | ||
|
|
74003313e8 | ||
|
|
09a60988fb | ||
|
|
23f05a4eb6 | ||
|
|
d7a936f6f1 | ||
|
|
532db722a6 | ||
|
|
75d716db26 | ||
|
|
4401ce7b23 | ||
|
|
74d1b11250 | ||
|
|
3cfa3d2d7b | ||
|
|
f2b0375df6 | ||
|
|
64a5ea3d90 | ||
|
|
020e307240 | ||
|
|
ca9e1c8860 | ||
|
|
59d9786a4c | ||
|
|
e733b4fced | ||
|
|
652acf4b86 | ||
|
|
0bd2e2d83d | ||
|
|
c5b9306918 | ||
|
|
c91476fe80 | ||
|
|
8767d170f1 | ||
|
|
e2960219c8 | ||
|
|
0b22b8d657 | ||
|
|
f5068fa30f | ||
|
|
30b8d4ddd9 | ||
|
|
cdb93920e4 | ||
|
|
9a616999d3 | ||
|
|
00041b30bd | ||
|
|
a289c8bbf6 | ||
|
|
cb601a82eb | ||
|
|
7218e47558 | ||
|
|
56c35b5eba | ||
|
|
486a685873 | ||
|
|
5cbf98e832 | ||
|
|
bffa24ad60 | ||
|
|
2a23dbb0ef | ||
|
|
f67ba27e4b | ||
|
|
8c4e20e649 | ||
|
|
03a394906e | ||
|
|
bf23abad87 | ||
|
|
e8a50e3101 | ||
|
|
0c260f286b | ||
|
|
38993eced2 | ||
|
|
635d8253fe | ||
|
|
f02074c794 | ||
|
|
4e33cee86a | ||
|
|
34a02f77d7 | ||
|
|
4de124d9ae | ||
|
|
c57640f804 | ||
|
|
39fc81b64b | ||
|
|
db2c4a739e | ||
|
|
371f348d88 | ||
|
|
265865a9b6 | ||
|
|
f443f6544a | ||
|
|
7635146a94 | ||
|
|
363f417eb7 | ||
|
|
3827cdda27 | ||
|
|
6d1aa2f347 | ||
|
|
cefcdc966b | ||
|
|
780d398d4c | ||
|
|
8cbf9c803f | ||
|
|
0754a794d3 | ||
|
|
1a3d3c8f80 | ||
|
|
ea5efd75d7 | ||
|
|
d1b967e9f3 | ||
|
|
aa4997a7e7 | ||
|
|
79e926324a | ||
|
|
bfcad700af | ||
|
|
e91a66af21 | ||
|
|
1ab5f83395 | ||
|
|
e425120d7d | ||
|
|
fbc3be64a2 | ||
|
|
eeb3422e8a | ||
|
|
4363566998 | ||
|
|
514249a132 | ||
|
|
3480a9550d | ||
|
|
047b5bb3b0 | ||
|
|
74292d9304 | ||
|
|
7c818d0913 | ||
|
|
cd263e7353 | ||
|
|
7485d0291a | ||
|
|
5d6235ec0b | ||
|
|
554b102356 | ||
|
|
012c3b7d22 | ||
|
|
33616f2c92 | ||
|
|
64658c06cd | ||
|
|
afb77c4365 | ||
|
|
1132bd134e | ||
|
|
1a5a5ad6c8 | ||
|
|
3614bae91b | ||
|
|
da86d0714d | ||
|
|
88ace95baa | ||
|
|
05a3405f07 | ||
|
|
960edf45ea | ||
|
|
cd99928cd4 | ||
|
|
d939b40486 | ||
|
|
447c035065 | ||
|
|
b87f68c06e | ||
|
|
a024cc19d3 | ||
|
|
9d9e05a54b | ||
|
|
01a4251b9a | ||
|
|
c1ea7fd6cc | ||
|
|
21b590d547 | ||
|
|
686fef1f4e | ||
|
|
7d34bd86b3 | ||
|
|
813587e8c9 | ||
|
|
0f9be43152 | ||
|
|
d1690c917d | ||
|
|
2c0729915c | ||
|
|
1af7524b76 | ||
|
|
266ae182f0 | ||
|
|
e0cfbd9b1b | ||
|
|
6d817b333c | ||
|
|
9cd60901b1 | ||
|
|
c53b3babbd | ||
|
|
53654444f0 | ||
|
|
3cee482b1c | ||
|
|
1cb6816a6f | ||
|
|
06025d03db | ||
|
|
8d660b1f98 | ||
|
|
7e73388730 | ||
|
|
b2f0f2fa30 | ||
|
|
3205f6ad82 | ||
|
|
c519feb6c8 | ||
|
|
1d4e7364ec | ||
|
|
e014b37f44 | ||
|
|
aece6cbaaa | ||
|
|
bf62dd68e9 | ||
|
|
065244c128 | ||
|
|
39e9ba904a | ||
|
|
faa47a9d2e | ||
|
|
096312dbdb | ||
|
|
a99efecb7b | ||
|
|
c640ece18b | ||
|
|
8644e750e9 | ||
|
|
9c9de6d0a1 | ||
|
|
189bbb540c | ||
|
|
93192b7e3d | ||
|
|
1a84cb311a | ||
|
|
4fb43aef5a | ||
|
|
791872adee | ||
|
|
5869abc56b | ||
|
|
a17fcfcd8e | ||
|
|
c6c99bc384 | ||
|
|
e557811acf | ||
|
|
41b5caa302 | ||
|
|
515a8de2e0 | ||
|
|
12896970cc | ||
|
|
12a44b75a3 | ||
|
|
f5b8b5b45d | ||
|
|
efd79e7521 | ||
|
|
ff4151093c | ||
|
|
84a61cbd14 | ||
|
|
d7a935b276 | ||
|
|
0acfb9a265 | ||
|
|
431a2e581c | ||
|
|
4cb4cce922 | ||
|
|
56adaae427 | ||
|
|
efd46b7a1d | ||
|
|
b03e759053 | ||
|
|
b7c46ccfda | ||
|
|
90f849c801 | ||
|
|
34b1d792ec | ||
|
|
bc1faf4d2e | ||
|
|
0a8659826f | ||
|
|
612a493873 | ||
|
|
c2f773ad85 | ||
|
|
5e18a0b5b4 | ||
|
|
dcba7a7572 | ||
|
|
da2174fafd | ||
|
|
f0fc1bfcc3 | ||
|
|
8773195f2a | ||
|
|
29e9907c89 | ||
|
|
113db3fb01 | ||
|
|
539b5b02eb | ||
|
|
ded86a39f2 | ||
|
|
a2645a4f16 | ||
|
|
025e293f80 | ||
|
|
db8e6f3ac6 | ||
|
|
6bb34b870a | ||
|
|
4a23c1df86 | ||
|
|
bb5a79ba70 | ||
|
|
30eadac7cd | ||
|
|
1873d77958 | ||
|
|
4a678ad1ec | ||
|
|
4d471ed592 | ||
|
|
fb44b524fd | ||
|
|
ed12ddb573 | ||
|
|
d8b2433edd | ||
|
|
e128e0e9dd | ||
|
|
2c7ab1cfb1 | ||
|
|
a7deac7948 | ||
|
|
e279a2f8e8 | ||
|
|
84fca7227c | ||
|
|
86fa6269b4 | ||
|
|
7e7b12f1c3 | ||
|
|
cad9e24ec3 | ||
|
|
42a7644d09 | ||
|
|
4c47d69a88 | ||
|
|
33e746ff80 | ||
|
|
54dabfed93 | ||
|
|
132b904315 | ||
|
|
fa241482c0 | ||
|
|
f55db469c7 | ||
|
|
c9ae939bff | ||
|
|
73a7f8a5f2 | ||
|
|
39b81e03c3 | ||
|
|
6a9def5358 | ||
|
|
15c281095d | ||
|
|
7bdf60ebbf | ||
|
|
606f8d8df8 | ||
|
|
993a8056ec | ||
|
|
81f091a44d | ||
|
|
1fc4d21f27 | ||
|
|
7b30188dd9 | ||
|
|
d3631a4f61 | ||
|
|
d994232cc4 | ||
|
|
84b709c8cd | ||
|
|
d8c534dff4 | ||
|
|
0695f35f8d | ||
|
|
f3fb09762f | ||
|
|
2c2d1e4dd8 | ||
|
|
130afd7d25 | ||
|
|
c0377d4e34 | ||
|
|
8fcfd70bd6 | ||
|
|
7c2ac0e6ad | ||
|
|
7aba671ade | ||
|
|
59e92a836f | ||
|
|
e10b7ff3e3 | ||
|
|
5dc5400e04 | ||
|
|
e8d1369fad | ||
|
|
397081bdeb | ||
|
|
ceeedcdd92 | ||
|
|
aa045478dd | ||
|
|
c9faef81f7 | ||
|
|
6b0b517bed | ||
|
|
9bb2943719 | ||
|
|
ee727c12ba | ||
|
|
8fbb5fe24c | ||
|
|
67d8cf39fb | ||
|
|
6defb81dd8 | ||
|
|
ffc259c680 | ||
|
|
bbc4943973 | ||
|
|
a9a68d9d7b | ||
|
|
64e6e8f1c4 | ||
|
|
18cfdb3efe | ||
|
|
e728633349 | ||
|
|
1710e5278b | ||
|
|
fd23364bde | ||
|
|
c7f8c157c6 | ||
|
|
70b2fa45e4 | ||
|
|
05e1f04773 | ||
|
|
c39fbcb70d | ||
|
|
c8aca99462 | ||
|
|
0c08af7246 | ||
|
|
58f349e295 | ||
|
|
c494afa49c | ||
|
|
7f0ed73f74 | ||
|
|
1df630a28e | ||
|
|
347c740f1f | ||
|
|
5e3f5fc8f0 | ||
|
|
7574615b3c | ||
|
|
664b881eb7 | ||
|
|
b9e12a82ae | ||
|
|
7292ceb83c | ||
|
|
ad49c78302 | ||
|
|
ff5580fa7e | ||
|
|
5b9df18756 | ||
|
|
53ee447d84 | ||
|
|
a0ef972028 | ||
|
|
47b3416b5b | ||
|
|
4f650f3d2b | ||
|
|
bb779c678c | ||
|
|
8e78a217fc | ||
|
|
826a6ae109 | ||
|
|
2fd21b9792 | ||
|
|
58e1abe568 | ||
|
|
41e2d7b3be | ||
|
|
2650ff4d7f | ||
|
|
bc06fd60f0 | ||
|
|
2850298297 | ||
|
|
b0868e9726 | ||
|
|
a018a1602a | ||
|
|
ec8d2ab8b3 | ||
|
|
d22d21d157 | ||
|
|
d82bd687aa | ||
|
|
02a830e74c | ||
|
|
16c8102392 | ||
|
|
5ac51f3c89 | ||
|
|
0d43c618cd | ||
|
|
68a16ce372 | ||
|
|
3931227789 | ||
|
|
6fa0849924 | ||
|
|
7d93bccee6 | ||
|
|
e68608bf04 | ||
|
|
7696dc66b8 | ||
|
|
d53318b917 | ||
|
|
aaec9a5410 | ||
|
|
531e11ce57 | ||
|
|
c524add775 | ||
|
|
92949d8887 | ||
|
|
2f23a09f24 | ||
|
|
445664ed53 | ||
|
|
9186cf66c3 | ||
|
|
3ac58509cc | ||
|
|
d5cef4fabf | ||
|
|
4bfb3795bd | ||
|
|
8197f37117 | ||
|
|
73b1051d82 | ||
|
|
6025092793 | ||
|
|
93f0faa145 | ||
|
|
b971932c88 | ||
|
|
2fe261492c | ||
|
|
aaa40c6075 | ||
|
|
82784f4aed | ||
|
|
dc18b39305 | ||
|
|
c5247b8abf | ||
|
|
f32f39bb6a | ||
|
|
f1f574c412 | ||
|
|
780be78d36 | ||
|
|
aa8290e03b | ||
|
|
935d8a7b68 | ||
|
|
768345a2ef | ||
|
|
6a3939158b | ||
|
|
8c2aac4d98 | ||
|
|
8129221b57 | ||
|
|
788b5b0014 | ||
|
|
768c02866c | ||
|
|
2d4c7b7581 | ||
|
|
d6e652ec45 | ||
|
|
a7286be63a | ||
|
|
599786bcb0 | ||
|
|
363fdf7a1a | ||
|
|
590a93525c | ||
|
|
518eecde18 | ||
|
|
59c59f136a | ||
|
|
b18fb02303 | ||
|
|
a2c82409c9 | ||
|
|
663d660e29 | ||
|
|
ec41921691 | ||
|
|
20bc412a17 | ||
|
|
feec95eff7 | ||
|
|
df76dbf35a | ||
|
|
e847ff2647 | ||
|
|
5a30032375 | ||
|
|
6f0803e698 | ||
|
|
3ddd18eb84 | ||
|
|
31ac06cfa8 | ||
|
|
1f40945218 | ||
|
|
8d38bb7669 | ||
|
|
649a2d280d | ||
|
|
d6106c0673 | ||
|
|
b93e6768c4 | ||
|
|
f80cb6c24f | ||
|
|
1c1d547e92 | ||
|
|
77a59e008b | ||
|
|
2c008bafee | ||
|
|
8e1e94e01a | ||
|
|
5323feca9b | ||
|
|
0ac709b3c8 | ||
|
|
1d72fea524 | ||
|
|
f7a96e6888 | ||
|
|
2d4007d62f | ||
|
|
e25fda8e9b | ||
|
|
faf45dc253 | ||
|
|
0c399ced95 | ||
|
|
6e2133747d | ||
|
|
f7bedcdbd8 | ||
|
|
f3cc82a780 | ||
|
|
a80f177691 | ||
|
|
63c0804e07 | ||
|
|
c369950458 | ||
|
|
b65c62e370 | ||
|
|
d46d6821fc | ||
|
|
410eeecd7f | ||
|
|
e3d7a6f464 | ||
|
|
0d9cdf7dcd | ||
|
|
52f5dbdcfa | ||
|
|
6dd96137bf | ||
|
|
020dfb00d2 | ||
|
|
fcab6f5a09 | ||
|
|
bf22fe7e6a | ||
|
|
3e0e8a1b8d | ||
|
|
104952d644 | ||
|
|
2158225795 | ||
|
|
8b796353a5 | ||
|
|
67a8d10797 | ||
|
|
c9a2aaca9c | ||
|
|
5e8de41b2e | ||
|
|
a182717d4a | ||
|
|
152c943d5a | ||
|
|
858c449489 | ||
|
|
ab438f18d9 | ||
|
|
ffef8d2417 | ||
|
|
78aab08ebd | ||
|
|
f440d8bf54 | ||
|
|
15d05d6ace | ||
|
|
f47ad55223 | ||
|
|
a80f710317 | ||
|
|
6f2581bba2 | ||
|
|
ab5e96a5ca | ||
|
|
f1aed51047 | ||
|
|
715f6ec04e | ||
|
|
65a1b64db9 | ||
|
|
3014b94111 | ||
|
|
6ed79ac5dc | ||
|
|
598529da7a | ||
|
|
88155c8cbf | ||
|
|
5a166d6a2b | ||
|
|
40f410a762 | ||
|
|
0cc4fccd7f | ||
|
|
d627aff69c | ||
|
|
18c7a910bb | ||
|
|
024a61319e | ||
|
|
867d676ef2 | ||
|
|
5bfc79ceff | ||
|
|
1617518282 | ||
|
|
71d9e14d69 | ||
|
|
831dff03db | ||
|
|
3b0ee6c3e3 | ||
|
|
3f74df0ae4 | ||
|
|
dc8c8670db | ||
|
|
eb0367bd7c | ||
|
|
73fe0e37ff | ||
|
|
16e4437032 | ||
|
|
c81a2554aa | ||
|
|
8d2de27828 | ||
|
|
9b357ec3d9 | ||
|
|
b8652ec951 | ||
|
|
94e57c6a5b | ||
|
|
5d28744758 | ||
|
|
237fb9af42 | ||
|
|
4c1acfe6dd | ||
|
|
a71da52667 | ||
|
|
12e85f66c3 | ||
|
|
c2df7a2421 | ||
|
|
e38e16bf69 | ||
|
|
78948a3f51 | ||
|
|
5148f27a01 | ||
|
|
d9c1d2f5af | ||
|
|
76f6500fd4 | ||
|
|
5e1bb70d9b | ||
|
|
c0b7f1a395 | ||
|
|
b8b88b1ba3 | ||
|
|
fdfad60c97 | ||
|
|
0b5ced7efb | ||
|
|
36215f676a | ||
|
|
dfad2e581b | ||
|
|
467e76b5b0 | ||
|
|
28d45c0270 | ||
|
|
f0bdb0fda3 | ||
|
|
505f0f97b7 | ||
|
|
62cf4f3fba | ||
|
|
1de3bf1d41 | ||
|
|
52e336ea4b | ||
|
|
9a1d92d250 | ||
|
|
71134eb29c | ||
|
|
2c43ef2c96 | ||
|
|
d06e5fa3fb | ||
|
|
630fefa3a8 | ||
|
|
5a32f4b7c5 | ||
|
|
94b8690266 | ||
|
|
45f1184696 | ||
|
|
4770364c45 | ||
|
|
8ec772c504 | ||
|
|
a736d60df5 | ||
|
|
faecb589cb | ||
|
|
131d2b4645 | ||
|
|
4c64b316db | ||
|
|
01062a16a5 | ||
|
|
52dfa8f401 | ||
|
|
3d40b14691 | ||
|
|
480a130180 | ||
|
|
a78800e036 | ||
|
|
a17220d373 | ||
|
|
ce2e6c61d2 | ||
|
|
a5994e3011 | ||
|
|
1a9e7bde1b | ||
|
|
ac81ce4335 | ||
|
|
8865f61a54 | ||
|
|
012dbeaf27 | ||
|
|
ee656527c2 | ||
|
|
10ecff6142 | ||
|
|
9e5224a661 | ||
|
|
d1ad6383d2 | ||
|
|
031408fdae | ||
|
|
29471ea6b3 | ||
|
|
9f491dce6d | ||
|
|
67cb38bd54 | ||
|
|
aa3384f28b | ||
|
|
600d14ed88 | ||
|
|
19502debea | ||
|
|
7b78a1ac69 | ||
|
|
276b62082b | ||
|
|
caea759aa9 | ||
|
|
db6456d698 | ||
|
|
e3bb44d504 | ||
|
|
4828c5ba63 | ||
|
|
b89b2a9254 | ||
|
|
6c84cab7d4 | ||
|
|
ca5457141d | ||
|
|
446472c3b1 | ||
|
|
709d362b02 | ||
|
|
54dea818f7 | ||
|
|
08d2cc389e | ||
|
|
680818a760 | ||
|
|
096f9773dc | ||
|
|
ab8b42f960 | ||
|
|
53d33f0d7a | ||
|
|
2edf1251c7 | ||
|
|
d664e166b6 | ||
|
|
9f49460ee9 | ||
|
|
508e1b74d3 | ||
|
|
5ba96000c1 | ||
|
|
0d4cd6a0be | ||
|
|
9c8f737dcd | ||
|
|
a34cd8b4ee | ||
|
|
8eec73b4be | ||
|
|
77c2841d40 | ||
|
|
00d9a8c239 | ||
|
|
4bd68ac535 | ||
|
|
38d8aebb49 | ||
|
|
fd0a362578 | ||
|
|
28aed4d11a | ||
|
|
e64ef5fae3 | ||
|
|
fbfd3644c7 | ||
|
|
e440985fb9 | ||
|
|
db668791d1 | ||
|
|
9a8b13a1cc | ||
|
|
b44a368d6d | ||
|
|
af9dc81ba4 | ||
|
|
cd3026a88a | ||
|
|
b14326e1ad | ||
|
|
9eae07fae9 | ||
|
|
cfc2ca1e24 | ||
|
|
619e8a8d30 | ||
|
|
31720be0fe | ||
|
|
395d71b705 | ||
|
|
505bf27d52 | ||
|
|
d56812f66d | ||
|
|
d9143ff271 | ||
|
|
5bb78b6468 | ||
|
|
550f0ee1f1 | ||
|
|
bf1d8482d4 | ||
|
|
1c8452ecea | ||
|
|
50fb928988 | ||
|
|
98734e8ef9 | ||
|
|
b974f4c4e9 | ||
|
|
cc6fd60168 | ||
|
|
b2c606f37f | ||
|
|
a446f45e43 | ||
|
|
db3a372e94 | ||
|
|
6f0b8806a1 | ||
|
|
b1c433e594 | ||
|
|
3a913aaaa9 | ||
|
|
3a29edff89 | ||
|
|
c59a112917 | ||
|
|
579b561d9d | ||
|
|
f4a9182ead | ||
|
|
4f014a51e4 | ||
|
|
6773f93e11 | ||
|
|
376df1cb20 | ||
|
|
fc5ad6e5e5 | ||
|
|
d497eebc01 | ||
|
|
88a3359a9e | ||
|
|
90cf72367d | ||
|
|
e5477708ad | ||
|
|
3e45348b31 | ||
|
|
c645bc3782 | ||
|
|
f3b7a979ff | ||
|
|
496020ca59 | ||
|
|
16f8333e89 | ||
|
|
2d97c204a8 | ||
|
|
1b8e7883d1 | ||
|
|
fd668ce709 | ||
|
|
2bd75c6d1f | ||
|
|
98374b513d | ||
|
|
c946126e53 | ||
|
|
22d314b87a | ||
|
|
c0f4ea859b | ||
|
|
df02d76e56 | ||
|
|
92bf2e1d69 | ||
|
|
204387237f | ||
|
|
30ae0ffc30 | ||
|
|
e4ac7a9275 | ||
|
|
57830a60d1 | ||
|
|
537327e41d | ||
|
|
ff69d6e08e | ||
|
|
317f10b5d1 | ||
|
|
cdf29f754d | ||
|
|
3776d2037d | ||
|
|
d524c5f48c | ||
|
|
7ed2660453 | ||
|
|
2e31004982 | ||
|
|
6319318773 | ||
|
|
06de96a552 | ||
|
|
a31524df09 | ||
|
|
bf11f7cc87 | ||
|
|
d1e79d1afc | ||
|
|
4a88ff342f | ||
|
|
a8af1a148b | ||
|
|
ae9be17b4d | ||
|
|
521e3b3380 | ||
|
|
1bf0529a68 | ||
|
|
8884b1b54d | ||
|
|
1ebe7332d1 | ||
|
|
84aa83d1d9 | ||
|
|
8ae40fbc9e | ||
|
|
6dddef6efa | ||
|
|
000a8e7710 | ||
|
|
48353cfa81 | ||
|
|
dc661029af | ||
|
|
d1f47f9320 | ||
|
|
1aefc633f9 | ||
|
|
20e3826316 | ||
|
|
4d27f98c1b | ||
|
|
00cd7fc700 | ||
|
|
7485e0b57a | ||
|
|
7cc6ed952e | ||
|
|
16613a1e27 | ||
|
|
6e89a180b1 | ||
|
|
5d1d406cc1 | ||
|
|
4538858561 | ||
|
|
2e58a9324f | ||
|
|
ede1cf3fbc | ||
|
|
9f0bc73372 | ||
|
|
48cc8d80e8 | ||
|
|
c69490daba | ||
|
|
0fac1646d4 | ||
|
|
9b30289b32 | ||
|
|
97f5f73730 | ||
|
|
297bdcb3a0 | ||
|
|
26ff848f9c | ||
|
|
509d23715a | ||
|
|
7a8fffadfc | ||
|
|
14123cd604 | ||
|
|
48ee318921 | ||
|
|
36b5fec504 | ||
|
|
4ad398a01e | ||
|
|
839607e1ca | ||
|
|
feda33c2c8 | ||
|
|
bf9a409a71 | ||
|
|
cce4be822c | ||
|
|
9c3b34b41e | ||
|
|
2c53286943 | ||
|
|
f21ce1f2ed | ||
|
|
2324a67da4 | ||
|
|
626d9d69c8 | ||
|
|
c6cd1b6900 | ||
|
|
835ab33fcd | ||
|
|
3b4cecabcc | ||
|
|
30112e4b21 | ||
|
|
3d5f321713 | ||
|
|
ef06f2909f | ||
|
|
0ed11fcb36 | ||
|
|
d928c43981 | ||
|
|
6950f7777e | ||
|
|
b5eddc2296 | ||
|
|
45acd496d6 | ||
|
|
6139c781d0 | ||
|
|
67e5eb5efe | ||
|
|
a41e03425b | ||
|
|
0e7b23ff4c | ||
|
|
756a86abe5 | ||
|
|
479214118e | ||
|
|
13e27496e0 | ||
|
|
111d433c8a | ||
|
|
23a456e730 | ||
|
|
c8df1533e6 | ||
|
|
2eda020373 | ||
|
|
9e5f005f05 | ||
|
|
5f71f51644 | ||
|
|
08c0507de2 | ||
|
|
9733c44ef3 | ||
|
|
7761f5d77b | ||
|
|
3d33c1d49c | ||
|
|
33c4f88636 | ||
|
|
5f900b7ab1 | ||
|
|
0602fad397 | ||
|
|
dc5d742c45 | ||
|
|
1ad2976f0d | ||
|
|
ac1c2a55e2 | ||
|
|
a6a7ede3f8 | ||
|
|
450bdc0b7f | ||
|
|
9b24827598 | ||
|
|
efec0c36bf | ||
|
|
901fcaef5e | ||
|
|
5ff1333c9f | ||
|
|
a97114b77d | ||
|
|
7f5908bcf8 | ||
|
|
60b65aad13 | ||
|
|
9672f19bc4 | ||
|
|
3e9d2dc695 | ||
|
|
01813f19f8 | ||
|
|
c3ef148ca6 | ||
|
|
58412c8179 | ||
|
|
eba7f208d5 | ||
|
|
11a8a8087f | ||
|
|
8362796339 | ||
|
|
4d43097961 | ||
|
|
0643a3dc87 | ||
|
|
cfdd951369 | ||
|
|
481d01977b | ||
|
|
dee275397a | ||
|
|
e7a50bfb91 | ||
|
|
36231f8cf3 | ||
|
|
6fc73a9a77 | ||
|
|
7b1835774d | ||
|
|
cbaa038c55 | ||
|
|
dcc64bc539 | ||
|
|
769b9e5beb | ||
|
|
1593ca5f34 | ||
|
|
e14e14ddb4 | ||
|
|
df095c63a3 | ||
|
|
e9827b8701 | ||
|
|
809f224e7d | ||
|
|
dabf821b6a | ||
|
|
babba864a1 | ||
|
|
3011f96372 | ||
|
|
2ec6534079 | ||
|
|
d82b59f173 | ||
|
|
a75d337912 | ||
|
|
4dbec073cc | ||
|
|
293e26c747 | ||
|
|
ac570b09e9 | ||
|
|
e4b934ea76 | ||
|
|
10f6606efa | ||
|
|
dc770f3c17 | ||
|
|
cbac16773d | ||
|
|
0d4c970029 | ||
|
|
79aa6c079c | ||
|
|
684f27ef87 | ||
|
|
b3cc272941 | ||
|
|
893a8d6d8d | ||
|
|
7d9de047bd | ||
|
|
83e42948ee | ||
|
|
04f9edbb39 | ||
|
|
51943050c2 | ||
|
|
89d5c98818 | ||
|
|
4b55bc4fd8 | ||
|
|
85157a8bfe | ||
|
|
3012fc52e5 | ||
|
|
55727bd1a2 | ||
|
|
d2382f437c | ||
|
|
b123cd29ca | ||
|
|
5d9b94de6b | ||
|
|
ed32e8e2b2 | ||
|
|
1b6a07b73e | ||
|
|
a493e7645d | ||
|
|
43f57637e7 | ||
|
|
270770782f | ||
|
|
d9a4305fd7 | ||
|
|
d96b3b84a2 | ||
|
|
e873ba999b | ||
|
|
ac0824ae37 | ||
|
|
400755a0e0 | ||
|
|
4a06e54f89 | ||
|
|
e20d4e492f | ||
|
|
1d521fd97e | ||
|
|
096b117e34 | ||
|
|
6f06faabc0 | ||
|
|
b3e7b9a2dd | ||
|
|
7362bf192b | ||
|
|
1c08d83704 | ||
|
|
572d776e55 | ||
|
|
bd56ca76c3 | ||
|
|
a09a023d42 | ||
|
|
65212329a7 | ||
|
|
511152be68 | ||
|
|
ffcc53408f | ||
|
|
40ddfd3ea6 | ||
|
|
7e3f490b57 | ||
|
|
95aede5c2b | ||
|
|
065bf4eb26 | ||
|
|
a870602324 | ||
|
|
9bc5b73771 | ||
|
|
68e97f81ce | ||
|
|
4b5c5ab00f | ||
|
|
670597ea5f | ||
|
|
88168d005e | ||
|
|
37db957c41 | ||
|
|
44bf03c557 | ||
|
|
801f0f0ed2 | ||
|
|
768ff5acb1 | ||
|
|
fa64bb3200 | ||
|
|
4bcb5f8e4c | ||
|
|
4fe696f18b | ||
|
|
023c2c58f1 | ||
|
|
5e8c34ad54 | ||
|
|
7ceb0e9718 | ||
|
|
4f4160c1a5 | ||
|
|
570dc9ca71 | ||
|
|
5c59a92624 | ||
|
|
469370cb42 | ||
|
|
f5505e85b2 | ||
|
|
e2c3cbe3cf | ||
|
|
1a002c9d18 | ||
|
|
d0cf90032f | ||
|
|
d8fb4fa4b0 | ||
|
|
d2c55cd685 | ||
|
|
cd4eb3d115 | ||
|
|
f97af846e6 | ||
|
|
b953ead796 | ||
|
|
d5109326f2 | ||
|
|
fd5bfe246f | ||
|
|
a2fbb7cca0 | ||
|
|
83e8f900e5 | ||
|
|
00d6b7e150 | ||
|
|
7860cdc769 | ||
|
|
ce3bb7d8ca | ||
|
|
add79b47d1 | ||
|
|
a3fcfcb6d9 | ||
|
|
d721ee374a | ||
|
|
4eec4b6977 | ||
|
|
695c7c7c44 | ||
|
|
3ccc9f5176 | ||
|
|
6d5ce06c9f | ||
|
|
4b7e9d9c75 | ||
|
|
ee88020054 | ||
|
|
08fac559c9 | ||
|
|
feee5600c4 | ||
|
|
fa96dca929 | ||
|
|
8c826a0c0d | ||
|
|
b2fa733a0d | ||
|
|
770daa330c | ||
|
|
963f2b9b78 | ||
|
|
07d7bb0834 | ||
|
|
90f4c17533 | ||
|
|
b27895e4ea | ||
|
|
d4ca66706d | ||
|
|
d7515b3084 | ||
|
|
6d09865bae | ||
|
|
6880901b4a | ||
|
|
6776f0c93d | ||
|
|
7adefd2d8d | ||
|
|
6e5634cf62 | ||
|
|
621dc6fd98 | ||
|
|
cad94cd18b | ||
|
|
64e517a02e | ||
|
|
1db49ff214 | ||
|
|
22a4160a58 | ||
|
|
4b76b5e6ae | ||
|
|
8fcfadf5a8 | ||
|
|
9e1dff071a | ||
|
|
4b1e933c76 | ||
|
|
fc688441ad | ||
|
|
0a256bde29 | ||
|
|
d5ae314dec | ||
|
|
d79b41c925 | ||
|
|
f4a638ce14 | ||
|
|
d33564ce88 | ||
|
|
e79cba72a8 | ||
|
|
56ecf9d99e | ||
|
|
37c7eed2bb | ||
|
|
2709231dfc | ||
|
|
3e12261637 | ||
|
|
770d9223af | ||
|
|
48cf4b2ff3 | ||
|
|
e252af2df4 | ||
|
|
23bec2fe96 | ||
|
|
0f39ccc7c3 | ||
|
|
046d07bbf1 | ||
|
|
70b45bcd24 | ||
|
|
39a7c26977 | ||
|
|
4e0a34966c | ||
|
|
3321b097e6 | ||
|
|
a4ddbd6605 | ||
|
|
93b8ee1750 | ||
|
|
6553f7a379 | ||
|
|
7ec84597eb | ||
|
|
4081173442 | ||
|
|
3958714bff | ||
|
|
620dfa6a29 | ||
|
|
31e1e48dea | ||
|
|
aa7daffe46 | ||
|
|
ded0c29b24 | ||
|
|
5df058415d | ||
|
|
dc2cadc6d8 | ||
|
|
ec80f5aa0e | ||
|
|
9902445ff1 | ||
|
|
c9cf0139ee | ||
|
|
5c2e3edee7 | ||
|
|
dc35f2d9dd | ||
|
|
af004146e9 | ||
|
|
0398229bca | ||
|
|
0ce5143532 | ||
|
|
18bd1fdf55 | ||
|
|
0199019ee6 | ||
|
|
d8daa1dd3d | ||
|
|
3bc9e9c5ce | ||
|
|
0d3596d237 | ||
|
|
5064c24388 | ||
|
|
e592d0e3d0 | ||
|
|
2cc48d491e | ||
|
|
295a6d0fe7 | ||
|
|
9ea9289fdf | ||
|
|
ba98736dfb | ||
|
|
00dd7ee2df | ||
|
|
2e647fb4ec | ||
|
|
801bda3560 | ||
|
|
659a62e133 | ||
|
|
0cdba79f59 | ||
|
|
f1fb23c7e7 | ||
|
|
8ea8c0086e | ||
|
|
63a1ae0c13 | ||
|
|
7c9f5d3819 | ||
|
|
e5376d144d | ||
|
|
90762b9e13 | ||
|
|
54ce5a7e16 | ||
|
|
5882fc10a9 | ||
|
|
3379a2510c | ||
|
|
9ba070da7c | ||
|
|
d47f4c5ca9 | ||
|
|
276245a395 | ||
|
|
718ac96777 | ||
|
|
a54f6f416b | ||
|
|
1ba06eeb27 | ||
|
|
21b703725b | ||
|
|
f9a00de8ee | ||
|
|
c9d0ac3e73 | ||
|
|
867a5b8d7c | ||
|
|
ed48285da5 | ||
|
|
2b62fbcc1b | ||
|
|
86e7b0a13f | ||
|
|
6fb4b9b545 | ||
|
|
7dc6cba8f2 | ||
|
|
e610d4d855 | ||
|
|
eadce9145d | ||
|
|
9711cee70a | ||
|
|
9ae591bae7 | ||
|
|
52f58727ca | ||
|
|
8d0e7e2b42 | ||
|
|
57dc5fa31a | ||
|
|
8ecc721f3c | ||
|
|
fd5920fc8d | ||
|
|
28e65a1520 | ||
|
|
ab3fc8ec7c | ||
|
|
20a798d9f1 | ||
|
|
c2ecc4adbb | ||
|
|
666ced5fea | ||
|
|
28c2323744 | ||
|
|
c0c9f755a8 | ||
|
|
2259acc3f2 | ||
|
|
05626a4759 | ||
|
|
d1ee800423 | ||
|
|
8447c87ab0 | ||
|
|
d7e22068af | ||
|
|
3976657a66 | ||
|
|
bf1473fbb1 | ||
|
|
9f211d1fda | ||
|
|
3e2931068e | ||
|
|
820b88c9cf | ||
|
|
c0215ffef3 | ||
|
|
f6a506ff92 | ||
|
|
7be573cac9 | ||
|
|
ad5c4fc332 | ||
|
|
1a8a0c3621 | ||
|
|
ab3475f512 | ||
|
|
aa416f90ec | ||
|
|
5506c0ed69 | ||
|
|
4a76a144ee | ||
|
|
d40dc681dc | ||
|
|
3514b0db89 | ||
|
|
0c0472ae3c | ||
|
|
c739d37bf5 | ||
|
|
c3e5909411 | ||
|
|
c4113c1abb | ||
|
|
90bf0f13f4 | ||
|
|
db66dff191 | ||
|
|
fb9d04a3a9 | ||
|
|
939cbd7a56 | ||
|
|
8d7e6715fa | ||
|
|
40ec1447d5 | ||
|
|
095e471f8b | ||
|
|
08e3a5aca3 | ||
|
|
77c5645ccc | ||
|
|
90affe7db1 | ||
|
|
49af6ab171 | ||
|
|
26d3c7a504 | ||
|
|
20d1a2695b | ||
|
|
6211014896 | ||
|
|
f6ba941e68 | ||
|
|
dffdc46568 | ||
|
|
0c0669fbbd | ||
|
|
66f478b36a | ||
|
|
edffd85f94 | ||
|
|
9b2eecca0e | ||
|
|
31d3d491b5 | ||
|
|
953e94cd8e | ||
|
|
9605989054 | ||
|
|
dda5ec7d13 | ||
|
|
841cd2cfaf | ||
|
|
b553263f11 | ||
|
|
7fe44b6644 | ||
|
|
d78b165322 | ||
|
|
7008b11f64 | ||
|
|
0066d29650 | ||
|
|
eda033babe | ||
|
|
40dda18f5a | ||
|
|
1ea5575fa8 | ||
|
|
2a234307a3 | ||
|
|
0bb1035261 | ||
|
|
9ff60e8a35 | ||
|
|
66aa7edbf5 | ||
|
|
e3664780e9 | ||
|
|
a87d493cb3 | ||
|
|
836bff3ea0 | ||
|
|
8528cd12ef | ||
|
|
e913be8add | ||
|
|
a575714218 | ||
|
|
656c4b0b7f | ||
|
|
a6d16911e8 | ||
|
|
6548776cb3 | ||
|
|
cb287741d0 | ||
|
|
414532db25 | ||
|
|
87519d6d08 | ||
|
|
af066bb15b | ||
|
|
5e478d749d | ||
|
|
981bcaf7d7 | ||
|
|
1640682a10 | ||
|
|
03b3bfa4e4 | ||
|
|
ffbc685752 | ||
|
|
91b163a825 | ||
|
|
aa4804cf56 | ||
|
|
795ca98b8f | ||
|
|
6ad630edf4 | ||
|
|
52ceaaf98e | ||
|
|
5d51f18c5b | ||
|
|
663cbab2c6 | ||
|
|
57839377f8 | ||
|
|
ab7776bdb9 | ||
|
|
7e0b1b6907 | ||
|
|
7bc2c0813d | ||
|
|
a1a8abceea | ||
|
|
dacacde524 | ||
|
|
233cf9b1f1 | ||
|
|
ceb7d65913 | ||
|
|
2641478216 | ||
|
|
2c3dff2a24 | ||
|
|
28a0860824 | ||
|
|
51f3416c70 | ||
|
|
2ad6a04965 | ||
|
|
16e70a0cdd | ||
|
|
d824ca30fb | ||
|
|
c7dbe7d16f | ||
|
|
8c4dc337c5 | ||
|
|
d89cfc3f1a | ||
|
|
b3c372e270 | ||
|
|
b1ac7d94ac | ||
|
|
13119773bf | ||
|
|
3ad9fe9743 | ||
|
|
e7bec65b89 | ||
|
|
03e227af4c | ||
|
|
4268e1874a | ||
|
|
17478a52ef | ||
|
|
de689727b0 | ||
|
|
18191000ea | ||
|
|
39b94d4c75 | ||
|
|
f3e1c56d5d | ||
|
|
e47ff72ec3 | ||
|
|
9d7b735ff4 | ||
|
|
d84d4cfcdb | ||
|
|
0cc14e937d | ||
|
|
7f1f551334 | ||
|
|
bf2ced4c6e | ||
|
|
231af615af | ||
|
|
4fa0efa07d | ||
|
|
83e960fe03 | ||
|
|
7eb76b4c99 | ||
|
|
89ad08a537 | ||
|
|
408c60bc15 | ||
|
|
dc198e383b | ||
|
|
593ba16c2d | ||
|
|
da82cbe8da | ||
|
|
8931759f84 | ||
|
|
093a1fa844 | ||
|
|
a8fad905a0 | ||
|
|
c768a9150b | ||
|
|
d2a0c08633 | ||
|
|
85a3041b9b | ||
|
|
cbf7f1a161 | ||
|
|
4dfade96f7 | ||
|
|
b9622ad165 | ||
|
|
e35b732d80 | ||
|
|
cde0f066ad | ||
|
|
81b8d2ae1b | ||
|
|
5b5e9af891 | ||
|
|
b8632046b7 | ||
|
|
7e0cae0590 | ||
|
|
3dda280ef8 | ||
|
|
3502ce5de7 | ||
|
|
b3c000de45 | ||
|
|
4b8fad4605 | ||
|
|
b803c1d448 | ||
|
|
e97c3a4b25 | ||
|
|
d547fdd05b | ||
|
|
c3e413c476 | ||
|
|
48141e1116 | ||
|
|
fd770b5264 | ||
|
|
065fa49cc4 | ||
|
|
2b5f9ab3b3 | ||
|
|
03690b9f1e | ||
|
|
903a491016 | ||
|
|
544e151135 | ||
|
|
b51b3bb9f3 | ||
|
|
eed90367da | ||
|
|
0b8c6692ae | ||
|
|
62f5dd1a9f | ||
|
|
6e75dd9c44 | ||
|
|
3244f20dcc | ||
|
|
9d575d6371 | ||
|
|
20e9157d01 | ||
|
|
d5b4553c90 | ||
|
|
3c4be73678 | ||
|
|
3cd766468d | ||
|
|
02e7066749 | ||
|
|
52fbb45df4 | ||
|
|
367039f8b1 | ||
|
|
ad336cdd9f | ||
|
|
70ea4c2314 | ||
|
|
2f7a91d785 | ||
|
|
d1a6651fa5 | ||
|
|
228bfffba1 | ||
|
|
3b3b5efafe | ||
|
|
7129b9737c | ||
|
|
ac09ee3773 | ||
|
|
529e546600 | ||
|
|
a42c42f335 | ||
|
|
6f4577d7b2 | ||
|
|
1538171d31 | ||
|
|
31853c5586 | ||
|
|
326a4eda2f | ||
|
|
2364d0505b | ||
|
|
6e58e2bb33 | ||
|
|
e36fbd87d8 | ||
|
|
10cb3e1cb3 | ||
|
|
1048e3d181 | ||
|
|
8784b1224b | ||
|
|
a320b3cc39 | ||
|
|
fe6d00b6e1 | ||
|
|
a4a1100abe | ||
|
|
a1f98902a5 | ||
|
|
6b7eb1cf3e | ||
|
|
b63ffa490b | ||
|
|
2a3b61aada | ||
|
|
6d8652f393 | ||
|
|
f4c25576bc | ||
|
|
0a38435a2d | ||
|
|
87308a3c21 | ||
|
|
92d01dcbd3 | ||
|
|
c657dabcda | ||
|
|
37a3661698 | ||
|
|
ed5f5bd169 | ||
|
|
68a69c7531 | ||
|
|
60d0a6cae4 | ||
|
|
909bfc4a30 | ||
|
|
c6e3aebc48 | ||
|
|
ed6b678b5f | ||
|
|
f5a06f8e69 | ||
|
|
4658db9c21 | ||
|
|
18c34ce29d | ||
|
|
bae2baf3f5 | ||
|
|
5895a6685a | ||
|
|
36b51b64b1 | ||
|
|
3d6dcbd181 | ||
|
|
68ccb13a72 | ||
|
|
5149511aaa | ||
|
|
f3d4b86bae | ||
|
|
22dce2fdf1 | ||
|
|
c54e16c3b4 | ||
|
|
5b2da28edd | ||
|
|
d152d9f3af | ||
|
|
b7014a6b21 | ||
|
|
04346aa4b8 | ||
|
|
d73071b38e | ||
|
|
58bd26966d | ||
|
|
79dd5a2f42 | ||
|
|
f1b502b2f2 | ||
|
|
38f90b400d | ||
|
|
94b79fcd09 | ||
|
|
e67e830946 | ||
|
|
2de2fc00fc | ||
|
|
81b153ccd5 | ||
|
|
716cbfa090 | ||
|
|
1c4944b166 | ||
|
|
eba5645281 | ||
|
|
01fb6feeca | ||
|
|
0b8666629b | ||
|
|
c86525e383 | ||
|
|
0c8daca856 | ||
|
|
7d0a18861b | ||
|
|
f181ca044d | ||
|
|
f54ed82496 | ||
|
|
ccc6112714 | ||
|
|
7c363ff4ef | ||
|
|
4e55911213 | ||
|
|
52a9e37729 | ||
|
|
1886b160b9 | ||
|
|
94a4844616 | ||
|
|
d82f8c44d1 | ||
|
|
e878f438fd | ||
|
|
658a666f15 | ||
|
|
ed1f74baca | ||
|
|
9e4b80e25b | ||
|
|
9fe0a39321 | ||
|
|
df193261b3 | ||
|
|
52395af0ce | ||
|
|
8f59babaad | ||
|
|
85cc7c017f | ||
|
|
e8b09b3f03 | ||
|
|
887612ddf9 | ||
|
|
547eb06725 | ||
|
|
b5a7f41a8e | ||
|
|
b0dfeca98b | ||
|
|
3074e2f530 | ||
|
|
b0013b9304 | ||
|
|
2de7d8931a | ||
|
|
7b5412ff36 | ||
|
|
596cb2afd6 | ||
|
|
cda9f99f9e | ||
|
|
07d760d7d8 | ||
|
|
014b7ac201 | ||
|
|
4c60fbde5d | ||
|
|
88585418f8 | ||
|
|
acb6337503 | ||
|
|
114a8a3ac1 | ||
|
|
afefe1d66c | ||
|
|
a2802f124d | ||
|
|
e953d9dcbb | ||
|
|
4d178a225d | ||
|
|
7f76864f41 | ||
|
|
6cebc644c2 | ||
|
|
2c41c57a13 | ||
|
|
8b9875a771 | ||
|
|
378e071232 | ||
|
|
bfd8184648 | ||
|
|
e851c7967a | ||
|
|
29bc0c1fda | ||
|
|
268d844b43 | ||
|
|
ab141b84df | ||
|
|
dd94898b19 | ||
|
|
88d89c206d | ||
|
|
1f701a84e4 | ||
|
|
ffc00a6beb | ||
|
|
aabbb5c254 | ||
|
|
9f2fd0e2ec | ||
|
|
05489891f7 | ||
|
|
c953d02604 | ||
|
|
f5333e7c8d | ||
|
|
752f4e8760 | ||
|
|
b5ae39836c | ||
|
|
8b848cc05a | ||
|
|
ee13f8d084 | ||
|
|
29ec098798 | ||
|
|
62878f29e0 | ||
|
|
0483e44ddc | ||
|
|
d954b4df1d | ||
|
|
66044f8b4a | ||
|
|
6847e1b6db | ||
|
|
aa162b6601 | ||
|
|
26cb15fe21 | ||
|
|
37e03e2e9e | ||
|
|
6aee48fc08 | ||
|
|
09dd448b40 | ||
|
|
a846bcf633 | ||
|
|
bbad479580 | ||
|
|
7c01cadb2f | ||
|
|
58a90d595f | ||
|
|
cfc73b1183 | ||
|
|
28e84443d8 | ||
|
|
c03566336a | ||
|
|
9e87300567 | ||
|
|
7259c668c4 | ||
|
|
5d6a56d95c | ||
|
|
6ee9288cb0 | ||
|
|
fdf14b2a1f | ||
|
|
0b88f3b30b | ||
|
|
7601e62504 | ||
|
|
78e1ac7572 | ||
|
|
d879cc6114 | ||
|
|
00b4817bc7 | ||
|
|
a5688a7c3b | ||
|
|
5c882bdbb2 | ||
|
|
3fd1dfe87a | ||
|
|
3213aa168f | ||
|
|
b855389965 | ||
|
|
d7f679428d | ||
|
|
d6e10dddd6 | ||
|
|
6e37e1ded6 | ||
|
|
e79a0015f9 | ||
|
|
8e3919ae09 | ||
|
|
7f1766ba94 | ||
|
|
efd8273901 | ||
|
|
18b7df494e | ||
|
|
c26d13484f | ||
|
|
99682a11d1 | ||
|
|
410654cb19 | ||
|
|
bb4c6fe83b | ||
|
|
310fa41bc2 | ||
|
|
c6f7b03700 | ||
|
|
bdcf9d8e93 | ||
|
|
1249d069c7 | ||
|
|
0e2b8df36b | ||
|
|
1326f825d3 | ||
|
|
2a38d713b8 | ||
|
|
7372ccfe11 | ||
|
|
919f4cb39c | ||
|
|
e7b0e7bdde | ||
|
|
977f28c30c | ||
|
|
b59b6a0cfb | ||
|
|
652e7a82af | ||
|
|
98e7615c5b | ||
|
|
72aa0375b7 | ||
|
|
092967004a | ||
|
|
3cc572a1cd | ||
|
|
c9bdac8d33 | ||
|
|
62a1d2d7ec | ||
|
|
c1b6fbf11a | ||
|
|
a548710a55 | ||
|
|
510067a714 | ||
|
|
ffb4f3179d | ||
|
|
dde99fa150 | ||
|
|
10b62bc7fb | ||
|
|
d7af33f579 | ||
|
|
3a615b6e06 | ||
|
|
da5dc944e7 | ||
|
|
923df99443 | ||
|
|
72c5bd237b | ||
|
|
c18f09d344 | ||
|
|
470e946ec2 | ||
|
|
050a2e60df | ||
|
|
7e306054a7 | ||
|
|
0c4103ce34 | ||
|
|
c01c59e2e5 | ||
|
|
a65315c537 | ||
|
|
df27dcf878 | ||
|
|
43b613c210 | ||
|
|
ee4215f89e | ||
|
|
0cfd663275 | ||
|
|
9905a1ed75 | ||
|
|
d2bf22994d | ||
|
|
e70cadf5dd | ||
|
|
caf35ad868 | ||
|
|
3ac9bcafc7 | ||
|
|
d95943a365 | ||
|
|
3853f0010f | ||
|
|
e5326430cb | ||
|
|
322bef00a2 | ||
|
|
858b9b4b38 | ||
|
|
132f146a9f | ||
|
|
469270882c | ||
|
|
b05a7f2ba5 | ||
|
|
5bdf7868d5 | ||
|
|
390a653b94 | ||
|
|
4fe435f450 | ||
|
|
0a8261fdcb | ||
|
|
012d4d9f8d | ||
|
|
e9c029e8fc | ||
|
|
6e9b840e45 | ||
|
|
ff3dd800e4 | ||
|
|
35594e23f9 | ||
|
|
fea676c1d4 | ||
|
|
8d7c8a0bdf | ||
|
|
293091d13d | ||
|
|
ce3c2d4f80 | ||
|
|
e102f5d6bc | ||
|
|
32241d1403 | ||
|
|
37fb2e2c47 | ||
|
|
7f28008d5d | ||
|
|
f6786406ef | ||
|
|
6006dd3944 | ||
|
|
9aadb7f471 | ||
|
|
4b1b702fc5 | ||
|
|
63920fdce8 | ||
|
|
08e9f14e9d | ||
|
|
6b8b099339 | ||
|
|
b03fcc5b6a | ||
|
|
7fc7ffd708 | ||
|
|
fa5721c2cb | ||
|
|
4c794381e6 | ||
|
|
283c51b193 | ||
|
|
d7403d3745 | ||
|
|
a761b0b417 | ||
|
|
8988bc0098 | ||
|
|
a18b3c6879 | ||
|
|
bfbd845bab | ||
|
|
50919f40c1 | ||
|
|
1a03adebbd | ||
|
|
2c775b560f | ||
|
|
b1bd666386 | ||
|
|
e0f7c16a10 | ||
|
|
7467df155d | ||
|
|
cafdd457c8 | ||
|
|
0239edd4ee | ||
|
|
c55b595ae9 | ||
|
|
e1fdfdbef6 | ||
|
|
89b0861f9e | ||
|
|
455014b2c1 | ||
|
|
38740e3a8b | ||
|
|
784505ce4c | ||
|
|
be16e7edce | ||
|
|
4aaf7f78e8 | ||
|
|
b310d3065d | ||
|
|
c1727652a8 | ||
|
|
7dfbad5451 | ||
|
|
05cf0b83f4 | ||
|
|
7f1dc2dfe1 | ||
|
|
e58f0888b5 | ||
|
|
c785906ffb | ||
|
|
27a323a38f | ||
|
|
602903de46 | ||
|
|
e74a9a4295 | ||
|
|
2b91fb06bc | ||
|
|
89811361bb | ||
|
|
42c050588b | ||
|
|
f6aded2428 | ||
|
|
7d82b73208 | ||
|
|
7401330e81 | ||
|
|
211a3bc6bc | ||
|
|
eb82f8cc19 | ||
|
|
94cf017102 | ||
|
|
efa316dbf8 | ||
|
|
247f27fa54 | ||
|
|
a7ea074328 | ||
|
|
b90d1a6be5 | ||
|
|
0d5f7a607a | ||
|
|
c98ff36977 | ||
|
|
b07cd2d442 | ||
|
|
40956e9501 | ||
|
|
f4648a7023 | ||
|
|
cf3dba89e0 | ||
|
|
ec4712b5bf | ||
|
|
99a83c0d97 | ||
|
|
475239e1ba | ||
|
|
d200070c16 | ||
|
|
2077cd6bcb | ||
|
|
86530371f4 | ||
|
|
69e1bb66ad | ||
|
|
761247fe0d | ||
|
|
bbcff75b00 | ||
|
|
8c63cc607b | ||
|
|
b814b07e2a | ||
|
|
27247438f5 | ||
|
|
c6d69bdb75 | ||
|
|
b1fa737b56 | ||
|
|
4108cf1696 | ||
|
|
3c05f5f5cb | ||
|
|
e280a6afa9 | ||
|
|
c1e38ec059 | ||
|
|
4191a8feb7 | ||
|
|
db22c3f348 | ||
|
|
c63f994a5f | ||
|
|
39bebbdcf6 | ||
|
|
6513642efb | ||
|
|
825c4378a0 | ||
|
|
16342981eb | ||
|
|
17b72a9d0c | ||
|
|
e6e14fb37a | ||
|
|
f3b5af1c43 | ||
|
|
4baa37b2d9 | ||
|
|
d3c7ef3088 | ||
|
|
b769ae3805 | ||
|
|
9a675bafb4 | ||
|
|
1c281b98e8 | ||
|
|
5e93bea2fd | ||
|
|
14d2a7263b | ||
|
|
eefdfb676a | ||
|
|
600cd490a4 | ||
|
|
24624f6136 | ||
|
|
56e7f567c7 | ||
|
|
3fee35fd3a | ||
|
|
e0ac6e0349 | ||
|
|
c12eed91b3 | ||
|
|
520a783407 | ||
|
|
ba4a6558b4 | ||
|
|
e562ad14cd | ||
|
|
9d2ed9dc97 | ||
|
|
f6d3e9785f | ||
|
|
c09146796f | ||
|
|
b832ace635 | ||
|
|
d0662a6132 | ||
|
|
ba621af162 | ||
|
|
32da91d145 | ||
|
|
66e6cec446 | ||
|
|
7a721ee84f | ||
|
|
2d2ebdc887 | ||
|
|
47f43a47ba | ||
|
|
95cdf17527 | ||
|
|
e49f675cfc | ||
|
|
05f1919e3c | ||
|
|
8375b66cbe | ||
|
|
d659627959 | ||
|
|
b27b8ba7fd | ||
|
|
5584cedce3 | ||
|
|
fae159a5f3 | ||
|
|
95ebfe1657 | ||
|
|
72535081d6 | ||
|
|
fbb91c9c30 | ||
|
|
9f0e5c4f3e | ||
|
|
b5f8e9efcc | ||
|
|
8b1b9fdb2a | ||
|
|
7d8f4f54c0 | ||
|
|
c6d26ec3fa | ||
|
|
e49c9e1c98 | ||
|
|
e21e897468 | ||
|
|
6cb5dec1a9 | ||
|
|
662d9d0d85 | ||
|
|
2c498613b6 | ||
|
|
7db1703477 | ||
|
|
c5a67874cf | ||
|
|
a8f5892562 | ||
|
|
718762d284 | ||
|
|
a560035482 | ||
|
|
106f849e82 | ||
|
|
3ddd24c7cd | ||
|
|
87bbb6bf44 | ||
|
|
1df09242a0 | ||
|
|
ba338191cb | ||
|
|
ca76b64ba8 | ||
|
|
20f2d68e05 | ||
|
|
10a8b14eff | ||
|
|
42bb8b4bf6 | ||
|
|
d05962c58b | ||
|
|
4e79899323 | ||
|
|
86ba717c83 | ||
|
|
44bc96835a | ||
|
|
c2446c48f5 | ||
|
|
e5016cf4f1 | ||
|
|
e8ec31e293 | ||
|
|
408cd5a3eb | ||
|
|
f9d2d9dc48 | ||
|
|
94dbc6b240 | ||
|
|
2bc839918a | ||
|
|
ef4b6578cc | ||
|
|
9ac66febee | ||
|
|
e10b6974ae | ||
|
|
ba5a73df45 | ||
|
|
cc387a1f52 | ||
|
|
04cb20a814 | ||
|
|
d3c12a84fd | ||
|
|
8592554ad7 | ||
|
|
622c6e134e | ||
|
|
bf2ebc561c | ||
|
|
3d1e6eede0 | ||
|
|
2cc90ccbaf | ||
|
|
500bbb552b | ||
|
|
489654c622 | ||
|
|
bbc6376bcf | ||
|
|
7597cb1c74 | ||
|
|
efc11d4236 | ||
|
|
35e6625601 | ||
|
|
42de7bb0c9 | ||
|
|
f5dc479714 | ||
|
|
70db94f83c | ||
|
|
736b916286 | ||
|
|
1c7bc39c80 | ||
|
|
7710f8e307 | ||
|
|
8f851e1a3a | ||
|
|
9d1f3b867f | ||
|
|
b869c4253c | ||
|
|
919543bf82 | ||
|
|
94c3ba51d1 | ||
|
|
1989657c9a | ||
|
|
88d7f252b6 | ||
|
|
3e777f987d | ||
|
|
9746c85ce5 | ||
|
|
7937f73031 | ||
|
|
be9f987342 | ||
|
|
b8e3e2d092 | ||
|
|
20c3ddfd1e | ||
|
|
4219559450 | ||
|
|
e932c3efd5 | ||
|
|
e3002fce0b | ||
|
|
d3eefc41bc | ||
|
|
df63e1bb7e | ||
|
|
159aa09636 | ||
|
|
19d4d84e58 | ||
|
|
556626501c | ||
|
|
839b5f72f6 | ||
|
|
5c558601c7 | ||
|
|
10f01c0fc6 | ||
|
|
da616fd4ed | ||
|
|
7bb3726f5b | ||
|
|
42ac18d962 | ||
|
|
6ba36e2cae | ||
|
|
86b1a562c1 | ||
|
|
40e97f7363 | ||
|
|
167e21abf7 | ||
|
|
93f3153903 | ||
|
|
2fee305eb2 | ||
|
|
813b265f6c | ||
|
|
42c20082eb | ||
|
|
1fb6305380 | ||
|
|
75ce06c128 | ||
|
|
f768ad63f0 | ||
|
|
e272d26f30 | ||
|
|
a1ccc60729 | ||
|
|
3249a8f889 | ||
|
|
926087a448 | ||
|
|
bf25274fc0 | ||
|
|
89334c25d6 | ||
|
|
bdee3da08e | ||
|
|
10dfc4d7b8 | ||
|
|
bdd0dd6582 | ||
|
|
84a65f0f32 | ||
|
|
2418675822 | ||
|
|
d64747ddef | ||
|
|
4d6ce5114a | ||
|
|
9604a4548d | ||
|
|
c92a6fb413 | ||
|
|
b646e4f9cf | ||
|
|
2a45854818 | ||
|
|
a8fd2da7ea | ||
|
|
d4e6732eeb | ||
|
|
169204173f | ||
|
|
8b9d4b98d5 | ||
|
|
58e52856b2 | ||
|
|
3fbfadeebd | ||
|
|
34ce80eb3d | ||
|
|
c8121afed1 | ||
|
|
a2bde8fd6b | ||
|
|
2d199cae8d | ||
|
|
cf6f8b952d | ||
|
|
3e45e8cb10 | ||
|
|
b6907c6bc2 | ||
|
|
38e75cf422 | ||
|
|
879ecea1e5 | ||
|
|
3112078041 | ||
|
|
74f9a0209b | ||
|
|
224172f785 | ||
|
|
c56d026679 | ||
|
|
f2ffca8096 | ||
|
|
9a20306399 | ||
|
|
b90c9a379a | ||
|
|
bf7a63bf5a | ||
|
|
504cfe6d3e | ||
|
|
4fa95bcd48 | ||
|
|
8126d6d3fe | ||
|
|
d9d5c98c5f | ||
|
|
4266e426db | ||
|
|
dc2edaca25 | ||
|
|
861776f9f0 | ||
|
|
20f5bd6489 | ||
|
|
8916c83a8e | ||
|
|
17c9556337 | ||
|
|
c4401a45df | ||
|
|
2e19ad3dcb | ||
|
|
40b84b89bd | ||
|
|
0cc0d0795e | ||
|
|
889c82652b | ||
|
|
073bdf24bb | ||
|
|
eebb3e996d | ||
|
|
739b6fb9a9 | ||
|
|
f397558f75 | ||
|
|
31fd01cc71 | ||
|
|
eb2f3c7148 | ||
|
|
71e0fd36ad | ||
|
|
a87ae68c24 | ||
|
|
8165ee4776 | ||
|
|
eef3b28270 | ||
|
|
148088f42a | ||
|
|
71e7d6f3e6 | ||
|
|
43016dcbc1 | ||
|
|
d2e959e32e | ||
|
|
229b7e874f | ||
|
|
dac9c7b37f | ||
|
|
83dcd9da7b | ||
|
|
b3ec207213 | ||
|
|
9f79586017 | ||
|
|
0fb14d4c6a | ||
|
|
624a96ddde | ||
|
|
138a6ce408 | ||
|
|
3c6bd6bf6f | ||
|
|
1cf7516cc3 | ||
|
|
45fd0bf934 | ||
|
|
5adaf41288 | ||
|
|
6097b7b9a9 | ||
|
|
f7e6a25a50 | ||
|
|
dd1310871f | ||
|
|
d5360b9342 | ||
|
|
13c3e15b4f | ||
|
|
8410ca9273 | ||
|
|
76e8d25f87 | ||
|
|
0434caa89a | ||
|
|
8a50145932 | ||
|
|
53296bb330 | ||
|
|
b717e0bafd | ||
|
|
5f76b170b5 | ||
|
|
e384966172 | ||
|
|
b49790f48a | ||
|
|
9eb10d06b8 | ||
|
|
65ec97c2ac | ||
|
|
4230df3c88 | ||
|
|
420586ea0a | ||
|
|
e68a7b82b3 | ||
|
|
b5b9a5eac3 | ||
|
|
b8b1996fb4 | ||
|
|
2bc217b156 | ||
|
|
5e5951880f | ||
|
|
7f9f118fba | ||
|
|
4d7f228a4c | ||
|
|
825ef2898b | ||
|
|
303a114178 | ||
|
|
3922d1706a | ||
|
|
d064d24903 | ||
|
|
a8c8dbf535 | ||
|
|
cb059d53eb | ||
|
|
97d471bce1 | ||
|
|
1544912dbc | ||
|
|
21b053cd0d | ||
|
|
50a837a05d | ||
|
|
95b332586c | ||
|
|
86d775ff84 | ||
|
|
de793abb7b | ||
|
|
21c1d1b7b9 | ||
|
|
4fe01ebbfd | ||
|
|
a32a5c929a | ||
|
|
62695fba33 | ||
|
|
44dbf74c57 | ||
|
|
6ab00875a9 | ||
|
|
b7a6bb2201 | ||
|
|
e7b307f6fd | ||
|
|
1b0a972cdd | ||
|
|
d159432181 | ||
|
|
20476876ac | ||
|
|
6380e028fa | ||
|
|
38f02a149e | ||
|
|
979b15a8fa | ||
|
|
8a4948085a | ||
|
|
51ca23085a | ||
|
|
99e52d68f4 | ||
|
|
6b2d4a4b75 | ||
|
|
f87a3ce570 | ||
|
|
ad95fdecd9 | ||
|
|
44bd7fda79 | ||
|
|
6930202349 | ||
|
|
92ab26d547 | ||
|
|
35d7a70ade | ||
|
|
b4e2224c3e | ||
|
|
281c4baeb3 | ||
|
|
e97b94d393 | ||
|
|
c6121ff201 | ||
|
|
1d01338e49 | ||
|
|
8a47cdd1da | ||
|
|
0d3ff8a2d4 | ||
|
|
7e3535ad1a | ||
|
|
088a146888 | ||
|
|
bc6f641eb3 | ||
|
|
d63b36f3bf | ||
|
|
e1926ed217 | ||
|
|
823e7bf76e | ||
|
|
cc685141e9 | ||
|
|
b28153d8f9 | ||
|
|
d0ef7f4238 | ||
|
|
35c8e57633 | ||
|
|
037646537b | ||
|
|
20c0abf69d | ||
|
|
358b0701a4 | ||
|
|
a18fd1d5c9 | ||
|
|
24c7c0a076 | ||
|
|
531cfbea29 | ||
|
|
aee1ff2fcb | ||
|
|
c137d28da5 | ||
|
|
e22f0e2065 | ||
|
|
8a08cc3bff | ||
|
|
ea4d3d782c | ||
|
|
ae1bbffc64 | ||
|
|
9999f6d57c | ||
|
|
c14aaf02a6 | ||
|
|
dccb4c476a | ||
|
|
7ed8801f46 | ||
|
|
ae3c5faef5 | ||
|
|
5912354f09 | ||
|
|
4590a14de1 | ||
|
|
6ad8c5a10f | ||
|
|
8d8f3e51fb | ||
|
|
8c77b0734c | ||
|
|
2188babab8 | ||
|
|
4e2313d387 | ||
|
|
4f70b6822b | ||
|
|
9a44f8439e | ||
|
|
f8adb0cecf | ||
|
|
fcfce2d68d | ||
|
|
28dc4d32ad | ||
|
|
b30aee4314 | ||
|
|
8723151361 | ||
|
|
7e24402671 | ||
|
|
caf1501c89 | ||
|
|
94682fb0ff | ||
|
|
b80cb91d54 | ||
|
|
76beca23c6 | ||
|
|
e96e94d471 | ||
|
|
64470891ba | ||
|
|
a3e0f6eb7d | ||
|
|
0dba3d5300 | ||
|
|
46b36ba7e5 | ||
|
|
46602c744b | ||
|
|
e527a6d176 | ||
|
|
23e3011d82 | ||
|
|
4c15aa7c49 | ||
|
|
e22ca653ed | ||
|
|
d2b2bd0226 | ||
|
|
daa4066c04 | ||
|
|
bb25509fd6 | ||
|
|
f7118a6ac3 | ||
|
|
1a35ef9cc3 | ||
|
|
ece56944d8 | ||
|
|
5bdc6fe3cc | ||
|
|
795eb1e028 | ||
|
|
6278dd8df3 | ||
|
|
0511d06d63 | ||
|
|
7a84ffee5e | ||
|
|
cdf78c0f4c | ||
|
|
41fa410010 | ||
|
|
50cf128471 | ||
|
|
4ea8b141da | ||
|
|
3654906e9a | ||
|
|
fb73b9c922 | ||
|
|
be8be01ed5 | ||
|
|
130c894a35 | ||
|
|
9786a51822 | ||
|
|
5224cbb9c6 | ||
|
|
0a87820f9a | ||
|
|
2caa65add6 | ||
|
|
3a0d9526f7 | ||
|
|
cac1387d24 | ||
|
|
e3bc75da15 | ||
|
|
ba23fa9073 | ||
|
|
8722b87727 | ||
|
|
c86616b971 | ||
|
|
552c3b4d98 | ||
|
|
688244c87b | ||
|
|
ce905f3144 | ||
|
|
b2b3975b70 | ||
|
|
8139bebb6a | ||
|
|
263ec73451 | ||
|
|
7d50c6e69d | ||
|
|
8b04957820 | ||
|
|
5f54964d69 | ||
|
|
267734e866 | ||
|
|
9fec5fd1c0 | ||
|
|
50490ce808 | ||
|
|
cc1c4081bc | ||
|
|
ced19968aa | ||
|
|
5a43b8f9f4 | ||
|
|
fe8e1d2b52 | ||
|
|
f5db1b66cb | ||
|
|
50a39d439a | ||
|
|
6deefda545 | ||
|
|
3e05cfe24f | ||
|
|
353be72dc9 | ||
|
|
50cfb869e2 | ||
|
|
a693233150 | ||
|
|
c7836aabfe | ||
|
|
8d5e6d9d14 | ||
|
|
c947f92a73 | ||
|
|
8b1effc2f3 | ||
|
|
e72e7f3f15 | ||
|
|
3ed43f3f09 | ||
|
|
14b30ce48f | ||
|
|
f2b091cb83 | ||
|
|
ba47fededd | ||
|
|
84e010bdf7 | ||
|
|
2fa5946bc5 | ||
|
|
f2c239f67c | ||
|
|
59786c7bb0 | ||
|
|
1cd5622ca0 | ||
|
|
b8fc40f60f | ||
|
|
d8e0ba840d | ||
|
|
66da520835 | ||
|
|
19793e41b9 | ||
|
|
00ed4c5743 | ||
|
|
c3f9abea0e | ||
|
|
4dcd92b528 | ||
|
|
601f32fc00 | ||
|
|
a7a9bc72a2 | ||
|
|
4a85977874 | ||
|
|
361b63256f | ||
|
|
7bd77ba43e | ||
|
|
c5435e0a27 | ||
|
|
3f6420a6d4 | ||
|
|
d317388d18 | ||
|
|
5139efd4d7 | ||
|
|
f859b48a57 | ||
|
|
4e32ce086e | ||
|
|
aca3db06c2 | ||
|
|
4bd2a9f766 | ||
|
|
51d0078e26 | ||
|
|
1578b12cf9 | ||
|
|
64c0b37726 | ||
|
|
535012f844 | ||
|
|
85ac4314f5 | ||
|
|
1f9aa108a4 | ||
|
|
8e606dac8b | ||
|
|
04eadaad67 | ||
|
|
dcc3d9e74c | ||
|
|
4770608d8f | ||
|
|
82ac006a13 | ||
|
|
06346b956c | ||
|
|
795f03f8b8 | ||
|
|
304a5d804e | ||
|
|
1175f6f9c5 | ||
|
|
e4bc8d2180 | ||
|
|
a3df77e713 | ||
|
|
0909d43bcf | ||
|
|
31017fee9d | ||
|
|
6826e69795 | ||
|
|
bd3fbd5cf7 | ||
|
|
1fe2b3bdc2 | ||
|
|
f84c8eedd2 | ||
|
|
42e168a1fc | ||
|
|
51fa5d18e6 | ||
|
|
8985748f8a | ||
|
|
e089cc898c | ||
|
|
c987412482 | ||
|
|
bae1386c58 | ||
|
|
839ae0b1df | ||
|
|
e6966ae841 | ||
|
|
8f7a84e495 | ||
|
|
a8d615071e | ||
|
|
b19f306bbf | ||
|
|
677534c8ec | ||
|
|
ce57466695 | ||
|
|
a213a6a0cd | ||
|
|
920d850915 | ||
|
|
2a727b6204 | ||
|
|
5f610c4049 | ||
|
|
8d1dc66c59 | ||
|
|
206983cffd | ||
|
|
21c7068341 | ||
|
|
b3426ec6eb | ||
|
|
7099dc6d73 | ||
|
|
3b18b4398c | ||
|
|
72ce140895 | ||
|
|
fcd4b23710 | ||
|
|
489f464163 | ||
|
|
2721a43dde | ||
|
|
724dfd45e6 | ||
|
|
e759b44d37 | ||
|
|
fb95d8f5ed | ||
|
|
3d76792239 | ||
|
|
49be0485c5 | ||
|
|
ee7180ccd3 | ||
|
|
4c3e45ee02 | ||
|
|
480aca1c80 | ||
|
|
3dc3b6f0d2 | ||
|
|
f41210f2d7 | ||
|
|
91db603a89 | ||
|
|
7b251fb419 | ||
|
|
0e5e09dbbf | ||
|
|
d4e28ec735 | ||
|
|
aa836a8954 | ||
|
|
bd7868cfc7 | ||
|
|
314906adf3 | ||
|
|
067890345e | ||
|
|
3907431369 | ||
|
|
179af06438 | ||
|
|
ee613233db | ||
|
|
01c03f33f9 | ||
|
|
bc608eff07 | ||
|
|
6c7648b75a | ||
|
|
db8b5cc033 | ||
|
|
d62d6f5662 | ||
|
|
14f600da35 | ||
|
|
2a5a2cd61d | ||
|
|
2da2f0af9a | ||
|
|
3b8d7a5271 | ||
|
|
468b146a64 | ||
|
|
d81f946446 | ||
|
|
097aae895f | ||
|
|
ad41fd2571 | ||
|
|
f71ea7eddc | ||
|
|
860f9b0854 | ||
|
|
3bd4605c1f | ||
|
|
5863d962ac | ||
|
|
569fa62737 | ||
|
|
65a1ba9102 | ||
|
|
9e09e5db5a | ||
|
|
6b95229ff7 | ||
|
|
6ae70ce7f6 | ||
|
|
4a5d084ddd | ||
|
|
502e9b6271 | ||
|
|
ffc709c557 | ||
|
|
52b64822c5 | ||
|
|
20e7b873a5 | ||
|
|
7d88617964 | ||
|
|
574cc53075 | ||
|
|
3e4e27f236 | ||
|
|
f7b2d5b6d6 | ||
|
|
eee4e2f0eb | ||
|
|
0fc1806ca4 | ||
|
|
5351bd9596 | ||
|
|
348d40ad22 | ||
|
|
10cbf3b3b3 | ||
|
|
1f77a749be | ||
|
|
3d0e970760 | ||
|
|
a55662ea1b | ||
|
|
d04e65108d | ||
|
|
f33f7ab41a | ||
|
|
c22b22f49a | ||
|
|
19c195a357 | ||
|
|
ecf8f311d9 | ||
|
|
14d79338de | ||
|
|
5dc4bf258b | ||
|
|
a30b3b9505 | ||
|
|
f78e02e7e8 | ||
|
|
50ef190ae7 | ||
|
|
031129a31c | ||
|
|
dc66a5959d | ||
|
|
7ba956d760 | ||
|
|
15bedc303e | ||
|
|
8d35bb6a9b | ||
|
|
ddfea8f3cb | ||
|
|
fd92628c30 | ||
|
|
37f9771b97 | ||
|
|
42b5162ca4 | ||
|
|
b0edf297a2 | ||
|
|
e8b99cea70 | ||
|
|
fcbb5f68fe | ||
|
|
6be0d179fc | ||
|
|
d54172d366 | ||
|
|
ab35650f0b | ||
|
|
850bb05481 | ||
|
|
7826d487cc | ||
|
|
07053ca7e9 | ||
|
|
022490e461 | ||
|
|
397c5ee9d8 | ||
|
|
8c0377aa39 | ||
|
|
b7de0f61c7 | ||
|
|
e97de9c6df | ||
|
|
58413e5218 | ||
|
|
4c6eb18528 | ||
|
|
92c24739bf | ||
|
|
263d4b7caf | ||
|
|
9aa2637a71 | ||
|
|
ad1d9f556f | ||
|
|
f53413006b | ||
|
|
de79e6c496 | ||
|
|
7e30ec4459 | ||
|
|
d8b42af4b1 | ||
|
|
aa49c5b0b1 | ||
|
|
1b0eb64698 | ||
|
|
3ef5dbd2ae | ||
|
|
ec244587eb | ||
|
|
0ba67b2634 | ||
|
|
a20c6f23e2 | ||
|
|
1bc65c0eef | ||
|
|
4c907dbf9e | ||
|
|
92f66f4b4a | ||
|
|
70e504ecef | ||
|
|
eeff55eb7d | ||
|
|
c4f7223293 | ||
|
|
e8456dec57 | ||
|
|
06c89b0cc5 | ||
|
|
cca8221f28 | ||
|
|
c8d7bdca8b | ||
|
|
e1f8a1abbb | ||
|
|
51a06c4ab6 | ||
|
|
16abca2913 | ||
|
|
6c74206544 | ||
|
|
68a695d58c | ||
|
|
972b8972be | ||
|
|
ed32bcfb70 | ||
|
|
91086c594e | ||
|
|
215380b806 | ||
|
|
170f70d005 | ||
|
|
55ccf3e987 | ||
|
|
0d4a2164f3 | ||
|
|
46bbf2234a | ||
|
|
3478d4e86c | ||
|
|
c7f5f77925 | ||
|
|
8a3aebf3cc | ||
|
|
f1ed611aa9 | ||
|
|
7fcfe644da | ||
|
|
6c7ff86a09 | ||
|
|
3d4f64a4e6 | ||
|
|
0c6515b4c7 | ||
|
|
de8726cccf | ||
|
|
0c48b342a5 | ||
|
|
d653c516ea | ||
|
|
30ccf4f8f6 | ||
|
|
c1b28071df | ||
|
|
2bf7bd0a4e | ||
|
|
ff53a3e3e5 | ||
|
|
b520bfece0 | ||
|
|
9a228017c1 | ||
|
|
572927668a | ||
|
|
5f8cc5f460 | ||
|
|
43341c802f | ||
|
|
75fbf8d1f4 | ||
|
|
368ef8478c | ||
|
|
8ed3264ae6 | ||
|
|
a6d8ed829f | ||
|
|
4e9cadeca6 | ||
|
|
ce79c8e8cd | ||
|
|
bd7a11f0b1 | ||
|
|
889779113d | ||
|
|
9604076555 | ||
|
|
d09605c6b9 | ||
|
|
f187dff23a | ||
|
|
a2179ca53e | ||
|
|
d0760b2925 | ||
|
|
5a3dec7c2e | ||
|
|
e17bcc714a | ||
|
|
4f2392e492 | ||
|
|
a6541296a1 | ||
|
|
7a601a1cd0 | ||
|
|
f25c090039 | ||
|
|
9bc675873d | ||
|
|
59fd3c7170 | ||
|
|
4290e705cf | ||
|
|
863d203133 | ||
|
|
f35573611d | ||
|
|
cd3a239482 | ||
|
|
9682b02b8e | ||
|
|
bf95beb536 | ||
|
|
ae288c83f2 | ||
|
|
a76e1de49e | ||
|
|
3583962085 | ||
|
|
6b2f528624 | ||
|
|
e4a568e6b9 | ||
|
|
d146e04a13 | ||
|
|
284f987783 | ||
|
|
8e5daeb960 | ||
|
|
26982d1da0 | ||
|
|
bab558cd5c | ||
|
|
9ce168b4b6 | ||
|
|
4ae913e307 | ||
|
|
51cae12fab | ||
|
|
6b1124c23f | ||
|
|
85174c6f45 | ||
|
|
4ac3ea014c | ||
|
|
f98aecaa59 | ||
|
|
88739db6e7 | ||
|
|
f7d695c015 | ||
|
|
3a531462d9 | ||
|
|
ddbc3839a5 | ||
|
|
ad1edc8281 | ||
|
|
5f46f97298 | ||
|
|
d070f6da85 | ||
|
|
401e995df6 | ||
|
|
370bef25ff | ||
|
|
2c63ab3caf | ||
|
|
9841c571b6 | ||
|
|
52559730d9 | ||
|
|
9269a74092 | ||
|
|
5348905c23 | ||
|
|
6b816f4d44 | ||
|
|
2feeb560d1 | ||
|
|
3c2980dfdf | ||
|
|
871ed870cc | ||
|
|
ac550a1ec1 | ||
|
|
7ed7ae01ca | ||
|
|
e158a873f5 | ||
|
|
f78af97b4a | ||
|
|
7f2bb15d49 | ||
|
|
6487db064a | ||
|
|
fd55efb3b9 | ||
|
|
88df1cee82 | ||
|
|
7cc3a0cf86 | ||
|
|
6fde8fe200 | ||
|
|
db3d563e3f | ||
|
|
b95f7ed91a | ||
|
|
28c39791dc | ||
|
|
905bc9c140 | ||
|
|
9643c12429 | ||
|
|
75c8129185 | ||
|
|
ee8ad500ce | ||
|
|
5a0a034be3 | ||
|
|
8ee6d74613 | ||
|
|
a0d0790a34 | ||
|
|
b96d75b97d | ||
|
|
ab72bb9f8c | ||
|
|
e513731455 | ||
|
|
3ed43b0a85 | ||
|
|
42ce9fa21b | ||
|
|
b981f87d38 | ||
|
|
dbf31053c9 | ||
|
|
1a179c7dca | ||
|
|
5d5d954077 | ||
|
|
5b03c3dcc3 | ||
|
|
9eb9114ece | ||
|
|
80a49262f4 | ||
|
|
d12f9993dd | ||
|
|
d8df113676 | ||
|
|
e7ed3f7789 | ||
|
|
67d10d10ae | ||
|
|
03d8d6c247 | ||
|
|
15a708fbf2 | ||
|
|
ecafa39d1e | ||
|
|
da7c04d250 | ||
|
|
34a7df9180 | ||
|
|
42d822a48d | ||
|
|
77794294b1 | ||
|
|
b3c9cb2728 | ||
|
|
fcddfb0162 | ||
|
|
5bac2e9a4e | ||
|
|
01ce03ca5c | ||
|
|
2fceade3a2 | ||
|
|
5bc915f487 | ||
|
|
0e8a385b6d | ||
|
|
2cd37d90b1 | ||
|
|
f2a7811f0c | ||
|
|
4cc1704915 | ||
|
|
6809645256 | ||
|
|
0c053d410c | ||
|
|
6a7b9c8a65 | ||
|
|
394a23fa57 | ||
|
|
a178ab9bc0 | ||
|
|
d7f7a40f06 | ||
|
|
7791ae1b0d | ||
|
|
82190c7d0e | ||
|
|
380ac2f1bd | ||
|
|
bd85c0c25a | ||
|
|
15bb6177d8 | ||
|
|
fb2e7dfe12 | ||
|
|
20f28bb7df | ||
|
|
46dc4ea6e3 | ||
|
|
da0b3e71b3 | ||
|
|
c2e2b1e9be | ||
|
|
4b23765042 | ||
|
|
f7c8d39b5d | ||
|
|
94744862a5 | ||
|
|
13a977f84f | ||
|
|
11bac92d2f | ||
|
|
a6085279c9 | ||
|
|
dea874de02 | ||
|
|
ec78639d94 | ||
|
|
1123611371 | ||
|
|
1bc5e6116c | ||
|
|
5a29cde314 | ||
|
|
944b059abe | ||
|
|
d9d4d89a27 | ||
|
|
86f641c3b0 | ||
|
|
3a99d005b1 | ||
|
|
325b91933d | ||
|
|
bd08e9b125 | ||
|
|
9de1ff7cf4 | ||
|
|
142af5c218 | ||
|
|
596a577529 | ||
|
|
c460c9e674 | ||
|
|
312e619fa6 | ||
|
|
45d3ebab3d | ||
|
|
34bd22f40e | ||
|
|
ed5a5bb069 | ||
|
|
4e15fee3fb | ||
|
|
68e3045da2 | ||
|
|
87eb1e0dc9 | ||
|
|
175485284d | ||
|
|
c2e49aa2d7 | ||
|
|
bcff843186 | ||
|
|
5246c3a329 | ||
|
|
19b9888d34 | ||
|
|
bcebca9c97 | ||
|
|
570e0fa782 | ||
|
|
d5e9c7532a | ||
|
|
5c94655bd7 | ||
|
|
c48030d54e | ||
|
|
13babfa3f9 | ||
|
|
ed1db45990 | ||
|
|
4e6081bacc | ||
|
|
062097a438 | ||
|
|
220fa8a8fc | ||
|
|
5b931afefb | ||
|
|
6678928301 | ||
|
|
b8d06babee | ||
|
|
38b7a7c660 | ||
|
|
3bc72a46df | ||
|
|
e65c266831 | ||
|
|
5e846059f7 | ||
|
|
f76536b0a4 | ||
|
|
536ead64ac | ||
|
|
6c1ac6f038 | ||
|
|
207f0b255f | ||
|
|
a80f4090af | ||
|
|
395f742bce | ||
|
|
20a695f571 | ||
|
|
06c71cc332 | ||
|
|
fedcdb1b99 | ||
|
|
d4652a614c | ||
|
|
b374e8e962 | ||
|
|
277fe6d5ad | ||
|
|
54525d60ef | ||
|
|
ce572f82cb | ||
|
|
eb7f3613ca | ||
|
|
fe9229c8bc | ||
|
|
2d967f8741 | ||
|
|
bdd75ecfee | ||
|
|
37fe7925a4 | ||
|
|
3aa22eccbd | ||
|
|
6f3594d294 | ||
|
|
d7232aa8cd | ||
|
|
359f030ddb | ||
|
|
540b1ece0a | ||
|
|
3efa77e78f | ||
|
|
d446034193 | ||
|
|
20227a44a4 | ||
|
|
d538bde579 | ||
|
|
bc7407ad85 | ||
|
|
f083b6fd7a | ||
|
|
4101a83639 | ||
|
|
5296edb8d2 | ||
|
|
6cfdea17b3 | ||
|
|
309be28256 | ||
|
|
448dc172d0 | ||
|
|
a5d77d7cbb | ||
|
|
4c74bda247 | ||
|
|
22c5470b9b | ||
|
|
71da44c618 | ||
|
|
9859737668 | ||
|
|
608a86d45c | ||
|
|
0fab2df676 | ||
|
|
7b41fa961c | ||
|
|
9955a0e07b | ||
|
|
cf2160993f | ||
|
|
7d664ac105 | ||
|
|
2ddd6aa468 | ||
|
|
ed0b1f28cb | ||
|
|
a6a335d481 | ||
|
|
b2027eb2d7 | ||
|
|
af177f5249 | ||
|
|
6c35f106a4 | ||
|
|
9b643fa700 | ||
|
|
a5c27190c1 | ||
|
|
b872318350 | ||
|
|
a16a57a1f9 | ||
|
|
3d10f91026 | ||
|
|
fa43001824 | ||
|
|
f32dbe5ef8 | ||
|
|
47d97e77d8 | ||
|
|
eefc346312 | ||
|
|
31ebf1807f | ||
|
|
b4e8c39158 | ||
|
|
2a1ce40a9c | ||
|
|
2d5827a1b9 | ||
|
|
c3d9efc691 | ||
|
|
304e54f009 | ||
|
|
4e682ecbe2 | ||
|
|
877f937413 | ||
|
|
962e0f8523 | ||
|
|
01b55843d2 | ||
|
|
7338ddaadd | ||
|
|
d04786884b | ||
|
|
654d8ac75a | ||
|
|
3d3025c2cd | ||
|
|
0b57325c04 | ||
|
|
91f7d8dfc3 | ||
|
|
5952d49711 | ||
|
|
0bac3deabb | ||
|
|
4b6eeba319 | ||
|
|
c0ba8a6711 | ||
|
|
8b065cf7ac | ||
|
|
505763e0be | ||
|
|
1afd3102ab | ||
|
|
107f96e921 | ||
|
|
61294336b5 | ||
|
|
08e768fc52 | ||
|
|
87b3c37cb0 | ||
|
|
4f3c6ed090 | ||
|
|
d7d4ab6390 | ||
|
|
12b0eadc66 | ||
|
|
5702708643 | ||
|
|
1ab9fdb229 | ||
|
|
9c64566386 | ||
|
|
4a413cf72b | ||
|
|
69e56a5087 | ||
|
|
2d3277a7ea | ||
|
|
df75ae5c8c | ||
|
|
0addaf56d3 | ||
|
|
040839714d | ||
|
|
ebdfc45b69 | ||
|
|
a590fec967 | ||
|
|
68be1ad42e | ||
|
|
ca9715c3bc | ||
|
|
a3b6ed8fb3 | ||
|
|
4bd0e3efe0 | ||
|
|
274c020148 | ||
|
|
387f67dad4 | ||
|
|
ff9b3486c5 | ||
|
|
8824aa4624 | ||
|
|
03bfa5f972 | ||
|
|
0e1571c6c8 | ||
|
|
4e5bf5912f | ||
|
|
90cbbe7d3c | ||
|
|
e00f440717 | ||
|
|
696b5f0996 | ||
|
|
bcb34f1e51 | ||
|
|
dc08f8df1b | ||
|
|
a796c85e01 | ||
|
|
3dae5ec57a | ||
|
|
7bc0b8947f | ||
|
|
2d7e511bb8 |
2
.gitignore
vendored
2
.gitignore
vendored
|
|
@ -1,6 +1,4 @@
|
|||
*.tar.gz
|
||||
SeedDMS_*/*.tgz
|
||||
ext/*
|
||||
vendor
|
||||
webapp/*
|
||||
www/ext
|
||||
|
|
|
|||
|
|
@ -27,13 +27,13 @@ RewriteRule "^out/images.*$" "-" [L]
|
|||
RewriteRule "^styles/.*$" "-" [L]
|
||||
|
||||
# Accessing a file in an extension is only possible in one
|
||||
# of the directories op, out, res, node_modules
|
||||
# of the directories op, out. res
|
||||
# Added for old extensions which do not use routes
|
||||
RewriteRule ^ext/[^/]+/icon.(?:png|svg)$ - [L]
|
||||
RewriteCond %{REQUEST_URI} "ext/[^/]+/"
|
||||
RewriteRule !^ext/[^/]+/.*(?:op|out|res|node_modules) - [F]
|
||||
RewriteCond %{REQUEST_URI} "ext/[^/]+/res/.*$" [NC]
|
||||
RewriteRule !^ext/[^/]+/res/.*\.(?:css|js|mjs|ftl|png|gif|svg|ico|html|woff|ttf) - [F]
|
||||
RewriteRule !^ext/[^/]+/res/.*\.(?:css|js|png|gif|svg|ico|html|woff|ttf) - [F]
|
||||
RewriteCond %{REQUEST_FILENAME} -f
|
||||
RewriteRule ^ext/.*$ - [L]
|
||||
|
||||
356
CHANGELOG
356
CHANGELOG
|
|
@ -1,59 +1,325 @@
|
|||
--------------------------------------------------------------------------------
|
||||
Changes in version 5.1.44
|
||||
Changes in version 6.0.33
|
||||
--------------------------------------------------------------------------------
|
||||
- fix php error in install tool
|
||||
- merge changes up to 5.1.40
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
Changes in version 5.1.43
|
||||
Changes in version 6.0.32
|
||||
--------------------------------------------------------------------------------
|
||||
- add Slim middleware for Basic authentication (can be used by extensions)
|
||||
- rest api endpoint 'statstotal' returns number of groups and categories
|
||||
- add new command line program utils/console
|
||||
- major code polishing
|
||||
- add markdown editor editor.md
|
||||
- less colorful extension manager
|
||||
- check for missing changes in extension configuration
|
||||
- use table for list of caches
|
||||
- propper error msgs when saving extension configuration
|
||||
- creating backup archives has been removed
|
||||
- add javascript table sorter
|
||||
- use table sorter on clear cache page and conversion services page
|
||||
- droping an url in the drag&drop area will download the url
|
||||
- add button to all password fields to make password visible
|
||||
- fix formatting of date input fields
|
||||
- do not remove custom attributes which were not set when editing attributes
|
||||
- merge changes up to 5.1.39
|
||||
- fix setting attributes (user, group, document, folder) when checking in
|
||||
a new document version
|
||||
- validate setting revision date
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
Changes in version 5.1.42
|
||||
Changes in version 6.0.31
|
||||
--------------------------------------------------------------------------------
|
||||
- use proxy when getting latest version
|
||||
- add endpoints to rest api for setting comment and name of folder
|
||||
- initial support for installation from git
|
||||
- memcached support can be configured (still rarely used)
|
||||
- fix folder parameter passed to hook 'folderRowAction'
|
||||
- require unrestricted access on document/folder for deletion by rest api
|
||||
- use php-cache instead of native memcached
|
||||
- various updates of documentation
|
||||
- merge changes up to 5.1.38
|
||||
- fix various restapi endpoints which hadn't been updated to slim4
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
Changes in version 5.1.41
|
||||
Changes in version 6.0.30
|
||||
--------------------------------------------------------------------------------
|
||||
- action when clicking on a thumbnail can be set (download or view online)
|
||||
- major update of polish translation
|
||||
- fix getting access rights in getMandatoryApprovers() and getMandatoryReviewers()
|
||||
- better checking for attribute definition when building a search query
|
||||
- fix list of related documents when hook documentListItem() is implemented
|
||||
- move EditAttributes into controller and add various hooks (like EditDocument)
|
||||
- move sending notification mail when attributes are changed into
|
||||
Notification Service
|
||||
- more documentation on configuring LDAP
|
||||
- collect output controller/view hooks with '+' instead of array_merge()
|
||||
- add hook 'searchExportOptions'
|
||||
- show how many users have to review/approve a document and how many did
|
||||
already (in menu task list and document list)
|
||||
- break long original file names on viewDocument page
|
||||
- fix potential XSS attack in many fields of settings
|
||||
- allow to edit original filename, check filename for problematic chars
|
||||
- merge changes up to 5.1.37
|
||||
- receipt comment can be disabled
|
||||
- send request receipt notification only when document is released
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
Changes in version 6.0.29
|
||||
--------------------------------------------------------------------------------
|
||||
- merge changes up to 5.1.36
|
||||
- fix regression in FolderNotify
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
Changes in version 6.0.28
|
||||
--------------------------------------------------------------------------------
|
||||
- merge changes up to 5.1.35
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
Changes in version 6.0.27
|
||||
--------------------------------------------------------------------------------
|
||||
- merge changes up to 5.1.34
|
||||
- Document/folder check distinguishes between documents which cannot be
|
||||
receiped/revised because of access rights or the recipient/revisor being
|
||||
disabled.
|
||||
- fix creating user via rest api
|
||||
- checkout info does not depend on whether the logged in user was substituted
|
||||
- add new endpoints for managing roles by rest api
|
||||
- add transmittals in menu
|
||||
- add legacy access check for controllers
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
Changes in version 6.0.26
|
||||
--------------------------------------------------------------------------------
|
||||
- merge changes up to 5.1.33
|
||||
- add task to import files from drop folder
|
||||
- add substitution of users in bootstrap4 theme
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
Changes in version 6.0.25
|
||||
--------------------------------------------------------------------------------
|
||||
- merge changes up to 5.1.32
|
||||
- status log can be turned on with advanced access control
|
||||
- scheduler has more condensed layout
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
Changes in version 6.0.24
|
||||
--------------------------------------------------------------------------------
|
||||
- add task to send list of recent changes by email
|
||||
- merge changes up to 5.1.31
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
Changes in version 6.0.23
|
||||
--------------------------------------------------------------------------------
|
||||
- fix setting recipients and revisors
|
||||
- check in of a document is allowed for the user having done the check out
|
||||
or those users with unlimited access rights on the document
|
||||
- merge changes up to 5.1.30
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
Changes in version 6.0.22
|
||||
--------------------------------------------------------------------------------
|
||||
- merge changes up to 5.1.29
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
Changes in version 6.0.21
|
||||
--------------------------------------------------------------------------------
|
||||
- merge changes up to 5.1.28
|
||||
- add new check for documents with identical sequence numbers in a folder
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
Changes in version 6.0.20
|
||||
--------------------------------------------------------------------------------
|
||||
- merge changes up to 5.1.27
|
||||
- fix triggering workflow (Closes: #542)
|
||||
- create original file name from new document name when uploading document
|
||||
from the library folder. Used to be the original file name
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
Changes in version 6.0.19
|
||||
--------------------------------------------------------------------------------
|
||||
- merge changes up to 5.1.26
|
||||
- fix deletion of tasks when using bootstrap4 theme
|
||||
- fix deletion of documents when clicking on icon in document list (my documents)
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
Changes in version 6.0.18
|
||||
--------------------------------------------------------------------------------
|
||||
- finish op/op.Cron.php, returns json
|
||||
- merge changes up to 5.1.25
|
||||
- fix sending trigger workflow notification (Closes: #522)
|
||||
- fix updating und deleting items in document lists
|
||||
- call hook 'filenameDownloadItem' in search export and transmittal download
|
||||
- fix possible xss attack in UsrMgr (CVE-2022-28479)
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
Changes in version 6.0.17
|
||||
--------------------------------------------------------------------------------
|
||||
- merge changes up to 5.1.24
|
||||
- send notification when a receiption of a document was submitted
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
Changes in version 6.0.16
|
||||
--------------------------------------------------------------------------------
|
||||
- cancel checkout needs confirmation
|
||||
- add input field to filter list of recipients if more then 10
|
||||
- add task for creating missing preview images
|
||||
- no longer use old PHPExcel classes, use PhpOffice\PhpSpreadsheet\Spreadsheet
|
||||
instead
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
Changes in version 6.0.15
|
||||
--------------------------------------------------------------------------------
|
||||
- merge changes up to 5.1.22
|
||||
- add a new task for checking the checksum of all document versions
|
||||
- add searching for revision date
|
||||
- list of open tasks will no longer contain expired documents but MyDocuments
|
||||
page still list them
|
||||
- fixed downloading approval file (Closes: #503)
|
||||
- regular users can no longer set owner of document while uploading
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
Changes in version 6.0.14
|
||||
--------------------------------------------------------------------------------
|
||||
- show debug menu only if debug mode is on
|
||||
- merge changes up to 5.1.21
|
||||
- document links can be added by regular users again
|
||||
- add list of checked out documents to tasks
|
||||
- issue a warning when removing a document which is checked out
|
||||
- checked out can be discarded if it was changed
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
Changes in version 6.0.13
|
||||
--------------------------------------------------------------------------------
|
||||
- merge changes up to 5.1.20
|
||||
- create download file for transmittal in system tmp (Closes: #478)
|
||||
- sync source code of checkin with update document
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
Changes in version 6.0.12
|
||||
--------------------------------------------------------------------------------
|
||||
- merge changes up to 5.1.19
|
||||
- fix various errors concerning workflows
|
||||
- show menu tasks even if not admin (Closes: #485)
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
Changes in version 6.0.11
|
||||
--------------------------------------------------------------------------------
|
||||
- merge changes up to 5.1.18
|
||||
- fix access restriction for roles (content of documents was visible even if the
|
||||
role and status didn't allow it)
|
||||
- fix missing Content-Type in UserList (Closes: #480)
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
Changes in version 6.0.10
|
||||
--------------------------------------------------------------------------------
|
||||
- merge changes up to 5.1.17
|
||||
- fix list of previous document versions (Closes: #471)
|
||||
- fix uploading files with fine uploader (Closes: #472)
|
||||
- clear revision date when all revisors have been deleted
|
||||
- improve scheduler task management, tasks can be deleted, fix setting parameters
|
||||
- add op.Cron.php for running all scheduled tasks
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
Changes in version 6.0.9
|
||||
--------------------------------------------------------------------------------
|
||||
- merge changes up to 5.1.16
|
||||
- fix removal of roles (Closes: #465)
|
||||
- fix password forgotten process
|
||||
- fix setting role of new user and retrieving role of existing user
|
||||
- processes of users can be deleted again, instead of only transfered to
|
||||
another user
|
||||
- fix export of search results, headers of excel file can be translated
|
||||
- fix arcordeon for folder filters on search page
|
||||
- fix upload from dropfolder
|
||||
- fix adding new calendar event
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
Changes in version 6.0.8
|
||||
--------------------------------------------------------------------------------
|
||||
- merge changes up to 5.1.15
|
||||
- fix syntax error in op/op.EditComment.php
|
||||
- fix use of private variable in op/op.SetRecipients.php and op/op.SetRevisors.php
|
||||
- fix triggering a transition in advanced workflow mode
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
Changes in version 6.0.7
|
||||
--------------------------------------------------------------------------------
|
||||
- fix editing of document attachments
|
||||
- make receipt summary look like approval/review summary
|
||||
- merge changes up to 5.1.14
|
||||
- do not show the updating user in a revision workflow if the status is 0
|
||||
this is misleading because the user starting the revision workflow is the one
|
||||
first accessing the document
|
||||
- rejection of document receipts are turned off by default, but can be turned
|
||||
on in the settings
|
||||
- documents in DocumentChooser are sorted by name
|
||||
- instead of just removing a user from all processes it can be replaced by a new user
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
Changes in version 6.0.6
|
||||
--------------------------------------------------------------------------------
|
||||
- fix setting attributes when checking in a new document version
|
||||
- setting a document revision to 'needs correction' will no longer set the
|
||||
documents status to 'needѕ correction' if this was turned off in the settings
|
||||
- a document will not leave draft status when setting the approver/reviewer
|
||||
without setting a reviewer/approver
|
||||
- tasks to be counted in menu can be configured
|
||||
- add number of documents which need correction to menu
|
||||
- minor 2 factor auth. fixes when initially setting the secret
|
||||
- remove ѕome unneeded code from AddDocument which just caused php warnings
|
||||
- do not set the uploader of new documents to owner if the owner is different from
|
||||
the uploader
|
||||
- add scheduler
|
||||
- add hook showVersionComment in out.ViewDocument.php
|
||||
- Various minor corrections of database tables tblWorkflowLog and
|
||||
tblWorkflowDocumentContent
|
||||
- merge changes up to 5.1.7
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
Changes in version 6.0.5
|
||||
--------------------------------------------------------------------------------
|
||||
- sync form for updating document by upload and checkin
|
||||
- add list of documents which need correction on MyDocuments page
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
Changes in version 6.0.4
|
||||
--------------------------------------------------------------------------------
|
||||
- merge changes up to 5.1.5
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
Changes in version 6.0.3
|
||||
--------------------------------------------------------------------------------
|
||||
- add list of documents without a receiver on MyDocuments page
|
||||
- propperly calculate number of documents for each value of value set in attribute mgr
|
||||
- output of progress bar for reception of a document can be controlled by access list
|
||||
- recipientof a document version can be set when uploading the file
|
||||
- fix export of search and display of 2nd, 3rd, ... search page
|
||||
- speed up creation of document lists if reception progress bar is shown
|
||||
- status of rejected documents can be overriden
|
||||
- do not add users from group as recipients if they are the uploader or reviewer
|
||||
of a document
|
||||
- add list of documents without a receiver, list of drafts, and list of absolete
|
||||
documents on MyDocuments page
|
||||
- add callback onCheckAccessDocument to SeedDMS_Core_Document
|
||||
- add new document status 'needs correction', revised documents which do not pass
|
||||
will no longer be in status 'rejected' but 'needs correction'
|
||||
- better error handling when indexing documents fails
|
||||
- apache xsendfile module is used for downloading documents when installed
|
||||
- add view access check for ApprovalSummary, ReviewSummary, ReceiptSummary,
|
||||
WorkflowSummary, DocumentAccess, GroupView, UsrView, WorkflowSummary
|
||||
- filter out reviewers and uploader of a document version when setting recipients
|
||||
by user group
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
Changes in version 6.0.2
|
||||
--------------------------------------------------------------------------------
|
||||
- check if user has access on document and is not disabled if set as
|
||||
receiver, revisor
|
||||
- check if group has members if set as reviewer, approver, receiver, revisor
|
||||
- fix bug in notification of approver after successful review
|
||||
- add document check for docs in revision and missing access rights of revisor
|
||||
- add document check for docs requiring receptions but user lacks access right
|
||||
- fix Acl manager when using pgsql
|
||||
- list all open tasks of user in user info of user manager
|
||||
- owner of document may see review/approval/receipt/revision log
|
||||
- fix sending mails to reviewer/approvers after check in
|
||||
- downloading of review/approval files works again
|
||||
- optimizing retrieval of open tasks
|
||||
- do not show user which has been removed from a process except for admins
|
||||
- show scheduled revisions in calendar
|
||||
- merge changes up to 5.1.5
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
Changes in version 6.0.1
|
||||
--------------------------------------------------------------------------------
|
||||
- call hook 'rawcontent' when downloading transmittal list or search content
|
||||
- speed up list of locked documents on MyDocuments page
|
||||
- sql queries and execution times can be written to file in database layer
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
Changes in version 6.0.0
|
||||
--------------------------------------------------------------------------------
|
||||
- merge changes up to 5.0.10
|
||||
- filter documents by status 'draft' on search page
|
||||
- list of documents to look at now contains documents in revision
|
||||
- add list of documents waiting for reception on MyDocuments page
|
||||
- group document lists on MyDocuments page into three sections
|
||||
- show progressbar and comments for reception of document in documentlist
|
||||
- restructure page for document/folder check, add check for missing access
|
||||
on documents by recipient or revisor
|
||||
- overhaul revision workflow, add hook after revision workflow was finished
|
||||
- add two factor authentication based on google authenticator
|
||||
- set timeout for ajax call 'mytasks' from 200ms to 1000ms
|
||||
- use a similar layout for document list on the ViewDocument page
|
||||
- add RSS feed of timeline
|
||||
- put more operations under access control
|
||||
- add receipent list for documents
|
||||
- add revision of documents
|
||||
- add substitute user command for regular users
|
||||
- add access controll list for many functions
|
||||
- add document list which can be exported as an archive
|
||||
- search results can be exported
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
Changes in version 5.1.40
|
||||
|
|
|
|||
30
Gruntfile.js
30
Gruntfile.js
|
|
@ -221,36 +221,6 @@ module.exports = function (grunt) {
|
|||
],
|
||||
dest: bootstrapDir + '/jquery-lazy',
|
||||
flatten: true
|
||||
},{
|
||||
expand: true,
|
||||
src: [
|
||||
nodeDir + '/editor.md/editormd.min.js'
|
||||
],
|
||||
dest: bootstrapDir + '/editor.md',
|
||||
flatten: true
|
||||
},{
|
||||
expand: true,
|
||||
cwd: nodeDir + '/editor.md/',
|
||||
src: [
|
||||
'lib/*',
|
||||
'languages/*',
|
||||
'images/*',
|
||||
'fonts/*',
|
||||
'plugins/**',
|
||||
'lib/codemirror/**',
|
||||
'css/*'
|
||||
],
|
||||
dest: bootstrapDir + '/editor.md',
|
||||
flatten: false
|
||||
},{
|
||||
expand: true,
|
||||
cwd: nodeDir + '/tablesort/dist/',
|
||||
src: [
|
||||
'tablesort.min.js',
|
||||
'sorts/**'
|
||||
],
|
||||
dest: bootstrapDir + '/tablesort',
|
||||
flatten: false
|
||||
},{
|
||||
expand: true,
|
||||
src: [
|
||||
|
|
|
|||
22
Makefile
22
Makefile
|
|
@ -6,11 +6,7 @@ NODISTFILES=utils/importmail.php utils/seedddms-importmail utils/remote-email-up
|
|||
|
||||
PHPDOC=~/Downloads/phpDocumentor.phar
|
||||
|
||||
INSTALL_PATH=/home/www-data/seeddms-test
|
||||
|
||||
all: dist
|
||||
|
||||
olddist:
|
||||
dist:
|
||||
mkdir -p tmp/seeddms-$(VERSION)
|
||||
cp -a $(SRC) tmp/seeddms-$(VERSION)
|
||||
mkdir -p tmp/seeddms-$(VERSION)/views
|
||||
|
|
@ -27,20 +23,8 @@ olddist:
|
|||
(cd tmp; tar --exclude=.svn --exclude=.gitignore -czvf ../seeddms-$(VERSION).tar.gz seeddms-$(VERSION))
|
||||
rm -rf tmp
|
||||
|
||||
dist:
|
||||
php vendor/bin/phing -Dversion=$(VERSION) dist
|
||||
|
||||
quickstart:
|
||||
php vendor/bin/phing -Dversion=$(VERSION) package
|
||||
|
||||
quickstart-dev:
|
||||
php vendor/bin/phing -Dversion=$(VERSION) -Dmode=development package
|
||||
|
||||
install:
|
||||
php vendor/bin/phing -Dversion=$(VERSION) -Dinstallpath=$(INSTALL_PATH) -Ddomain=dms.seeddms.org install
|
||||
|
||||
update:
|
||||
php vendor/bin/phing -Dversion=$(VERSION) -Dinstallpath=$(INSTALL_PATH) -Ddomain=dms.seeddms.org update
|
||||
php7.4 vendor/bin/phing -Dversion=$(VERSION) package
|
||||
|
||||
unittest:
|
||||
vendor/bin/phing -Dversion=$(VERSION) phpunitfast
|
||||
|
|
@ -111,4 +95,4 @@ PKGFILE=SeedDMS_Core/package.xml
|
|||
changelog:
|
||||
@sgrep 'stag("DATE") .. etag("DATE") or ((stag("RELEASE") .. etag("RELEASE")) in (stag("VERSION") .. etag("VERSION"))) or inner(stag("NOTES") __ etag("NOTES"))' ${PKGFILE} | sed -e 's#^ *<date>\([-0-9]*\)</date><release>\([0-9.preRC]*\)</release>#\n\n\2 (\1)\n---------------------#' | awk -F'\n' -vRS='' -vOFS='|' '{$$1=$$1}1' | sort -V -r | sed 's/$$/\n/' | tr '|' '\n'
|
||||
|
||||
.PHONY: doc webdav webapp repository changelog install
|
||||
.PHONY: doc webdav webapp repository changelog
|
||||
|
|
|
|||
52
README.md
52
README.md
|
|
@ -1,52 +0,0 @@
|
|||
SeedDMS is a PHP based Document Management System. For more information
|
||||
check the web site at https://www.seeddms.org
|
||||
|
||||
There are detailed installation instructions from a preconfigured distribution
|
||||
at [doc/README.Install.md]
|
||||
|
||||
If you prefer to install from git, you will need to:
|
||||
|
||||
1. Create a directory, e.g. seeddms
|
||||
|
||||
`mkdir seeddms`
|
||||
2. Change into that directory
|
||||
|
||||
`cd seeddms`
|
||||
3. Clone the various SeedDMS repositories
|
||||
|
||||
```
|
||||
git clone https://codeberg.org/SeedDMS/preview.git
|
||||
git clone https://codeberg.org/SeedDMS/lucene.git
|
||||
git clone https://codeberg.org/SeedDMS/ѕqlitefts.git
|
||||
git clone https://codeberg.org/SeedDMS/http_webdav_server.git
|
||||
```
|
||||
4. For SeedDMS 5.1.x
|
||||
|
||||
```
|
||||
git clone -b seeddms-5.1.x https://codeberg.org/SeedDMS/seeddms.git
|
||||
git clone -b seeddms-5.1.x https://codeberg.org/SeedDMS/core.git
|
||||
```
|
||||
|
||||
For SeedDMS 6.0.x
|
||||
|
||||
```
|
||||
git clone -b seeddms-6.0.x https://codeberg.org/SeedDMS/seeddms.git
|
||||
git clone -b seeddms-6.0.x https://codeberg.org/SeedDMS/core.git
|
||||
```
|
||||
5. Run composer
|
||||
|
||||
`composer update`
|
||||
|
||||
6. Create an installable distribution
|
||||
|
||||
`vendor/bin/phing -Dversion=$(php -r 'include "inc/inc.Version.php"; echo (new SeedDMS_Version())->version();') package`
|
||||
|
||||
or create an installable distribution with softlinks
|
||||
|
||||
`vendor/bin/phing -Dversion=$(php -r 'include "inc/inc.Version.php"; echo (new SeedDMS_Version())->version();') -Dmode=development package`
|
||||
|
||||
This archive does not contain any sources but only links to the previously
|
||||
cloned repositories.
|
||||
|
||||
The archive created in step 6. can be installed like the official releases of
|
||||
SeedDMS.
|
||||
2
TODO
2
TODO
|
|
@ -1,5 +1,3 @@
|
|||
!!! This is hopelessly outdated !!!
|
||||
|
||||
This list is hopelessly outdated, but some of the issues are
|
||||
still worth to be implemented!
|
||||
|
||||
|
|
|
|||
372
build.xml
372
build.xml
|
|
@ -1,6 +1,6 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project name="seeddms" basedir="." default="main">
|
||||
<property name="tmp" value="/tmp" />
|
||||
<property name="tmp" value="/tmp" />
|
||||
<property name="package" value="${phing.project.name}" override="true" />
|
||||
<property name="seeddmsurl" value="http://localhost/seeddms51x" />
|
||||
<property name="builddir" value="${tmp}/build/${phing.project.name}" override="true" />
|
||||
|
|
@ -16,13 +16,9 @@
|
|||
<propertyregex property="shortversion" subject="${version} kk" pattern="([56])\.([0-9]).*" replace="seeddms$1$2x" override="true"/>
|
||||
<property name="majorversion" value="${version}" />
|
||||
<propertyregex property="majorversion" subject="${version}" pattern="([56])\..*" replace="$1" override="true"/>
|
||||
<property name="minorversion" value="${version}" />
|
||||
<propertyregex property="minorversion" subject="${version}" pattern="[56]\.([0-9])\..*" replace="$1" override="true"/>
|
||||
<property name="subminorversion" value="${version}" />
|
||||
<propertyregex property="subminorversion" subject="${version}" pattern="[56]\.[0-9]\.(.*)" replace="$1" override="true"/>
|
||||
<property name="composer_version" value="2.8.5" />
|
||||
<property name="composer_extra_params" value="" />
|
||||
<property name="composer_env" value="" />
|
||||
<property name="composer_version" value="2.8.5" />
|
||||
<property name="composer_extra_params" value="" />
|
||||
<property name="composer_env" value="" />
|
||||
<property name="mink_driver" value="chrome" />
|
||||
<property name="snooze_multiplier" value="1" />
|
||||
|
||||
|
|
@ -39,43 +35,44 @@
|
|||
<include name="webdav/**" />
|
||||
<include name="install/**" />
|
||||
<include name="restapi/**" />
|
||||
<include name="www/index.php" />
|
||||
<include name="pdfviewer/**" />
|
||||
<include name="index.php" />
|
||||
<include name="CHANGELOG" />
|
||||
<include name="www/.htaccess" />
|
||||
<include name=".htaccess" />
|
||||
<include name="LICENSE" />
|
||||
</fileset>
|
||||
|
||||
<target name="main">
|
||||
<echo>Hello</echo>
|
||||
</target>
|
||||
<target name="main">
|
||||
<echo>Hello</echo>
|
||||
</target>
|
||||
|
||||
<!-- PHP CodeSniffer -->
|
||||
<target name="phpcbf">
|
||||
<exec executable="bash" line="${srcdir}/vendor/bin/phpcbf --standard=${srcdir}/phpcs.xml" escape="false" passthru="true" checkreturn="true" />
|
||||
</target>
|
||||
<target name="phpcs">
|
||||
<exec executable="bash" line="${srcdir}/vendor/bin/phpcs --standard=${srcdir}/phpcs.xml --report=checkstyle > ${builddir}/reports/checkstyle.xml" escape="false" />
|
||||
</target>
|
||||
<target name="phpcs-console">
|
||||
<exec executable="bash" line="${srcdir}/vendor/bin/phpcs --standard=${srcdir}/phpcs.xml" escape="false" passthru="true" checkreturn="true" />
|
||||
</target>
|
||||
<!-- PHP CodeSniffer -->
|
||||
<target name="phpcbf">
|
||||
<exec command="${srcdir}/vendor/bin/phpcbf --standard=${srcdir}/phpcs.xml" escape="false" passthru="true" checkreturn="true" />
|
||||
</target>
|
||||
<target name="phpcs">
|
||||
<exec command="${srcdir}/vendor/bin/phpcs --standard=${srcdir}/phpcs.xml --report=checkstyle > ${builddir}/reports/checkstyle.xml" escape="false" />
|
||||
</target>
|
||||
<target name="phpcs-console">
|
||||
<exec command="${srcdir}/vendor/bin/phpcs --standard=${srcdir}/phpcs.xml" escape="false" passthru="true" checkreturn="true" />
|
||||
</target>
|
||||
|
||||
<target name="php-cs-fixer-dryrun">
|
||||
<exec executable="bash" line="${srcdir}/vendor/bin/php-cs-fixer fix --dry-run -vvv --diff ${srcdir}/inc" passthru="true" escape="false" checkreturn="true" />
|
||||
<target name="php-cs-fixer-dryrun">
|
||||
<exec command="${srcdir}/vendor/bin/php-cs-fixer fix --dry-run -vvv --diff ${srcdir}/inc" passthru="true" escape="false" checkreturn="true" />
|
||||
</target>
|
||||
|
||||
<!-- PHPUnit -->
|
||||
<target name="phpunitfast" description="Run tests">
|
||||
<exec dir="${srcdir}/SeedDMS_Core" executable="bash" line="XDEBUG_MODE=coverage SEEDDMS_CORE_SQL=../install/create_tables-sqlite3.sql ${srcdir}/vendor/bin/phpunit --bootstrap ${srcdir}/SeedDMS_Core/bootstrap-${majorversion}.php --coverage-html ${srcdir}/coverage/" passthru="true" checkreturn="true" />
|
||||
<exec dir="${srcdir}/SeedDMS_Core" command="XDEBUG_MODE=coverage SEEDDMS_CORE_SQL=../install/create_tables-sqlite3.sql ${srcdir}/vendor/bin/phpunit --bootstrap ${srcdir}/SeedDMS_Core/bootstrap-${majorversion}.php --coverage-html ${srcdir}/coverage/" passthru="true" checkreturn="true" />
|
||||
<!-- exec dir="${srcdir}/tests" command="SEEDDMS_URL=${seeddmsurl} SEEDDMS_MINK_DRIVER=${mink_driver} SEEDDMS_SNOOZE_MULTIPLIER=${snooze_multiplier} ${srcdir}/vendor/bin/phpunit" passthru="true" checkreturn="true" / -->
|
||||
</target>
|
||||
|
||||
<target name="composer" description="Install dependencies with Composer">
|
||||
<if>
|
||||
<equals arg1="${composer_version}" arg2="latest-2.x" />
|
||||
<then>
|
||||
<httpget url="https://getcomposer.org/composer-2.phar" sslVerifyPeer="false" dir="${srcdir}" filename="composer.phar" />
|
||||
</then>
|
||||
<target name="composer" description="Install dependencies with Composer">
|
||||
<if>
|
||||
<equals arg1="${composer_version}" arg2="latest-2.x" />
|
||||
<then>
|
||||
<httpget url="https://getcomposer.org/composer-2.phar" sslVerifyPeer="false" dir="${srcdir}" filename="composer.phar" />
|
||||
</then>
|
||||
<else>
|
||||
<if>
|
||||
<not><available file="composer.phar" /></not>
|
||||
|
|
@ -83,16 +80,10 @@
|
|||
<httpget url="https://getcomposer.org/download/${composer_version}/composer.phar" sslVerifyPeer="false" dir="${srcdir}" />
|
||||
</then>
|
||||
</if>
|
||||
</else>
|
||||
</if>
|
||||
<echo message="Installing dependencies..." />
|
||||
<exec executable="php" passthru="false" dir="${builddir}/export/${shortversion}">
|
||||
<arg line="${srcdir}/composer.phar install ${composer_extra_params}"/>
|
||||
<!-- arg line="${composer_env} php ${srcdir}/composer.phar install ${composer_extra_params}"/ -->
|
||||
</exec>
|
||||
<exec executable="php" passthru="true" dir="${builddir}/export/${shortversion}">
|
||||
<arg line="${srcdir}/composer.phar dump -o ${composer_extra_params}"/>
|
||||
</exec>
|
||||
</else>
|
||||
</if>
|
||||
<echo message="Installing dependencies..." />
|
||||
<exec command="${composer_env} php ${srcdir}/composer.phar install ${composer_extra_params}" passthru="true" checkreturn="true" />
|
||||
</target>
|
||||
|
||||
<target name="dist" description="build SeedDMS tar archive">
|
||||
|
|
@ -101,29 +92,11 @@
|
|||
<then><fail msg="Pass version as property 'version'" /></then>
|
||||
</if>
|
||||
|
||||
<echo msg="This is ${version}" />
|
||||
<echo msg="This is ${shortversion}" />
|
||||
|
||||
<delete file="./seeddms-${version}.tar.gz" failonerror="false" />
|
||||
<tar destfile="./seeddms-${version}.tar.gz" prefix="seeddms-${version}" compression="gzip">
|
||||
<!-- fileset refid="distfiles" / -->
|
||||
<fileset dir=".">
|
||||
<include name="languages/**" />
|
||||
<include name="op/**" />
|
||||
<include name="out/**" />
|
||||
<include name="inc/**" />
|
||||
<include name="controllers/**" />
|
||||
<include name="styles/**" />
|
||||
<include name="views/bootstrap*/**" />
|
||||
<include name="utils/**" />
|
||||
<include name="doc/**" />
|
||||
<include name="webdav/**" />
|
||||
<include name="install/**" />
|
||||
<include name="restapi/**" />
|
||||
<include name="www/index.php" />
|
||||
<include name="CHANGELOG" />
|
||||
<include name="www/.htaccess" />
|
||||
<include name="LICENSE" />
|
||||
</fileset>
|
||||
<fileset refid="distfiles" />
|
||||
</tar>
|
||||
</target>
|
||||
|
||||
|
|
@ -134,9 +107,6 @@
|
|||
</if>
|
||||
|
||||
<echo msg="This is ${shortversion}" />
|
||||
<echo msg="Major version ${majorversion}" />
|
||||
<echo msg="Minor version ${minorversion}" />
|
||||
<echo msg="Subminor version ${subminorversion}" />
|
||||
|
||||
<if>
|
||||
<matches string="${version}" pattern="^6\.0\..*" />
|
||||
|
|
@ -144,231 +114,103 @@
|
|||
<else><echo msg="This is version 5" /></else>
|
||||
</if>
|
||||
<!-- make sure the work area is empty, then rebuild it -->
|
||||
<delete dir="${builddir}/packages" includeemptydirs="true" failonerror="false" />
|
||||
<mkdir dir="${builddir}/packages" />
|
||||
<delete dir="${builddir}/export" includeemptydirs="true" failonerror="false" />
|
||||
<mkdir dir="${builddir}/export" />
|
||||
<delete dir="${builddir}/packages" includeemptydirs="true" failonerror="false" />
|
||||
<mkdir dir="${builddir}/packages" />
|
||||
<delete dir="${builddir}/export" includeemptydirs="true" failonerror="false" />
|
||||
<mkdir dir="${builddir}/export/${shortversion}" />
|
||||
<mkdir dir="${builddir}/export/${shortversion}/conf" />
|
||||
<mkdir dir="${builddir}/export/${shortversion}/data" />
|
||||
<mkdir dir="${builddir}/export/${shortversion}/data/1048576" />
|
||||
<mkdir dir="${builddir}/export/${shortversion}/data/log" />
|
||||
<mkdir dir="${builddir}/export/${shortversion}/data/cache" />
|
||||
<exec executable="echo" passthru="true" checkreturn="true">
|
||||
<arg line="'Signature: 8a477f597d28d172789f06886806bc55' > ${builddir}/export/${shortversion}/data/cache/CACHEDIR.TAG" />
|
||||
</exec>
|
||||
<exec executable="echo" passthru="true" checkreturn="true">
|
||||
<arg line="'# This file is a cache directory tag created by seeddms.' >> ${builddir}/export/${shortversion}/data/cache/CACHEDIR.TAG" />
|
||||
</exec>
|
||||
<exec executable="echo" passthru="true" checkreturn="true">
|
||||
<arg line="echo '# For information about cache directory tags, see: http://www.brynosaurus.com/cachedir/' >> ${builddir}/export/${shortversion}/data/cache/CACHEDIR.TAG" />
|
||||
</exec>
|
||||
<exec command="echo 'Signature: 8a477f597d28d172789f06886806bc55' > ${builddir}/export/${shortversion}/data/cache/CACHEDIR.TAG" />
|
||||
<exec command="echo '# This file is a cache directory tag created by seeddms.' >> ${builddir}/export/${shortversion}/data/cache/CACHEDIR.TAG" />
|
||||
<exec command="echo '# For information about cache directory tags, see: http://www.brynosaurus.com/cachedir/' >> ${builddir}/export/${shortversion}/data/cache/CACHEDIR.TAG" />
|
||||
<mkdir dir="${builddir}/export/${shortversion}/data/backup" />
|
||||
<mkdir dir="${builddir}/export/${shortversion}/data/lucene" />
|
||||
<mkdir dir="${builddir}/export/${shortversion}/data/staging" />
|
||||
<mkdir dir="${builddir}/export/${shortversion}/pear" />
|
||||
<mkdir dir="${builddir}/export/${shortversion}/www" />
|
||||
<mkdir dir="${builddir}/export/${shortversion}/www/ext" />
|
||||
<if>
|
||||
<matches string="${mode}" pattern="^development" />
|
||||
<then></then>
|
||||
<else>
|
||||
<mkdir dir="${builddir}/export/${shortversion}/seeddms-${version}" />
|
||||
</else>
|
||||
</if>
|
||||
<mkdir dir="${builddir}/export/${shortversion}/seeddms-${version}" />
|
||||
|
||||
<copy file="${srcdir}/conf/settings.xml.template" tofile="${builddir}/export/${shortversion}/conf/settings.xml">
|
||||
<filterchain>
|
||||
<replaceregexp>
|
||||
<replaceregexp>
|
||||
<regexp pattern="_DBC_DBTYPE_" replace="${dbtype}"/>
|
||||
<regexp pattern="_DBC_DBSERVER_" replace="${dbhost}"/>
|
||||
<regexp pattern="_DBC_DBNAME_" replace="${dbname}"/>
|
||||
<regexp pattern="_DBC_DBUSER_" replace="${dbuser}"/>
|
||||
<regexp pattern="_DBC_DBPASS_" replace="${dbpass}"/>
|
||||
<regexp pattern="_SHORT_VERSION_" replace="${shortversion}"/>
|
||||
</replaceregexp>
|
||||
</replaceregexp>
|
||||
</filterchain>
|
||||
</copy>
|
||||
<copy file="${srcdir}/conf/.htaccess" tofile="${builddir}/export/${shortversion}/conf/.htaccess" />
|
||||
<if>
|
||||
<matches string="${mode}" pattern="^development" />
|
||||
<then>
|
||||
<exec executable="ln" passthru="true" dir="${builddir}/export/${shortversion}">
|
||||
<arg line="-s ${srcdir} seeddms" />
|
||||
</exec>
|
||||
<exec executable="ln" passthru="true" dir="${builddir}/export/${shortversion}/www">
|
||||
<arg line="-s ${srcdir}/op" />
|
||||
</exec>
|
||||
<exec executable="ln" passthru="true" dir="${builddir}/export/${shortversion}/www">
|
||||
<arg line="-s ${srcdir}/out" />
|
||||
</exec>
|
||||
<exec executable="ln" passthru="true" dir="${builddir}/export/${shortversion}/www">
|
||||
<arg line="-s ${srcdir}/inc" />
|
||||
</exec>
|
||||
<exec executable="ln" passthru="true" dir="${builddir}/export/${shortversion}/www">
|
||||
<arg line="-s ${srcdir}/controllers" />
|
||||
</exec>
|
||||
<exec executable="ln" passthru="true" dir="${builddir}/export/${shortversion}/www">
|
||||
<arg line="-s ${srcdir}/languages" />
|
||||
</exec>
|
||||
<exec executable="ln" passthru="true" dir="${builddir}/export/${shortversion}/www">
|
||||
<arg line="-s ${srcdir}/views" />
|
||||
</exec>
|
||||
<exec executable="ln" passthru="true" dir="${builddir}/export/${shortversion}/www">
|
||||
<arg line="-s ${srcdir}/restapi" />
|
||||
</exec>
|
||||
<exec executable="ln" passthru="true" dir="${builddir}/export/${shortversion}/www">
|
||||
<arg line="-s ${srcdir}/styles" />
|
||||
</exec>
|
||||
<exec executable="ln" passthru="true" dir="${builddir}/export/${shortversion}/www">
|
||||
<arg line="-s ${srcdir}/install" />
|
||||
</exec>
|
||||
<exec executable="ln" passthru="true" dir="${builddir}/export/${shortversion}/www">
|
||||
<arg line="-s ${srcdir}/webdav" />
|
||||
</exec>
|
||||
<exec executable="ln" passthru="true" dir="${builddir}/export/${shortversion}/www">
|
||||
<arg line="-s ${srcdir}/www/index.php" />
|
||||
</exec>
|
||||
<exec executable="ln" passthru="true" dir="${builddir}/export/${shortversion}/www">
|
||||
<arg line="-s ${srcdir}/www/.htaccess" />
|
||||
</exec>
|
||||
</then>
|
||||
<else>
|
||||
<copy todir="${builddir}/export/${shortversion}/seeddms-${version}">
|
||||
<fileset refid="distfiles" />
|
||||
</copy>
|
||||
<copy todir="${builddir}/export/${shortversion}/www/ext/example">
|
||||
<fileset dir="${srcdir}/www/ext/example" defaultexcludes="false" />
|
||||
</copy>
|
||||
<if>
|
||||
<available file="${srcdir}/www/ext/pdfviewer/conf.php"/>
|
||||
<then>
|
||||
<copy todir="${builddir}/export/${shortversion}/www/ext/pdfviewer">
|
||||
<fileset dir="${srcdir}/www/ext/pdfviewer/" expandsymboliclinks="true" defaultexcludes="false">
|
||||
<include name="**/*" />
|
||||
</fileset>
|
||||
</copy>
|
||||
</then>
|
||||
<else>
|
||||
<echo level="warning" message="I didn't find the extension 'pdfviewer'. You need to install it manually." />
|
||||
</else>
|
||||
</if>
|
||||
<copy tofile="${builddir}/export/${shortversion}/composer.json" file="composer-dist.json">
|
||||
<filterchain>
|
||||
<replaceregexp>
|
||||
<regexp pattern="/home/cvs/seeddms-ext/" replace="${srcdir}/../"/>
|
||||
<regexp pattern="__CORE_BRANCH__" replace="seeddms-${majorversion}.${minorversion}.x"/>
|
||||
</replaceregexp>
|
||||
</filterchain>
|
||||
</copy>
|
||||
<exec executable="ln" passthru="true" dir="${builddir}/export/${shortversion}">
|
||||
<arg line="-s seeddms-${version} seeddms" />
|
||||
</exec>
|
||||
<phingcall target="composer">
|
||||
<property name="composer_extra_params" value="--working-dir=${builddir}/export/${shortversion}/" />
|
||||
<property name="composer_envv" value="COMPOSER=${srcdir}/composer-dist.json" />
|
||||
</phingcall>
|
||||
<exec executable="ln" passthru="true" dir="${builddir}/export/${shortversion}/www">
|
||||
<arg line="-s ../seeddms/op" />
|
||||
</exec>
|
||||
<exec executable="ln" passthru="true" dir="${builddir}/export/${shortversion}/www">
|
||||
<arg line="-s ../seeddms/out" />
|
||||
</exec>
|
||||
<exec executable="ln" passthru="true" dir="${builddir}/export/${shortversion}/www">
|
||||
<arg line="-s ../seeddms/inc" />
|
||||
</exec>
|
||||
<exec executable="ln" passthru="true" dir="${builddir}/export/${shortversion}/www">
|
||||
<arg line="-s ../seeddms/controllers" />
|
||||
</exec>
|
||||
<exec executable="ln" passthru="true" dir="${builddir}/export/${shortversion}/www">
|
||||
<arg line="-s ../seeddms/languages" />
|
||||
</exec>
|
||||
<exec executable="ln" passthru="true" dir="${builddir}/export/${shortversion}/www">
|
||||
<arg line="-s ../seeddms/views" />
|
||||
</exec>
|
||||
<exec executable="ln" passthru="true" dir="${builddir}/export/${shortversion}/www">
|
||||
<arg line="-s ../seeddms/restapi" />
|
||||
</exec>
|
||||
<exec executable="ln" passthru="true" dir="${builddir}/export/${shortversion}/www">
|
||||
<arg line="-s ../seeddms/styles" />
|
||||
</exec>
|
||||
<exec executable="ln" passthru="true" dir="${builddir}/export/${shortversion}/www">
|
||||
<arg line="-s ../seeddms/install" />
|
||||
</exec>
|
||||
<exec executable="ln" passthru="true" dir="${builddir}/export/${shortversion}/www">
|
||||
<arg line="-s ../seeddms/webdav" />
|
||||
</exec>
|
||||
<exec executable="ln" passthru="true" dir="${builddir}/export/${shortversion}/www">
|
||||
<arg line="-s ../seeddms/www/index.php" />
|
||||
</exec>
|
||||
<exec executable="ln" passthru="true" dir="${builddir}/export/${shortversion}/www">
|
||||
<arg line="-s ../seeddms/www/.htaccess" />
|
||||
</exec>
|
||||
</else>
|
||||
</if>
|
||||
<copy todir="${builddir}/export/${shortversion}/seeddms-${version}">
|
||||
<fileset refid="distfiles" />
|
||||
</copy>
|
||||
<copy todir="${builddir}/export/${shortversion}/pear/vendor">
|
||||
<fileset dir="${srcdir}/vendor" defaultexcludes="false" />
|
||||
</copy>
|
||||
<copy todir="${builddir}/export/${shortversion}/www/ext/example">
|
||||
<fileset dir="${srcdir}/ext/example" defaultexcludes="false" />
|
||||
</copy>
|
||||
<!-- copy todir="${builddir}/export/${shortversion}/pear/SeedDMS">
|
||||
<fileset dir="SeedDMS_Core">
|
||||
<include name="Core/**" />
|
||||
<include name="Core.php" />
|
||||
</fileset>
|
||||
<fileset dir="SeedDMS_Preview">
|
||||
<include name="Preview/**" />
|
||||
<include name="Preview.php" />
|
||||
</fileset>
|
||||
<fileset dir="SeedDMS_Lucene">
|
||||
<include name="Lucene/**" />
|
||||
<include name="Lucene.php" />
|
||||
</fileset -->
|
||||
<!-- fileset dir="SeedDMS_SQLiteFTS">
|
||||
<include name="SQLiteFTS/**" />
|
||||
<include name="SQLiteFTS.php" />
|
||||
</fileset>
|
||||
</copy -->
|
||||
<!-- copy todir="${builddir}/export/${shortversion}/pear">
|
||||
<fileset dir="../seeddms-ext/http_webdav_server">
|
||||
<include name="HTTP/WebDAV/Server/**" />
|
||||
<include name="HTTP/WebDAV/Server.php" />
|
||||
</fileset>
|
||||
</copy>
|
||||
<copy todir="${builddir}/export/${shortversion}/pear/HTTP/WebDAV">
|
||||
<fileset dir="../seeddms-ext/http_webdav_server">
|
||||
<include name="Tools/**" />
|
||||
</fileset>
|
||||
</copy -->
|
||||
<copy tofile="${builddir}/export/${shortversion}/pear/composer.json" file="composer-dist.json">
|
||||
</copy>
|
||||
<phingcall target="composer">
|
||||
<property name="composer_extra_params" value="--working-dir=${builddir}/export/${shortversion}/pear/" />
|
||||
<property name="composer_envv" value="COMPOSER=${srcdir}/composer-dist.json" />
|
||||
</phingcall>
|
||||
<exec command="cd ${builddir}/export/${shortversion} && ln -s seeddms-${version} seeddms" />
|
||||
<exec command="cd ${builddir}/export/${shortversion}/www && ln -s ../seeddms/op" />
|
||||
<exec command="cd ${builddir}/export/${shortversion}/www && ln -s ../seeddms/out" />
|
||||
<exec command="cd ${builddir}/export/${shortversion}/www && ln -s ../seeddms/inc" />
|
||||
<exec command="cd ${builddir}/export/${shortversion}/www && ln -s ../seeddms/controllers" />
|
||||
<exec command="cd ${builddir}/export/${shortversion}/www && ln -s ../seeddms/languages" />
|
||||
<exec command="cd ${builddir}/export/${shortversion}/www && ln -s ../seeddms/views" />
|
||||
<exec command="cd ${builddir}/export/${shortversion}/www && ln -s ../seeddms/restapi" />
|
||||
<exec command="cd ${builddir}/export/${shortversion}/www && ln -s ../seeddms/styles" />
|
||||
<exec command="cd ${builddir}/export/${shortversion}/www && ln -s ../seeddms/pdfviewer" />
|
||||
<exec command="cd ${builddir}/export/${shortversion}/www && ln -s ../seeddms/install" />
|
||||
<exec command="cd ${builddir}/export/${shortversion}/www && ln -s ../seeddms/webdav" />
|
||||
<exec command="cd ${builddir}/export/${shortversion}/www && ln -s ../seeddms/index.php" />
|
||||
<exec command="cd ${builddir}/export/${shortversion}/www && ln -s ../seeddms/.htaccess" />
|
||||
|
||||
<!-- create initial empty database -->
|
||||
<echo message="Creating sqlite3 database ..." />
|
||||
<exec executable="bash" passthru="true">
|
||||
<arg value="-c"/>
|
||||
<arg line='"cat ${srcdir}/install/create_tables-sqlite3.sql | sqlite3 ${builddir}/export/${shortversion}/data/content.db"' />
|
||||
</exec>
|
||||
<exec command="cat ${srcdir}/install/create_tables-sqlite3.sql | sqlite3 ${builddir}/export/${shortversion}/data/content.db" />
|
||||
|
||||
<!-- build the standard tar.gz archive -->
|
||||
<echo message="Building .tar.gz ..." />
|
||||
<exec executable="tar" passthru="true" checkreturn="true" dir="${builddir}/export">
|
||||
<arg line="czf ../packages/seeddms-quickstart-${version}.tar.gz ${shortversion}" />
|
||||
</exec>
|
||||
<!-- build the standard tar.gz archive -->
|
||||
<echo message="Building .tar.gz...." />
|
||||
<exec command="cd ${builddir}/export ; tar czf ${builddir}/packages/seeddms-quickstart-${version}.tar.gz ${shortversion}" checkreturn="true" />
|
||||
<echo message="Built in ${builddir}/packages/seeddms-quickstart-${version}.tar.gz" />
|
||||
</target>
|
||||
|
||||
<target name="install" description="Install SeedDMS">
|
||||
<if>
|
||||
<equals arg1="" arg2="${installpath}" />
|
||||
<then><fail msg="Pass install path as property 'installpath'. Ensure this directory exists and is writeable by the user running this build script." /></then>
|
||||
</if>
|
||||
<if>
|
||||
<not><available file="${installpath}"/></not>
|
||||
<then><fail msg="Install path '${installpath}' does not exist." /></then>
|
||||
</if>
|
||||
<phingcall target="package"></phingcall>
|
||||
<exec executable="tar" passthru="false" checkreturn="true" dir="${installpath}">
|
||||
<arg line="-xzvf ${builddir}/packages/seeddms-quickstart-${version}.tar.gz --strip-components=1" />
|
||||
</exec>
|
||||
<copy file="${srcdir}/conf/apache.virtualhost.template" tofile="${installpath}/conf/apache.virtualhost.conf">
|
||||
<filterchain>
|
||||
<replaceregexp>
|
||||
<regexp pattern="_INSTALL_PATH_" replace="${installpath}"/>
|
||||
<regexp pattern="_DOMAIN_" replace="${domain}"/>
|
||||
</replaceregexp>
|
||||
</filterchain>
|
||||
</copy>
|
||||
<exec executable="bash" passthru="true" dir="${installpath}">
|
||||
<arg value="-c"/>
|
||||
<arg line="'sudo chown www-data:www-data ${installpath}'" />
|
||||
</exec>
|
||||
<exec executable="bash" passthru="true" dir="${installpath}">
|
||||
<arg value="-c"/>
|
||||
<arg line="'sudo chown -R www-data:www-data ${installpath}/data ${installpath}/conf'" />
|
||||
</exec>
|
||||
<echo message="Create a link in /etc/apache2/sites-enabled/" />
|
||||
<echo message="sudo ln -s ${installpath}/conf/apache.virtualhost.conf /etc/apache2/sites-enabled/001-seeddms.conf" />
|
||||
</target>
|
||||
|
||||
<target name="update" description="Update SeedDMS Installation">
|
||||
<if>
|
||||
<equals arg1="" arg2="${installpath}" />
|
||||
<then><fail msg="Pass install path as property 'installpath'. Ensure this directory exists and is writeable by the user running this build script." /></then>
|
||||
</if>
|
||||
<if>
|
||||
<not><available file="${installpath}"/></not>
|
||||
<then><fail msg="Install path '${installpath}' does not exist." /></then>
|
||||
</if>
|
||||
<phingcall target="package"></phingcall>
|
||||
<exec executable="tar" passthru="false" checkreturn="true" dir="${installpath}">
|
||||
<arg line="-xzvf ${builddir}/packages/seeddms-quickstart-${version}.tar.gz --strip-components=1 ${shortversion}/vendor ${shortversion}/seeddms-${version}" />
|
||||
</exec>
|
||||
<!-- delete file="${installpath}/seeddms" / -->
|
||||
<!-- symlink target="${installpath}/${shortversion}" link="${installpath}/seeddms" relative="true"/ -->
|
||||
<echo message="If you have updated to a newer version of SeedDMS, you will have to adjust the link 'seeddms' pointing to 'seeddms-${version}' in '${installpath}'." />
|
||||
</target>
|
||||
</project>
|
||||
|
|
|
|||
|
|
@ -1,44 +1,11 @@
|
|||
{
|
||||
"name": "seeddms/dms",
|
||||
"description": "Open Source Document Management System",
|
||||
"type": "project",
|
||||
"license": "GPL 2",
|
||||
"authors": [
|
||||
{
|
||||
"name": "Uwe Steinmann",
|
||||
"email": "steinm@debian.org"
|
||||
}
|
||||
],
|
||||
"minimum-stability": "stable",
|
||||
"config": {
|
||||
"platform": {
|
||||
"php": "8.2"
|
||||
},
|
||||
"allow-plugins": {
|
||||
"wikimedia/composer-merge-plugin": true
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"SeedDMS\\Console\\": "seeddms/utils"
|
||||
},
|
||||
"classmap": [
|
||||
"seeddms/inc/inc.ClassTranslator.php",
|
||||
"seeddms/inc/inc.ClassSettings.php",
|
||||
"seeddms/inc/inc.Version.php",
|
||||
"seeddms/inc/inc.ClassViewCommon.php",
|
||||
"seeddms/inc/inc.ClassControllerCommon.php",
|
||||
"seeddms/inc/inc.ClassController.php",
|
||||
"seeddms/inc/inc.ClassSession.php",
|
||||
"seeddms/inc/inc.ClassUtilities.php",
|
||||
"seeddms/inc/inc.ClassExtensionMgr.php",
|
||||
"seeddms/inc/inc.ClassExtBase.php"
|
||||
]
|
||||
},
|
||||
"require": {
|
||||
"pear/http_request2": "^2",
|
||||
"robthree/twofactorauth": "^3.0",
|
||||
"php-mime-mail-parser/php-mime-mail-parser": "*",
|
||||
"robthree/twofactorauth": "^1.5",
|
||||
"slim/slim": "^4.0",
|
||||
"guzzlehttp/psr7": "*",
|
||||
"erusev/parsedown": "*",
|
||||
|
|
@ -55,25 +22,16 @@
|
|||
"pear/db": "*",
|
||||
"dragonmantank/cron-expression": "^3.1",
|
||||
"alecrabbit/php-console-colour": "*",
|
||||
"dragonmantank/cron-expression": "^3",
|
||||
"zf1/zend-search-lucene": "*",
|
||||
"symfony/http-foundation": "^7",
|
||||
"php-di/php-di": "^7",
|
||||
"hfig/mapi": "*",
|
||||
"symfony/http-foundation": "^5.4",
|
||||
"php-di/php-di": "^6.4",
|
||||
"slim/psr7": "^1.7",
|
||||
"chillerlan/php-qrcode": "^5.0",
|
||||
"bacon/bacon-qr-code": "^3.0",
|
||||
"seeddms/core": "dev-__CORE_BRANCH__",
|
||||
"seeddms/core": "dev-master",
|
||||
"seeddms/lucene": "dev-master",
|
||||
"seeddms/preview": "dev-master",
|
||||
"seeddms/sqlitefts": "dev-master",
|
||||
"seeddms/http_webdav_server": "dev-master",
|
||||
"wikimedia/composer-merge-plugin": "dev-master",
|
||||
"cache/memcached-adapter": "^1.2",
|
||||
"symfony/console": "^7.2",
|
||||
"twig/twig": "^3.0",
|
||||
"league/commonmark": "^2.7",
|
||||
"symfony/process": "^7.3",
|
||||
"symfony/http-client": "^7.4"
|
||||
"seeddms/http_webdav_server": "dev-master"
|
||||
},
|
||||
"require-dev": {
|
||||
"composer/composer": "dev-main"
|
||||
|
|
@ -114,19 +72,5 @@
|
|||
"symlink": false
|
||||
}
|
||||
}
|
||||
],
|
||||
"extra": {
|
||||
"merge-plugin": {
|
||||
"include": [
|
||||
"composer.local.json"
|
||||
],
|
||||
"recurse": false,
|
||||
"replace": true,
|
||||
"ignore-duplicates": true,
|
||||
"merge-dev": true,
|
||||
"merge-extra": false,
|
||||
"merge-extra-deep": false,
|
||||
"merge-scripts": true
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
|
|||
146
composer.json
146
composer.json
|
|
@ -1,146 +0,0 @@
|
|||
{
|
||||
"name": "seeddms/dms",
|
||||
"description": "Open Source Document Management System",
|
||||
"type": "project",
|
||||
"license": "GPL 2",
|
||||
"authors": [
|
||||
{
|
||||
"name": "Uwe Steinmann",
|
||||
"email": "steinm@debian.org"
|
||||
}
|
||||
],
|
||||
"minimum-stability": "stable",
|
||||
"config": {
|
||||
"platform": {
|
||||
"php": "8.2"
|
||||
},
|
||||
"allow-plugins": {
|
||||
"composer/package-versions-deprecated": true,
|
||||
"wikimedia/composer-merge-plugin": true
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Seeddms\\Console\\": "utils"
|
||||
},
|
||||
"classmap": [
|
||||
"inc/inc.ClassTranslator.php",
|
||||
"inc/inc.ClassSettings.php",
|
||||
"inc/inc.Version.php",
|
||||
"inc/inc.ClassViewCommon.php",
|
||||
"inc/inc.ClassControllerCommon.php",
|
||||
"inc/inc.ClassController.php",
|
||||
"inc/inc.ClassSession.php",
|
||||
"inc/inc.ClassUtilities.php",
|
||||
"inc/inc.ClassExtensionMgr.php",
|
||||
"inc/inc.ClassExtBase.php"
|
||||
]
|
||||
},
|
||||
"require": {
|
||||
"php": ">=8.2.0",
|
||||
"phing/phing": "3.*",
|
||||
"pear/http_request2": "^2",
|
||||
"robthree/twofactorauth": "^3.0",
|
||||
"php-mime-mail-parser/php-mime-mail-parser": "*",
|
||||
"slim/slim": "^4.0",
|
||||
"guzzlehttp/psr7": "*",
|
||||
"erusev/parsedown": "*",
|
||||
"erusev/parsedown-extra": "*",
|
||||
"mibe/feedwriter": "^1.1",
|
||||
"phpoffice/phpspreadsheet": "*",
|
||||
"sabre/xml": "*",
|
||||
"sabre/dav": "^4.",
|
||||
"pear/log": "*",
|
||||
"pear/mail": "*",
|
||||
"pear/mail_mime": "*",
|
||||
"pear/net_smtp": "*",
|
||||
"pear/auth_sasl": "*",
|
||||
"pear/db": "*",
|
||||
"dragonmantank/cron-expression": "^3.1",
|
||||
"alecrabbit/php-console-colour": "*",
|
||||
"zf1/zend-search-lucene": "*",
|
||||
"symfony/http-foundation": "^7",
|
||||
"php-di/php-di": "^7",
|
||||
"hfig/mapi": "*",
|
||||
"slim/psr7": "^1.7",
|
||||
"chillerlan/php-qrcode": "^5.0",
|
||||
"bacon/bacon-qr-code": "^3.0",
|
||||
"seeddms/core": "dev-seeddms-5.1.x",
|
||||
"seeddms/lucene": "dev-master",
|
||||
"seeddms/preview": "dev-master",
|
||||
"seeddms/sqlitefts": "dev-master",
|
||||
"seeddms/http_webdav_server": "dev-master",
|
||||
"wikimedia/composer-merge-plugin": "dev-master",
|
||||
"cache/memcached-adapter": "^1.2",
|
||||
"symfony/console": "^7.2",
|
||||
"twig/twig": "^3.0",
|
||||
"league/commonmark": "^2.7",
|
||||
"symfony/process": "^7.3",
|
||||
"symfony/http-client": "^7.4"
|
||||
},
|
||||
"require-dev": {
|
||||
"composer/composer": "dev-main",
|
||||
"behat/mink": "^1",
|
||||
"behat/mink-selenium2-driver": "^1",
|
||||
"dmore/chrome-mink-driver": "^2",
|
||||
"friendsofphp/php-cs-fixer": "^3",
|
||||
"phpunit/phpunit": "9.5.9",
|
||||
"squizlabs/php_codesniffer": "^4",
|
||||
"phpstan/phpstan": "^2.1",
|
||||
"pear/archive_tar": "*"
|
||||
},
|
||||
"repositories": [
|
||||
{
|
||||
"type": "path",
|
||||
"url": "../core",
|
||||
"options": {
|
||||
"symlink": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "path",
|
||||
"url": "../lucene",
|
||||
"options": {
|
||||
"symlink": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "path",
|
||||
"url": "../preview",
|
||||
"options": {
|
||||
"symlink": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "path",
|
||||
"url": "../sqlitefts",
|
||||
"options": {
|
||||
"symlink": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "path",
|
||||
"url": "../http_webdav_server",
|
||||
"options": {
|
||||
"symlink": true
|
||||
}
|
||||
}
|
||||
],
|
||||
"scripts": {
|
||||
"phpcs": "phpcs -s"
|
||||
},
|
||||
"extra": {
|
||||
"merge-plugin": {
|
||||
"include": [
|
||||
"composer.local.json"
|
||||
],
|
||||
"recurse": false,
|
||||
"replace": true,
|
||||
"ignore-duplicates": true,
|
||||
"merge-dev": true,
|
||||
"merge-extra": false,
|
||||
"merge-extra-deep": false,
|
||||
"merge-scripts": true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,27 +0,0 @@
|
|||
<VirtualHost _default_:443>
|
||||
ServerName _DOMAIN_
|
||||
ErrorLog /var/log/apache2/seeddms-error.log
|
||||
CustomLog /var/log/apache2/seeddms-access.log combined
|
||||
|
||||
DocumentRoot _INSTALL_PATH_/www
|
||||
|
||||
SSLEngine on
|
||||
SSLCertificateFile /etc/ssl/certs/ssl-cert-snakeoil.pem
|
||||
SSLCertificateKeyFile /etc/ssl/private/ssl-cert-snakeoil.key
|
||||
# SSLCertificateChainFile /just/if/needed/fullchain.cer
|
||||
|
||||
<Directory _INSTALL_PATH_>
|
||||
Options Indexes FollowSymLinks MultiViews
|
||||
AllowOverride All
|
||||
Require all granted
|
||||
</Directory>
|
||||
|
||||
<FilesMatch \.php$>
|
||||
# Apache 2.4.10+ can proxy to unix socket
|
||||
SetHandler "proxy:unix:/var/run/php/php8.2-fpm.sock|fcgi://localhost"
|
||||
</FilesMatch>
|
||||
|
||||
# Consider to install the webdav_checkout extension
|
||||
Alias /checkout _INSTALL_PATH_/www/ext/webdav_checkout/op/remote.php
|
||||
|
||||
</VirtualHost>
|
||||
|
|
@ -296,7 +296,7 @@
|
|||
updateNotifyTime = "86400"
|
||||
extraPath = ""
|
||||
maxExecutionTime = "30"
|
||||
cmdTimeout = "1"
|
||||
cmdTimeout = "10"
|
||||
/>
|
||||
<!--
|
||||
- enableNotificationAppRev: set to true if reviewers and approvers shall be informed about a pending review/approval
|
||||
|
|
|
|||
|
|
@ -52,6 +52,7 @@ class SeedDMS_Controller_AddDocument extends SeedDMS_Controller_Common {
|
|||
$sequence = $this->getParam('sequence');
|
||||
$reviewers = $this->getParam('reviewers');
|
||||
$approvers = $this->getParam('approvers');
|
||||
$recipients = $this->getParam('recipients');
|
||||
$reqversion = $this->getParam('reqversion');
|
||||
$version_comment = $this->getParam('versioncomment');
|
||||
$attributes = $this->getParam('attributes');
|
||||
|
|
@ -160,6 +161,7 @@ class SeedDMS_Controller_AddDocument extends SeedDMS_Controller_Common {
|
|||
$workflow = $this->getParam('workflow');
|
||||
$notificationgroups = $this->getParam('notificationgroups');
|
||||
$notificationusers = $this->getParam('notificationusers');
|
||||
$initialdocumentstatus = $this->getParam('initialdocumentstatus');
|
||||
$maxsizeforfulltext = $this->getParam('maxsizeforfulltext');
|
||||
$defaultaccessdocs = $this->getParam('defaultaccessdocs');
|
||||
|
||||
|
|
@ -170,7 +172,7 @@ class SeedDMS_Controller_AddDocument extends SeedDMS_Controller_Common {
|
|||
$cats, $userfiletmp, utf8_basename($userfilename),
|
||||
$filetype, $userfiletype, $sequence,
|
||||
$reviewers, $approvers, $reqversion,
|
||||
$version_comment, $attributes, $attributes_version, $workflow);
|
||||
$version_comment, $attributes, $attributes_version, $workflow, $initialdocumentstatus);
|
||||
|
||||
if (is_bool($res) && !$res) {
|
||||
$this->errormsg = "error_occured";
|
||||
|
|
@ -187,6 +189,24 @@ class SeedDMS_Controller_AddDocument extends SeedDMS_Controller_Common {
|
|||
}
|
||||
}
|
||||
|
||||
$lc = $document->getLatestContent();
|
||||
if($recipients) {
|
||||
if($recipients['i']) {
|
||||
foreach($recipients['i'] as $uid) {
|
||||
if($u = $dms->getUser($uid)) {
|
||||
$res = $lc->addIndRecipient($u, $user);
|
||||
}
|
||||
}
|
||||
}
|
||||
if($recipients['g']) {
|
||||
foreach($recipients['g'] as $gid) {
|
||||
if($g = $dms->getGroup($gid)) {
|
||||
$res = $lc->addGrpRecipient($g, $user);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Add a default notification for the owner of the document */
|
||||
if($settings->_enableOwnerNotification) {
|
||||
$res = $document->addNotify($owner->getID(), true);
|
||||
|
|
|
|||
|
|
@ -40,62 +40,76 @@ class SeedDMS_Controller_ApproveDocument extends SeedDMS_Controller_Common {
|
|||
$this->oldstatus = $overallStatus['status'];
|
||||
$this->newstatus = $this->oldstatus;
|
||||
|
||||
if ($approvaltype == "ind") {
|
||||
$approvalLogID = $content->setApprovalByInd($user, $user, $approvalstatus, $approvalcomment, $approvalfile);
|
||||
} elseif ($approvaltype == "grp") {
|
||||
$approvalLogID = $content->setApprovalByGrp($approvalgroup, $user, $approvalstatus, $approvalcomment, $approvalfile);
|
||||
} else {
|
||||
$this->errormsg = "approval_wrong_type";
|
||||
return false;
|
||||
}
|
||||
if($approvalLogID === false || 0 > $approvalLogID) {
|
||||
$this->errormsg = "approval_update_failed";
|
||||
return false;
|
||||
if(!$this->callHook('preApproveDocument', $content)) {
|
||||
}
|
||||
|
||||
if($approvalstatus == -1) {
|
||||
$this->newstatus = S_REJECTED;
|
||||
if($content->setStatus(S_REJECTED, $approvalcomment, $user)) {
|
||||
if(isset($GLOBALS['SEEDDMS_HOOKS']['approveDocument'])) {
|
||||
foreach($GLOBALS['SEEDDMS_HOOKS']['approveDocument'] as $hookObj) {
|
||||
if (method_exists($hookObj, 'postApproveDocument')) {
|
||||
$hookObj->postApproveDocument(null, $content, S_REJECTED);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$docApprovalStatus = $content->getApprovalStatus();
|
||||
if (is_bool($docApprovalStatus) && !$docApprovalStatus) {
|
||||
$this->errormsg = "cannot_retrieve_approval_snapshot";
|
||||
$result = $this->callHook('approveDocument', $content);
|
||||
if($result === null) {
|
||||
if ($approvaltype == "ind") {
|
||||
$approvalLogID = $content->setApprovalByInd($user, $user, $approvalstatus, $approvalcomment, $approvalfile);
|
||||
} elseif ($approvaltype == "grp") {
|
||||
$approvalLogID = $content->setApprovalByGrp($approvalgroup, $user, $approvalstatus, $approvalcomment, $approvalfile);
|
||||
} else {
|
||||
$this->errormsg = "approval_wrong_type";
|
||||
return false;
|
||||
}
|
||||
$approvalCT = 0;
|
||||
$approvalTotal = 0;
|
||||
foreach ($docApprovalStatus as $drstat) {
|
||||
if ($drstat["status"] == 1) {
|
||||
$approvalCT++;
|
||||
}
|
||||
if ($drstat["status"] != -2) {
|
||||
$approvalTotal++;
|
||||
}
|
||||
if($approvalLogID === false || 0 > $approvalLogID) {
|
||||
$this->errormsg = "approval_update_failed";
|
||||
return false;
|
||||
}
|
||||
// If all approvals have been received and there are no rejections, retrieve a
|
||||
// count of the approvals required for this document.
|
||||
if ($approvalCT == $approvalTotal) {
|
||||
// Change the status to released.
|
||||
$this->newstatus=S_RELEASED;
|
||||
if($content->setStatus($this->newstatus, getMLText("automatic_status_update"), $user)) {
|
||||
}
|
||||
|
||||
$result = $this->callHook('approveUpdateDocumentStatus', $content);
|
||||
if($result === null) {
|
||||
if($approvalstatus == -1) {
|
||||
$this->newstatus = S_REJECTED;
|
||||
if($content->setStatus(S_REJECTED, $approvalcomment, $user)) {
|
||||
if(isset($GLOBALS['SEEDDMS_HOOKS']['approveDocument'])) {
|
||||
foreach($GLOBALS['SEEDDMS_HOOKS']['approveDocument'] as $hookObj) {
|
||||
if (method_exists($hookObj, 'postApproveDocument')) {
|
||||
$hookObj->postApproveDocument(null, $content, S_RELEASED);
|
||||
$hookObj->postApproveDocument(null, $content, S_REJECTED);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$docApprovalStatus = $content->getApprovalStatus();
|
||||
if (is_bool($docApprovalStatus) && !$docApprovalStatus) {
|
||||
$this->errormsg = "cannot_retrieve_approval_snapshot";
|
||||
return false;
|
||||
}
|
||||
$approvalCT = 0;
|
||||
$approvalTotal = 0;
|
||||
foreach ($docApprovalStatus as $drstat) {
|
||||
if ($drstat["status"] == 1) {
|
||||
$approvalCT++;
|
||||
}
|
||||
if ($drstat["status"] != -2) {
|
||||
$approvalTotal++;
|
||||
}
|
||||
}
|
||||
// If all approvals have been received and there are no rejections, retrieve a
|
||||
// count of the approvals required for this document.
|
||||
if ($approvalCT == $approvalTotal) {
|
||||
// Change the status to released.
|
||||
$this->newstatus=S_RELEASED;
|
||||
if($content->setStatus($this->newstatus, getMLText("automatic_status_update"), $user)) {
|
||||
if(isset($GLOBALS['SEEDDMS_HOOKS']['approveDocument'])) {
|
||||
foreach($GLOBALS['SEEDDMS_HOOKS']['approveDocument'] as $hookObj) {
|
||||
if (method_exists($hookObj, 'postApproveDocument')) {
|
||||
$hookObj->postApproveDocument(null, $content, S_RELEASED);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(!$this->callHook('postApproveDocument', $content)) {
|
||||
}
|
||||
|
||||
return true;
|
||||
} /* }}} */
|
||||
}
|
||||
|
||||
|
|
|
|||
114
controllers/class.CheckInDocument.php
Normal file
114
controllers/class.CheckInDocument.php
Normal file
|
|
@ -0,0 +1,114 @@
|
|||
<?php
|
||||
/**
|
||||
* Implementation of CheckInDocument controller
|
||||
*
|
||||
* @category DMS
|
||||
* @package SeedDMS
|
||||
* @license GPL 2
|
||||
* @version @version@
|
||||
* @author Uwe Steinmann <uwe@steinmann.cx>
|
||||
* @copyright Copyright (C) 2010-2024 Uwe Steinmann
|
||||
* @version Release: @package_version@
|
||||
*/
|
||||
|
||||
/**
|
||||
* Class which does the busines logic for downloading a document
|
||||
*
|
||||
* @category DMS
|
||||
* @package SeedDMS
|
||||
* @author Uwe Steinmann <uwe@steinmann.cx>
|
||||
* @copyright Copyright (C) 2010-2024 Uwe Steinmann
|
||||
* @version Release: @package_version@
|
||||
*/
|
||||
class SeedDMS_Controller_CheckInDocument extends SeedDMS_Controller_Common {
|
||||
|
||||
public function run() { /* {{{ */
|
||||
$name = $this->getParam('name');
|
||||
$comment = $this->getParam('comment');
|
||||
|
||||
/* Call preCheckInDocument early, because it might need to modify some
|
||||
* of the parameters.
|
||||
*/
|
||||
if(false === $this->callHook('preCheckInDocument', $this->params['document'])) {
|
||||
if(empty($this->errormsg))
|
||||
$this->errormsg = 'hook_preCheckInDocument_failed';
|
||||
return null;
|
||||
}
|
||||
|
||||
$comment = $this->getParam('comment');
|
||||
$dms = $this->params['dms'];
|
||||
$user = $this->params['user'];
|
||||
$document = $this->params['document'];
|
||||
$settings = $this->params['settings'];
|
||||
$fulltextservice = $this->params['fulltextservice'];
|
||||
$folder = $this->params['folder'];
|
||||
$userfiletmp = $this->getParam('userfiletmp');
|
||||
$userfilename = $this->getParam('userfilename');
|
||||
$filetype = $this->getParam('filetype');
|
||||
$userfiletype = $this->getParam('userfiletype');
|
||||
$reviewers = $this->getParam('reviewers');
|
||||
$approvers = $this->getParam('approvers');
|
||||
$recipients = $this->getParam('recipients');
|
||||
$reqversion = $this->getParam('reqversion');
|
||||
$comment = $this->getParam('comment');
|
||||
$attributes = $this->getParam('attributes');
|
||||
$workflow = $this->getParam('workflow');
|
||||
$maxsizeforfulltext = $this->getParam('maxsizeforfulltext');
|
||||
$initialdocumentstatus = $this->getParam('initialdocumentstatus');
|
||||
|
||||
$content = $this->callHook('checkinDocument');
|
||||
if($content === null) {
|
||||
if($contentResult=$document->checkIn($comment, $user, $reviewers, $approvers, $version=0, $attributes, $workflow, $initialdocumentstatus)) {
|
||||
|
||||
if ($this->hasParam('expires')) {
|
||||
if($document->setExpires($this->getParam('expires'))) {
|
||||
} else {
|
||||
}
|
||||
}
|
||||
|
||||
if(!empty($recipients['i'])) {
|
||||
foreach($recipients['i'] as $uid) {
|
||||
if($u = $dms->getUser($uid)) {
|
||||
$res = $contentResult->getContent()->addIndRecipient($u, $user);
|
||||
}
|
||||
}
|
||||
}
|
||||
if(!empty($recipients['g'])) {
|
||||
foreach($recipients['g'] as $gid) {
|
||||
if($g = $dms->getGroup($gid)) {
|
||||
$res = $contentResult->getContent()->addGrpRecipient($g, $user);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$content = $contentResult->getContent();
|
||||
} else {
|
||||
$this->errormsg = 'error_checkin_document';
|
||||
$result = false;
|
||||
}
|
||||
} elseif($result === false) {
|
||||
if(empty($this->errormsg))
|
||||
$this->errormsg = 'hook_checkinDocument_failed';
|
||||
return false;
|
||||
}
|
||||
|
||||
if($fulltextservice && ($index = $fulltextservice->Indexer()) && $content) {
|
||||
$idoc = $fulltextservice->IndexedDocument($document);
|
||||
if(false !== $this->callHook('preIndexDocument', $document, $idoc)) {
|
||||
$lucenesearch = $fulltextservice->Search();
|
||||
if($hit = $lucenesearch->getDocument((int) $document->getId())) {
|
||||
$index->delete($hit->id);
|
||||
}
|
||||
$index->addDocument($idoc);
|
||||
$index->commit();
|
||||
}
|
||||
}
|
||||
|
||||
if(false === $this->callHook('postCheckInDocument', $document, $content)) {
|
||||
}
|
||||
|
||||
return $content;
|
||||
} /* }}} */
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -23,6 +23,8 @@
|
|||
class SeedDMS_Controller_ClearCache extends SeedDMS_Controller_Common {
|
||||
|
||||
public function run() {
|
||||
$dms = $this->params['dms'];
|
||||
$user = $this->params['user'];
|
||||
$settings = $this->params['settings'];
|
||||
$post = $this->params['post'];
|
||||
|
||||
|
|
|
|||
108
controllers/class.Cron.php
Normal file
108
controllers/class.Cron.php
Normal file
|
|
@ -0,0 +1,108 @@
|
|||
<?php
|
||||
/**
|
||||
* Implementation of Cron controller
|
||||
*
|
||||
* @category DMS
|
||||
* @package SeedDMS
|
||||
* @license GPL 2
|
||||
* @version @version@
|
||||
* @author Uwe Steinmann <uwe@steinmann.cx>
|
||||
* @copyright Copyright (C) 2010-2020 Uwe Steinmann
|
||||
* @version Release: @package_version@
|
||||
*/
|
||||
|
||||
/**
|
||||
* Class which does the busines logic for the regular cron job
|
||||
*
|
||||
* @category DMS
|
||||
* @package SeedDMS
|
||||
* @author Uwe Steinmann <uwe@steinmann.cx>
|
||||
* @copyright Copyright (C) 2010-2020 Uwe Steinmann
|
||||
* @version Release: @package_version@
|
||||
*/
|
||||
class SeedDMS_Controller_Cron extends SeedDMS_Controller_Common {
|
||||
|
||||
public function run() { /* {{{ */
|
||||
$dms = $this->params['dms'];
|
||||
$user = $this->params['user'];
|
||||
$settings = $this->params['settings'];
|
||||
$logger = $this->params['logger'];
|
||||
$mode = $this->params['mode'];
|
||||
$seltask = $this->params['task'];
|
||||
$db = $dms->getDb();
|
||||
|
||||
$scheduler = new SeedDMS_Scheduler($db);
|
||||
$tasks = $scheduler->getTasks();
|
||||
|
||||
$jsonarr = [];
|
||||
foreach($tasks as $task) {
|
||||
if($seltask && $seltask != $task->getExtension()."::".$task->getTask())
|
||||
continue;
|
||||
if(isset($GLOBALS['SEEDDMS_SCHEDULER']['tasks'][$task->getExtension()]) && is_object($taskobj = resolveTask($GLOBALS['SEEDDMS_SCHEDULER']['tasks'][$task->getExtension()][$task->getTask()]))) {
|
||||
$arr = array(
|
||||
'extension'=>$task->getExtension(),
|
||||
'name'=>$task->getTask(),
|
||||
'mode'=>$mode,
|
||||
'disabled' => (bool) $task->getDisabled(),
|
||||
'isdue' => $task->isDue(),
|
||||
);
|
||||
switch($mode) {
|
||||
case "run":
|
||||
case "dryrun":
|
||||
if(method_exists($taskobj, 'execute')) {
|
||||
if(!$task->getDisabled() && $task->isDue()) {
|
||||
if($mode == 'run') {
|
||||
/* Schedule the next run right away to prevent a second execution
|
||||
* of the task when the cron job of the scheduler is called before
|
||||
* the last run was finished. The task itself can still be scheduled
|
||||
* to fast, but this is up to the admin of seeddms.
|
||||
*/
|
||||
$task->updateLastNextRun();
|
||||
if($taskobj->execute($task)) {
|
||||
add_log_line("Execution of task ".$task->getExtension()."::".$task->getTask()." successful.");
|
||||
$arr['success'] = true;
|
||||
} else {
|
||||
add_log_line("Execution of task ".$task->getExtension()."::".$task->getTask()." failed, task has been disabled.", PEAR_LOG_ERR);
|
||||
$arr['success'] = false;
|
||||
$task->setDisabled(1);
|
||||
}
|
||||
} elseif($mode == 'dryrun') {
|
||||
$arr['success'] = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case "check":
|
||||
$arr['error'] = false;
|
||||
if(!method_exists($taskobj, 'execute')) {
|
||||
$arr['error'] = true;
|
||||
$arr['messages'][] = 'Missing method execute()';
|
||||
}
|
||||
if(get_parent_class($taskobj) != 'SeedDMS_SchedulerTaskBase') {
|
||||
$arr['error'] = true;
|
||||
$arr['error'][] = "Wrong parent class";
|
||||
}
|
||||
break;
|
||||
case "list":
|
||||
default:
|
||||
header("Content-Type: application/json");
|
||||
$arr['nextrun']=$task->getNextRun();
|
||||
$arr['frequency']=$task->getFrequency();
|
||||
$arr['params']=array();
|
||||
if($params = $task->getParameter()) {
|
||||
foreach($params as $key=>$value) {
|
||||
$p = $taskobj->getAdditionalParamByName($key);
|
||||
$arr['params'][$key] = ($p['type'] == 'password') ? '*******' : $value;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
$jsonarr[] = $arr;
|
||||
}
|
||||
}
|
||||
echo json_encode($jsonarr);
|
||||
|
||||
return true;
|
||||
} /* }}} */
|
||||
}
|
||||
|
||||
|
|
@ -22,49 +22,192 @@
|
|||
*/
|
||||
class SeedDMS_Controller_Download extends SeedDMS_Controller_Common {
|
||||
|
||||
public function run() {
|
||||
public function version() { /* {{{ */
|
||||
$dms = $this->params['dms'];
|
||||
$version = $this->params['version'];
|
||||
$document = $this->params['document'];
|
||||
if($version < 1) {
|
||||
$content = $this->callHook('documentLatestContent', $document);
|
||||
if($content === null)
|
||||
$content = $document->getLatestContent();
|
||||
} else {
|
||||
$content = $this->callHook('documentContent', $document, $version);
|
||||
if($content === null)
|
||||
$content = $document->getContentByVersion($version);
|
||||
}
|
||||
if (!is_object($content)) {
|
||||
$this->errormsg = 'invalid_version';
|
||||
return false;
|
||||
}
|
||||
/* set params['content'] for compatiblity with older extensions which
|
||||
* expect the content in the controller
|
||||
*/
|
||||
$this->params['content'] = $content;
|
||||
if(null === $this->callHook('version')) {
|
||||
if(file_exists($dms->contentDir . $content->getPath())) {
|
||||
header("Content-Transfer-Encoding: binary");
|
||||
$efilename = rawurlencode($content->getOriginalFileName());
|
||||
header("Content-Disposition: attachment; filename=\"" . $efilename . "\"; filename*=UTF-8''".$efilename);
|
||||
header("Content-Type: " . $content->getMimeType());
|
||||
header("Cache-Control: must-revalidate");
|
||||
header("ETag: ".$content->getChecksum());
|
||||
|
||||
sendFile($dms->contentDir . $content->getPath());
|
||||
}
|
||||
}
|
||||
return true;
|
||||
} /* }}} */
|
||||
|
||||
public function file() { /* {{{ */
|
||||
$dms = $this->params['dms'];
|
||||
$file = $this->params['file'];
|
||||
|
||||
if(null === $this->callHook('file')) {
|
||||
if(file_exists($dms->contentDir . $file->getPath())) {
|
||||
header("Content-Transfer-Encoding: binary");
|
||||
header("Content-Disposition: attachment; filename=\"" . $file->getOriginalFileName() . "\"");
|
||||
header("Content-Type: " . $file->getMimeType());
|
||||
header("Cache-Control: must-revalidate");
|
||||
|
||||
sendFile($dms->contentDir . $file->getPath());
|
||||
}
|
||||
}
|
||||
return true;
|
||||
} /* }}} */
|
||||
|
||||
public function archive() { /* {{{ */
|
||||
$dms = $this->params['dms'];
|
||||
$filename = $this->params['file'];
|
||||
$basedir = $this->params['basedir'];
|
||||
|
||||
if(null === $this->callHook('archive')) {
|
||||
if(file_exists($basedir . $filename)) {
|
||||
header('Content-Description: File Transfer');
|
||||
header("Content-Type: application/zip");
|
||||
header("Content-Transfer-Encoding: binary");
|
||||
$efilename = rawurlencode($filename);
|
||||
header("Content-Disposition: attachment; filename=\"" .$efilename . "\"; filename*=UTF-8''".$efilename);
|
||||
header("Cache-Control: public");
|
||||
|
||||
sendFile($basedir .$filename );
|
||||
}
|
||||
}
|
||||
return true;
|
||||
} /* }}} */
|
||||
|
||||
public function log() { /* {{{ */
|
||||
$dms = $this->params['dms'];
|
||||
$filename = $this->params['file'];
|
||||
$basedir = $this->params['basedir'];
|
||||
|
||||
if(null === $this->callHook('log')) {
|
||||
if(file_exists($basedir . $filename)) {
|
||||
header("Content-Type: text/plain; name=\"" . $filename . "\"");
|
||||
header("Content-Transfer-Encoding: binary");
|
||||
$efilename = rawurlencode($filename);
|
||||
header("Content-Disposition: attachment; filename=\"" .$efilename . "\"; filename*=UTF-8''".$efilename);
|
||||
header("Cache-Control: must-revalidate");
|
||||
|
||||
sendFile($basedir.$filename);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
} /* }}} */
|
||||
|
||||
public function sqldump() { /* {{{ */
|
||||
$dms = $this->params['dms'];
|
||||
$filename = $this->params['file'];
|
||||
$basedir = $this->params['basedir'];
|
||||
|
||||
if(null === $this->callHook('sqldump')) {
|
||||
if(file_exists($basedir . $filename)) {
|
||||
header("Content-Type: application/zip");
|
||||
header("Content-Transfer-Encoding: binary");
|
||||
$efilename = rawurlencode($filename);
|
||||
header("Content-Disposition: attachment; filename=\"" .$efilename . "\"; filename*=UTF-8''".$efilename);
|
||||
header("Cache-Control: must-revalidate");
|
||||
|
||||
sendFile($basedir.$filename);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
} /* }}} */
|
||||
|
||||
public function approval() { /* {{{ */
|
||||
$dms = $this->params['dms'];
|
||||
$document = $this->params['document'];
|
||||
$logid = $this->params['approvelogid'];
|
||||
|
||||
$filename = $dms->contentDir . $document->getDir().'a'.$logid;
|
||||
if (!file_exists($filename) ) {
|
||||
$this->error = 1;
|
||||
return false;
|
||||
}
|
||||
|
||||
if(null === $this->callHook('approval')) {
|
||||
$finfo = finfo_open(FILEINFO_MIME_TYPE);
|
||||
$mimetype = finfo_file($finfo, $filename);
|
||||
|
||||
header("Content-Type: ".$mimetype);
|
||||
header("Content-Transfer-Encoding: binary");
|
||||
header("Content-Disposition: attachment; filename=\"approval-" . $document->getID()."-".(int) $_GET['approvelogid'] . get_extension($mimetype) . "\"");
|
||||
header("Cache-Control: must-revalidate");
|
||||
sendFile($filename);
|
||||
}
|
||||
return true;
|
||||
} /* }}} */
|
||||
|
||||
public function review() { /* {{{ */
|
||||
$dms = $this->params['dms'];
|
||||
$document = $this->params['document'];
|
||||
$logid = $this->params['reviewlogid'];
|
||||
|
||||
$filename = $dms->contentDir . $document->getDir().'r'.$logid;
|
||||
if (!file_exists($filename) ) {
|
||||
$this->error = 1;
|
||||
return false;
|
||||
}
|
||||
|
||||
if(null === $this->callHook('review')) {
|
||||
$finfo = finfo_open(FILEINFO_MIME_TYPE);
|
||||
$mimetype = finfo_file($finfo, $filename);
|
||||
|
||||
header("Content-Type: ".$mimetype);
|
||||
header("Content-Transfer-Encoding: binary");
|
||||
header("Content-Length: " . filesize($filename ));
|
||||
header("Content-Disposition: attachment; filename=\"review-" . $document->getID()."-".(int) $_GET['reviewlogid'] . get_extension($mimetype) . "\"");
|
||||
header("Cache-Control: must-revalidate");
|
||||
sendFile($filename);
|
||||
}
|
||||
return true;
|
||||
} /* }}} */
|
||||
|
||||
public function run() { /* {{{ */
|
||||
$dms = $this->params['dms'];
|
||||
$type = $this->params['type'];
|
||||
|
||||
switch($type) {
|
||||
case "version":
|
||||
if(empty($this->params['content'])) {
|
||||
$version = $this->params['version'];
|
||||
$document = $this->params['document'];
|
||||
if($version < 1) {
|
||||
$content = $this->callHook('documentLatestContent', $document);
|
||||
if($content === null)
|
||||
$content = $document->getLatestContent();
|
||||
} else {
|
||||
$content = $this->callHook('documentContent', $document, $version);
|
||||
if($content === null)
|
||||
$content = $document->getContentByVersion($version);
|
||||
}
|
||||
if (!is_object($content)) {
|
||||
$this->errormsg = 'invalid_version';
|
||||
return false;
|
||||
}
|
||||
/* set params['content'] for compatiblity with older extensions which
|
||||
* expect the content in the controller
|
||||
*/
|
||||
$this->params['content'] = $content;
|
||||
} else {
|
||||
$content = $this->params['content'];
|
||||
}
|
||||
if(null === $this->callHook('version')) {
|
||||
if(file_exists($dms->contentDir . $content->getPath())) {
|
||||
header("Content-Transfer-Encoding: binary");
|
||||
$efilename = rawurlencode($content->getOriginalFileName());
|
||||
header("Content-Disposition: attachment; filename=\"" . $efilename . "\"; filename*=UTF-8''".$efilename);
|
||||
header("Content-Type: " . $content->getMimeType());
|
||||
header("Cache-Control: must-revalidate");
|
||||
header("ETag: ".$content->getChecksum());
|
||||
|
||||
sendFile($dms->contentDir.$content->getPath());
|
||||
}
|
||||
}
|
||||
return $this->version();
|
||||
break;
|
||||
case "file":
|
||||
return $this->file();
|
||||
break;
|
||||
case "archive":
|
||||
return $this->archive();
|
||||
break;
|
||||
case "log":
|
||||
return $this->log();
|
||||
break;
|
||||
case "sqldump":
|
||||
return $this->sqldump();
|
||||
break;
|
||||
case "approval":
|
||||
return $this->approval();
|
||||
break;
|
||||
case "review":
|
||||
return $this->review();
|
||||
break;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
} /* }}} */
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,123 +0,0 @@
|
|||
<?php
|
||||
/**
|
||||
* Implementation of EditAttributes controller
|
||||
*
|
||||
* @category DMS
|
||||
* @package SeedDMS
|
||||
* @license GPL 2
|
||||
* @version @version@
|
||||
* @author Uwe Steinmann <uwe@steinmann.cx>
|
||||
* @copyright Copyright (C) 2010-2013 Uwe Steinmann
|
||||
* @version Release: @package_version@
|
||||
*/
|
||||
|
||||
/**
|
||||
* Class which does the busines logic for editing the version attributes
|
||||
*
|
||||
* @category DMS
|
||||
* @package SeedDMS
|
||||
* @author Uwe Steinmann <uwe@steinmann.cx>
|
||||
* @copyright Copyright (C) 2010-2025 Uwe Steinmann
|
||||
* @version Release: @package_version@
|
||||
*/
|
||||
class SeedDMS_Controller_EditAttributes extends SeedDMS_Controller_Common {
|
||||
|
||||
public function run() {
|
||||
$dms = $this->params['dms'];
|
||||
$user = $this->params['user'];
|
||||
$settings = $this->params['settings'];
|
||||
$document = $this->params['document'];
|
||||
$version = $this->params['version'];
|
||||
|
||||
if(false === $this->callHook('preEditAttributes')) {
|
||||
if(empty($this->errormsg))
|
||||
$this->errormsg = 'hook_preEditAttributes_failed';
|
||||
return null;
|
||||
}
|
||||
|
||||
$result = $this->callHook('editAttributes', $version);
|
||||
if($result === null) {
|
||||
$attributes = $this->params['attributes'];
|
||||
$oldattributes = $version->getAttributes();
|
||||
if($attributes) {
|
||||
foreach($attributes as $attrdefid=>$attribute) {
|
||||
if($attrdef = $dms->getAttributeDefinition($attrdefid)) {
|
||||
if(null === ($ret = $this->callHook('validateAttribute', $attrdef, $attribute))) {
|
||||
if($attribute) {
|
||||
switch($attrdef->getType()) {
|
||||
case SeedDMS_Core_AttributeDefinition::type_date:
|
||||
if(is_array($attribute))
|
||||
$attribute = array_map(fn($value): string => date('Y-m-d', makeTsFromDate($value)), $attribute);
|
||||
else
|
||||
$attribute = date('Y-m-d', makeTsFromDate($attribute));
|
||||
break;
|
||||
case SeedDMS_Core_AttributeDefinition::type_folder:
|
||||
if(is_array($attribute))
|
||||
$attribute = array_map(fn($value): object => $dms->getFolder((int) $value), $attribute);
|
||||
else
|
||||
$attribute = $dms->getFolder((int) $attribute);
|
||||
break;
|
||||
case SeedDMS_Core_AttributeDefinition::type_document:
|
||||
if(is_array($attribute))
|
||||
$attribute = array_map(fn($value): object => $dms->getDocument((int) $value), $attribute);
|
||||
else
|
||||
$attribute = $dms->getDocument((int) $attribute);
|
||||
break;
|
||||
case SeedDMS_Core_AttributeDefinition::type_user:
|
||||
if(is_array($attribute))
|
||||
$attribute = array_map(fn($value): object => $dms->getUser((int) $value), $attribute);
|
||||
else
|
||||
$attribute = $dms->getUser((int) $attribute);
|
||||
break;
|
||||
case SeedDMS_Core_AttributeDefinition::type_group:
|
||||
if(is_array($attribute))
|
||||
$attribute = array_map(fn($value): object => $dms->getGroup((int) $value), $attribute);
|
||||
else
|
||||
$attribute = $dms->getGroup((int) $attribute);
|
||||
break;
|
||||
}
|
||||
if(!$attrdef->validate($attribute, $version, false)) {
|
||||
$this->errormsg = getAttributeValidationText($attrdef->getValidationError(), $attrdef->getName(), $attribute);
|
||||
return false;
|
||||
}
|
||||
|
||||
if(!isset($oldattributes[$attrdefid]) || $attribute != $oldattributes[$attrdefid]->getValue()) {
|
||||
if(!$version->setAttributeValue($dms->getAttributeDefinition($attrdefid), $attribute)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
} elseif($attrdef->getMinValues() > 0) {
|
||||
$this->errormsg = array("attr_min_values", array("attrname"=>$attrdef->getName()));
|
||||
return false;
|
||||
} elseif(isset($oldattributes[$attrdefid])) {
|
||||
if(!$version->removeAttribute($dms->getAttributeDefinition($attrdefid)))
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
if($ret === false)
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
/* Do not remove any old attributes if they have not be set by the form
|
||||
foreach($oldattributes as $attrdefid=>$oldattribute) {
|
||||
if(!isset($attributes[$attrdefid])) {
|
||||
if(!$version->removeAttribute($dms->getAttributeDefinition($attrdefid)))
|
||||
return false;
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
} elseif($result === false) {
|
||||
if(empty($this->errormsg))
|
||||
$this->errormsg = 'hook_editAttributes_failed';
|
||||
return false;
|
||||
}
|
||||
|
||||
if(false === $this->callHook('postEditAttributes')) {
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
@ -174,14 +174,12 @@ class SeedDMS_Controller_EditDocument extends SeedDMS_Controller_Common {
|
|||
}
|
||||
}
|
||||
}
|
||||
/* Do not remove any old attributes if they have not be set by the form
|
||||
foreach($oldattributes as $attrdefid=>$oldattribute) {
|
||||
if(!isset($attributes[$attrdefid])) {
|
||||
if(!$document->removeAttribute($dms->getAttributeDefinition($attrdefid)))
|
||||
return false;
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
$sequence = $this->params['sequence'];
|
||||
if(strcasecmp($sequence, "keep")) {
|
||||
|
|
|
|||
|
|
@ -64,6 +64,16 @@ class SeedDMS_Controller_Login extends SeedDMS_Controller_Common {
|
|||
return false;
|
||||
}
|
||||
|
||||
if($settings->_enable2FactorAuthentication) {
|
||||
if($user->getSecret()) {
|
||||
$tfa = new \RobThree\Auth\TwoFactorAuth('SeedDMS');
|
||||
if($tfa->verifyCode($user->getSecret(), $_POST['twofactauth']) !== true) {
|
||||
$this->setErrorMsg("login_error_text");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Run any additional checks which may prevent login */
|
||||
if(false === $this->callHook('restrictLogin', $user)) {
|
||||
if(empty($this->errormsg))
|
||||
|
|
@ -125,7 +135,7 @@ class SeedDMS_Controller_Login extends SeedDMS_Controller_Common {
|
|||
$dms_session = $_COOKIE["mydms_session"];
|
||||
if(!$resArr = $session->load($dms_session)) {
|
||||
/* Turn off http only cookies if jumploader is enabled */
|
||||
setcookie("mydms_session", $dms_session, time()-3600, $settings->_httpRoot, '', false, true); //delete cookie
|
||||
setcookie("mydms_session", $dms_session, time()-3600, $settings->_httpRoot, null, false, true); //delete cookie
|
||||
header("Location: " . $settings->_httpRoot . "out/out.Login.php?referuri=".$referuri);
|
||||
exit;
|
||||
} else {
|
||||
|
|
@ -144,7 +154,7 @@ class SeedDMS_Controller_Login extends SeedDMS_Controller_Common {
|
|||
$lifetime = time() + intval($settings->_cookieLifetime);
|
||||
else
|
||||
$lifetime = 0;
|
||||
setcookie("mydms_session", $id, $lifetime, $settings->_httpRoot, '', false, true);
|
||||
setcookie("mydms_session", $id, $lifetime, $settings->_httpRoot, null, false, true);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
67
controllers/class.ReceiptDocument.php
Normal file
67
controllers/class.ReceiptDocument.php
Normal file
|
|
@ -0,0 +1,67 @@
|
|||
<?php
|
||||
/**
|
||||
* Implementation of ReceiptDocument controller
|
||||
*
|
||||
* @category DMS
|
||||
* @package SeedDMS
|
||||
* @license GPL 2
|
||||
* @version @version@
|
||||
* @author Uwe Steinmann <uwe@steinmann.cx>
|
||||
* @copyright Copyright (C) 2010-2013 Uwe Steinmann
|
||||
* @version Release: @package_version@
|
||||
*/
|
||||
|
||||
/**
|
||||
* Class which does the busines logic for downloading a document
|
||||
*
|
||||
* @category DMS
|
||||
* @package SeedDMS
|
||||
* @author Uwe Steinmann <uwe@steinmann.cx>
|
||||
* @copyright Copyright (C) 2010-2013 Uwe Steinmann
|
||||
* @version Release: @package_version@
|
||||
*/
|
||||
class SeedDMS_Controller_ReceiptDocument extends SeedDMS_Controller_Common {
|
||||
|
||||
public function run() {
|
||||
$dms = $this->params['dms'];
|
||||
$user = $this->params['user'];
|
||||
$settings = $this->params['settings'];
|
||||
$document = $this->params['document'];
|
||||
$content = $this->params['content'];
|
||||
$receiptstatus = $this->params['receiptstatus'];
|
||||
$receipttype = $this->params['receipttype'];
|
||||
$group = $this->params['group'];
|
||||
$comment = $this->params['comment'];
|
||||
|
||||
/* Get the document id and name before removing the document */
|
||||
$docname = $document->getName();
|
||||
$documentid = $document->getID();
|
||||
|
||||
if(!$this->callHook('preReceiptDocument', $content)) {
|
||||
}
|
||||
|
||||
$result = $this->callHook('receiptDocument', $content);
|
||||
if($result === null) {
|
||||
|
||||
if ($receipttype == "ind") {
|
||||
if(0 > $content->setReceiptByInd($user, $user, $receiptstatus, $comment)) {
|
||||
$this->error = 1;
|
||||
$this->errormsg = "receipt_update_failed";
|
||||
return false;
|
||||
}
|
||||
} elseif ($receipttype == "grp") {
|
||||
if(0 > $content->setReceiptByGrp($group, $user, $receiptstatus, $comment)) {
|
||||
$this->error = 1;
|
||||
$this->errormsg = "receipt_update_failed";
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(!$this->callHook('postReceiptDocument', $content)) {
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -36,83 +36,96 @@ class SeedDMS_Controller_ReviewDocument extends SeedDMS_Controller_Common {
|
|||
$this->oldstatus = $overallStatus['status'];
|
||||
$this->newstatus = $this->oldstatus;
|
||||
|
||||
if ($reviewtype == "ind") {
|
||||
$reviewLogID = $content->setReviewByInd($user, $user, $reviewstatus, $reviewcomment, $reviewfile);
|
||||
} elseif($reviewtype == "grp") {
|
||||
$reviewLogID = $content->setReviewByGrp($reviewgroup, $user, $reviewstatus, $reviewcomment, $reviewfile);
|
||||
} else {
|
||||
$this->errormsg = "review_wrong_type";
|
||||
return false;
|
||||
}
|
||||
if($reviewLogID === false || 0 > $reviewLogID) {
|
||||
$this->errormsg = "review_update_failed";
|
||||
return false;
|
||||
if(!$this->callHook('preReviewDocument', $content)) {
|
||||
}
|
||||
|
||||
if($reviewstatus == -1) {
|
||||
$this->newstatus = S_REJECTED;
|
||||
if($content->setStatus(S_REJECTED, $reviewcomment, $user)) {
|
||||
if(isset($GLOBALS['SEEDDMS_HOOKS']['reviewDocument'])) {
|
||||
foreach($GLOBALS['SEEDDMS_HOOKS']['reviewDocument'] as $hookObj) {
|
||||
if (method_exists($hookObj, 'postReviewDocument')) {
|
||||
$hookObj->postReviewDocument(null, $content, S_REJECTED);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$docReviewStatus = $content->getReviewStatus();
|
||||
if (is_bool($docReviewStatus) && !$docReviewStatus) {
|
||||
$this->errormsg = "cannot_retrieve_review_snapshot";
|
||||
$result = $this->callHook('reviewDocument', $content);
|
||||
if($result === null) {
|
||||
if ($reviewtype == "ind") {
|
||||
$reviewLogID = $content->setReviewByInd($user, $user, $reviewstatus, $reviewcomment, $reviewfile);
|
||||
} elseif($reviewtype == "grp") {
|
||||
$reviewLogID = $content->setReviewByGrp($reviewgroup, $user, $reviewstatus, $reviewcomment, $reviewfile);
|
||||
} else {
|
||||
$this->errormsg = "review_wrong_type";
|
||||
return false;
|
||||
}
|
||||
$reviewCT = 0;
|
||||
$reviewTotal = 0;
|
||||
foreach ($docReviewStatus as $drstat) {
|
||||
if ($drstat["status"] == 1) {
|
||||
$reviewCT++;
|
||||
}
|
||||
if ($drstat["status"] != -2) {
|
||||
$reviewTotal++;
|
||||
}
|
||||
if($reviewLogID === false || 0 > $reviewLogID) {
|
||||
$this->errormsg = "review_update_failed";
|
||||
return false;
|
||||
}
|
||||
// If all reviews have been received and there are no rejections, retrieve a
|
||||
// count of the approvals required for this document.
|
||||
if ($reviewCT == $reviewTotal) {
|
||||
$docApprovalStatus = $content->getApprovalStatus();
|
||||
if (is_bool($docApprovalStatus) && !$docApprovalStatus) {
|
||||
$this->errormsg = "cannot_retrieve_approval_snapshot";
|
||||
return false;
|
||||
}
|
||||
$approvalCT = 0;
|
||||
$approvalTotal = 0;
|
||||
foreach($docApprovalStatus as $dastat) {
|
||||
if($dastat["status"] == 1) {
|
||||
$approvalCT++;
|
||||
}
|
||||
if($dastat["status"] != -2) {
|
||||
$approvalTotal++;
|
||||
}
|
||||
}
|
||||
// If the approvals received is less than the approvals total, then
|
||||
// change status to pending approval.
|
||||
if($approvalCT < $approvalTotal) {
|
||||
$this->newstatus = S_DRAFT_APP;
|
||||
} else {
|
||||
// Otherwise, change the status to released.
|
||||
$this->newstatus = S_RELEASED;
|
||||
}
|
||||
if($content->setStatus($this->newstatus, getMLText("automatic_status_update"), $user)) {
|
||||
}
|
||||
|
||||
$result = $this->callHook('reviewUpdateDocumentStatus', $content);
|
||||
if($result === null) {
|
||||
if($reviewstatus == -1) {
|
||||
$this->newstatus = S_REJECTED;
|
||||
if($content->setStatus(S_REJECTED, $reviewcomment, $user)) {
|
||||
if(isset($GLOBALS['SEEDDMS_HOOKS']['reviewDocument'])) {
|
||||
foreach($GLOBALS['SEEDDMS_HOOKS']['reviewDocument'] as $hookObj) {
|
||||
if (method_exists($hookObj, 'postReviewDocument')) {
|
||||
$hookObj->postReviewDocument(null, $content, $this->newstatus);
|
||||
$hookObj->postReviewDocument(null, $content, S_REJECTED);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$docReviewStatus = $content->getReviewStatus();
|
||||
if (is_bool($docReviewStatus) && !$docReviewStatus) {
|
||||
$this->errormsg = "cannot_retrieve_review_snapshot";
|
||||
return false;
|
||||
}
|
||||
$reviewCT = 0;
|
||||
$reviewTotal = 0;
|
||||
foreach ($docReviewStatus as $drstat) {
|
||||
if ($drstat["status"] == 1) {
|
||||
$reviewCT++;
|
||||
}
|
||||
if ($drstat["status"] != -2) {
|
||||
$reviewTotal++;
|
||||
}
|
||||
}
|
||||
// If all reviews have been received and there are no rejections, retrieve a
|
||||
// count of the approvals required for this document.
|
||||
if ($reviewCT == $reviewTotal) {
|
||||
$docApprovalStatus = $content->getApprovalStatus();
|
||||
if (is_bool($docApprovalStatus) && !$docApprovalStatus) {
|
||||
$this->errormsg = "cannot_retrieve_approval_snapshot";
|
||||
return false;
|
||||
}
|
||||
$approvalCT = 0;
|
||||
$approvalTotal = 0;
|
||||
foreach($docApprovalStatus as $dastat) {
|
||||
if($dastat["status"] == 1) {
|
||||
$approvalCT++;
|
||||
}
|
||||
if($dastat["status"] != -2) {
|
||||
$approvalTotal++;
|
||||
}
|
||||
}
|
||||
// If the approvals received is less than the approvals total, then
|
||||
// change status to pending approval.
|
||||
if($approvalCT < $approvalTotal) {
|
||||
$this->newstatus = S_DRAFT_APP;
|
||||
} else {
|
||||
// Otherwise, change the status to released.
|
||||
$this->newstatus = S_RELEASED;
|
||||
}
|
||||
if($content->setStatus($this->newstatus, getMLText("automatic_status_update"), $user)) {
|
||||
if(isset($GLOBALS['SEEDDMS_HOOKS']['reviewDocument'])) {
|
||||
foreach($GLOBALS['SEEDDMS_HOOKS']['reviewDocument'] as $hookObj) {
|
||||
if (method_exists($hookObj, 'postReviewDocument')) {
|
||||
$hookObj->postReviewDocument(null, $content, $this->newstatus);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(!$this->callHook('postReviewDocument', $content)) {
|
||||
}
|
||||
|
||||
return true;
|
||||
} /* }}} */
|
||||
}
|
||||
|
|
|
|||
143
controllers/class.ReviseDocument.php
Normal file
143
controllers/class.ReviseDocument.php
Normal file
|
|
@ -0,0 +1,143 @@
|
|||
<?php
|
||||
/**
|
||||
* Implementation of ReviseDocument controller
|
||||
*
|
||||
* @category DMS
|
||||
* @package SeedDMS
|
||||
* @license GPL 2
|
||||
* @version @version@
|
||||
* @author Uwe Steinmann <uwe@steinmann.cx>
|
||||
* @copyright Copyright (C) 2010-2013 Uwe Steinmann
|
||||
* @version Release: @package_version@
|
||||
*/
|
||||
|
||||
/**
|
||||
* Class which does the busines logic for downloading a document
|
||||
*
|
||||
* @category DMS
|
||||
* @package SeedDMS
|
||||
* @author Uwe Steinmann <uwe@steinmann.cx>
|
||||
* @copyright Copyright (C) 2010-2013 Uwe Steinmann
|
||||
* @version Release: @package_version@
|
||||
*/
|
||||
class SeedDMS_Controller_ReviseDocument extends SeedDMS_Controller_Common {
|
||||
|
||||
public $oldstatus;
|
||||
|
||||
public $newstatus;
|
||||
|
||||
public function run() {
|
||||
$dms = $this->params['dms'];
|
||||
$user = $this->params['user'];
|
||||
$settings = $this->params['settings'];
|
||||
$document = $this->params['document'];
|
||||
$content = $this->params['content'];
|
||||
$revisionstatus = $this->params['revisionstatus'];
|
||||
$revisiontype = $this->params['revisiontype'];
|
||||
$group = $this->params['group'];
|
||||
$comment = $this->params['comment'];
|
||||
$overallStatus = $content->getStatus();
|
||||
$this->oldstatus = $overallStatus['status'];
|
||||
$this->newstatus = $this->oldstatus;
|
||||
|
||||
/* if set to true, a single reject will reject the doc. If set to false
|
||||
* all revisions will be collected first and afterwards the doc is rejected
|
||||
* if one has rejected it. So in the very end the doc is rejected, but
|
||||
* doc remainѕ in S_IN_REVISION until all have revised the doc
|
||||
*/
|
||||
$onevotereject = $this->params['onevotereject'];
|
||||
|
||||
/* Get the document id and name before removing the document */
|
||||
$docname = $document->getName();
|
||||
$documentid = $document->getID();
|
||||
|
||||
if(!$this->callHook('preReviseDocument', $content)) {
|
||||
}
|
||||
|
||||
$result = $this->callHook('reviseDocument', $content);
|
||||
if($result === null) {
|
||||
|
||||
if ($revisiontype == "ind") {
|
||||
if(0 > $content->setRevision($user, $user, $revisionstatus, $comment)) {
|
||||
$this->error = 1;
|
||||
$this->errormsg = "revision_update_failed";
|
||||
return false;
|
||||
}
|
||||
} elseif ($revisiontype == "grp") {
|
||||
if(0 > $content->setRevision($group, $user, $revisionstatus, $comment)) {
|
||||
$this->error = 1;
|
||||
$this->errormsg = $ll."revision_update_failed";
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Check to see if the overall status for the document version needs to be
|
||||
* updated.
|
||||
*/
|
||||
$result = $this->callHook('reviseUpdateDocumentStatus', $content);
|
||||
if($result === null) {
|
||||
if ($onevotereject && $revisionstatus == -1){
|
||||
$this->newstatus = S_NEEDS_CORRECTION;
|
||||
if(!$content->setStatus(S_NEEDS_CORRECTION,$comment,$user)) {
|
||||
$this->error = 1;
|
||||
$this->errormsg = "revision_update_failed";
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
$docRevisionStatus = $content->getRevisionStatus();
|
||||
if (is_bool($docRevisionStatus) && !$docRevisionStatus) {
|
||||
$this->error = 1;
|
||||
$this->errormsg = "cannot_retrieve_revision_snapshot";
|
||||
return false;
|
||||
}
|
||||
$revisionok = 0;
|
||||
$revisionnotok = 0;
|
||||
$revisionTotal = 0;
|
||||
foreach ($docRevisionStatus as $drstat) {
|
||||
if ($drstat["status"] == 1) {
|
||||
$revisionok++;
|
||||
}
|
||||
if ($drstat["status"] == -1) {
|
||||
$revisionnotok++;
|
||||
}
|
||||
if ($drstat["status"] != -2) {
|
||||
$revisionTotal++;
|
||||
}
|
||||
}
|
||||
// If all revisions have been done and there are no rejections,
|
||||
// then release the document. If all revisions have been done but some
|
||||
// of them were rejections then documents needs correction.
|
||||
// Otherwise put it back into revision workflow
|
||||
if ($revisionok == $revisionTotal) {
|
||||
$this->newstatus=S_RELEASED;
|
||||
if ($content->finishRevision($user, $this->newstatus, 'Finished revision workflow', getMLText("automatic_status_update"))) {
|
||||
if(!$this->callHook('finishReviseDocument', $content)) {
|
||||
}
|
||||
}
|
||||
} elseif (($revisionok + $revisionnotok) == $revisionTotal) {
|
||||
$this->newstatus=S_NEEDS_CORRECTION;
|
||||
// if ($content->finishRevision($user, $this->newstatus, 'Finished revision workflow', getMLText("automatic_status_update"))) {
|
||||
if(!$content->setStatus($this->newstatus,$comment,$user)) {
|
||||
$this->error = 1;
|
||||
$this->errormsg = "revision_update_failed";
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
$this->newstatus=S_IN_REVISION;
|
||||
if(!$content->setStatus($this->newstatus,$comment,$user)) {
|
||||
$this->error = 1;
|
||||
$this->errormsg = "revision_update_failed";
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(!$this->callHook('postReviseDocument', $content)) {
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
56
controllers/class.RoleMgr.php
Normal file
56
controllers/class.RoleMgr.php
Normal file
|
|
@ -0,0 +1,56 @@
|
|||
<?php
|
||||
/**
|
||||
* Implementation of Role manager controller
|
||||
*
|
||||
* @category DMS
|
||||
* @package SeedDMS
|
||||
* @license GPL 2
|
||||
* @version @version@
|
||||
* @author Uwe Steinmann <uwe@steinmann.cx>
|
||||
* @copyright Copyright (C) 2010-2013 Uwe Steinmann
|
||||
* @version Release: @package_version@
|
||||
*/
|
||||
|
||||
/**
|
||||
* Class which does the busines logic for role manager
|
||||
*
|
||||
* @category DMS
|
||||
* @package SeedDMS
|
||||
* @author Uwe Steinmann <uwe@steinmann.cx>
|
||||
* @copyright Copyright (C) 2010-2013 Uwe Steinmann
|
||||
* @version Release: @package_version@
|
||||
*/
|
||||
class SeedDMS_Controller_RoleMgr extends SeedDMS_Controller_Common {
|
||||
|
||||
public function run() {
|
||||
}
|
||||
|
||||
public function addrole() {
|
||||
$dms = $this->params['dms'];
|
||||
$name = $this->params['name'];
|
||||
$role = $this->params['role'];
|
||||
|
||||
return($dms->addRole($name, $role));
|
||||
}
|
||||
|
||||
public function removerole() {
|
||||
$roleobj = $this->params['roleobj'];
|
||||
return $roleobj->remove();
|
||||
}
|
||||
|
||||
public function editrole() {
|
||||
$dms = $this->params['dms'];
|
||||
$name = $this->params['name'];
|
||||
$role = $this->params['role'];
|
||||
$roleobj = $this->params['roleobj'];
|
||||
$noaccess = $this->params['noaccess'];
|
||||
|
||||
if ($roleobj->getName() != $name)
|
||||
$roleobj->setName($name);
|
||||
if ($roleobj->getRole() != $role)
|
||||
$roleobj->setRole($role);
|
||||
$roleobj->setNoAccess($noaccess);
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
68
controllers/class.TransmittalDownload.php
Normal file
68
controllers/class.TransmittalDownload.php
Normal file
|
|
@ -0,0 +1,68 @@
|
|||
<?php
|
||||
/**
|
||||
* Implementation of Transmittal Download controller
|
||||
*
|
||||
* @category DMS
|
||||
* @package SeedDMS
|
||||
* @license GPL 2
|
||||
* @version @version@
|
||||
* @author Uwe Steinmann <uwe@steinmann.cx>
|
||||
* @copyright Copyright (C) 2010-2013 Uwe Steinmann
|
||||
* @version Release: @package_version@
|
||||
*/
|
||||
|
||||
/**
|
||||
* Class which does the busines logic for downloading a transmittal
|
||||
*
|
||||
* @category DMS
|
||||
* @package SeedDMS
|
||||
* @author Uwe Steinmann <uwe@steinmann.cx>
|
||||
* @copyright Copyright (C) 2010-2013 Uwe Steinmann
|
||||
* @version Release: @package_version@
|
||||
*/
|
||||
class SeedDMS_Controller_TransmittalDownload extends SeedDMS_Controller_Common {
|
||||
|
||||
public function run() {
|
||||
$dms = $this->params['dms'];
|
||||
$user = $this->params['user'];
|
||||
$transmittal = $this->params['transmittal'];
|
||||
|
||||
$items = $transmittal->getItems();
|
||||
if($items) {
|
||||
include("../inc/inc.ClassDownloadMgr.php");
|
||||
$downmgr = new SeedDMS_Download_Mgr();
|
||||
if($extraheader = $this->callHook('extraDownloadHeader'))
|
||||
$downmgr->addHeader($extraheader);
|
||||
|
||||
foreach($items as $item) {
|
||||
$content = $item->getContent();
|
||||
$document = $content->getDocument();
|
||||
if ($document->getAccessMode($user) >= M_READ) {
|
||||
$extracols = $this->callHook('extraDownloadColumns', $document);
|
||||
$filename = $this->callHook('filenameDownloadItem', $content);
|
||||
if($rawcontent = $this->callHook('rawcontent', $content)) {
|
||||
$downmgr->addItem($content, $extracols, $rawcontent, $filename);
|
||||
} else
|
||||
$downmgr->addItem($content, $extracols, null, $filename);
|
||||
}
|
||||
}
|
||||
|
||||
$filename = tempnam(sys_get_temp_dir(), 'transmittal-download-');
|
||||
if($filename) {
|
||||
if($downmgr->createArchive($filename)) {
|
||||
header("Content-Transfer-Encoding: binary");
|
||||
header("Content-Length: " . filesize($filename));
|
||||
header("Content-Disposition: attachment; filename=\"export-" .date('Y-m-d') . ".zip\"");
|
||||
header("Content-Type: application/zip");
|
||||
header("Cache-Control: must-revalidate");
|
||||
|
||||
readfile($filename);
|
||||
} else {
|
||||
}
|
||||
unlink($filename);
|
||||
}
|
||||
exit;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -48,16 +48,18 @@ class SeedDMS_Controller_UpdateDocument extends SeedDMS_Controller_Common {
|
|||
$userfiletype = $this->getParam('userfiletype');
|
||||
$reviewers = $this->getParam('reviewers');
|
||||
$approvers = $this->getParam('approvers');
|
||||
$recipients = $this->getParam('recipients');
|
||||
$reqversion = $this->getParam('reqversion');
|
||||
$comment = $this->getParam('comment');
|
||||
$attributes = $this->getParam('attributes');
|
||||
$workflow = $this->getParam('workflow');
|
||||
$maxsizeforfulltext = $this->getParam('maxsizeforfulltext');
|
||||
$initialdocumentstatus = $this->getParam('initialdocumentstatus');
|
||||
|
||||
$content = $this->callHook('updateDocument');
|
||||
if($content === null) {
|
||||
$filesize = SeedDMS_Core_File::fileSize($userfiletmp);
|
||||
if($contentResult=$document->addContent($comment, $user, $userfiletmp, utf8_basename($userfilename), $filetype, $userfiletype, $reviewers, $approvers, 0, $attributes, $workflow)) {
|
||||
if($contentResult=$document->addContent($comment, $user, $userfiletmp, utf8_basename($userfilename), $filetype, $userfiletype, $reviewers, $approvers, 0, $attributes, $workflow, $initialdocumentstatus)) {
|
||||
|
||||
if ($this->hasParam('expires')) {
|
||||
if($document->setExpires($this->getParam('expires'))) {
|
||||
|
|
@ -65,6 +67,21 @@ class SeedDMS_Controller_UpdateDocument extends SeedDMS_Controller_Common {
|
|||
}
|
||||
}
|
||||
|
||||
if(!empty($recipients['i'])) {
|
||||
foreach($recipients['i'] as $uid) {
|
||||
if($u = $dms->getUser($uid)) {
|
||||
$res = $contentResult->getContent()->addIndRecipient($u, $user);
|
||||
}
|
||||
}
|
||||
}
|
||||
if(!empty($recipients['g'])) {
|
||||
foreach($recipients['g'] as $gid) {
|
||||
if($g = $dms->getGroup($gid)) {
|
||||
$res = $contentResult->getContent()->addGrpRecipient($g, $user);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$content = $contentResult->getContent();
|
||||
} else {
|
||||
$this->errormsg = 'error_update_document';
|
||||
|
|
|
|||
|
|
@ -1,3 +1,3 @@
|
|||
#!/bin/sh
|
||||
# This command retrieves the strings that need to be translated
|
||||
sgrep -o "%r\n" '"getMLText(\"" __ "\""' */*.php|sort|uniq -c
|
||||
sgrep -o "%r\n" '"getMLText(\"" __ "\""' */*.php views/bootstrap/*.php |sort|uniq -c
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
<?php
|
||||
/* Determine all languages keys used in the php files */
|
||||
$output = array();
|
||||
if(exec('sgrep -o "%r\n" \'"tMLText(\"" __ "\""\' */*.php|sort|uniq -c', $output)) {
|
||||
if(exec('sgrep -o "%r\n" \'"tMLText(\"" __ "\""\' */*.php views/bootstrap/*.php|sort|uniq -c', $output)) {
|
||||
$allkeys = array();
|
||||
foreach($output as $line) {
|
||||
$data = explode(' ', trim($line));
|
||||
|
|
@ -9,8 +9,9 @@ if(exec('sgrep -o "%r\n" \'"tMLText(\"" __ "\""\' */*.php|sort|uniq -c', $output
|
|||
}
|
||||
}
|
||||
|
||||
$languages = array('ar_EG', 'bg_BG', 'ca_ES', 'cs_CZ', 'de_DE', 'en_GB', 'es_ES', 'fr_FR', 'hu_HU', 'it_IT', 'nl_NL', 'pl_PL', 'pt_BR', 'ro_RO', 'ru_RU', 'sk_SK', 'sv_SE', 'tr_TR', 'zh_CN', 'zh_TW');
|
||||
/* Reading languages */
|
||||
foreach(array('en_GB', 'de_DE', 'it_IT', 'sk_SK', 'cs_CZ') as $lang) {
|
||||
foreach($languages as $lang) {
|
||||
include('languages/'.$lang.'/lang.inc');
|
||||
ksort($text);
|
||||
$langarr[$lang] = $text;
|
||||
|
|
@ -20,7 +21,7 @@ foreach(array('en_GB', 'de_DE', 'it_IT', 'sk_SK', 'cs_CZ') as $lang) {
|
|||
echo "List of missing keys\n";
|
||||
echo "-----------------------------\n";
|
||||
foreach(array_keys($allkeys) as $key) {
|
||||
foreach(array('en_GB', 'de_DE', 'it_IT', 'sk_SK', 'cs_CZ') as $lang) {
|
||||
foreach($languages as $lang) {
|
||||
if(!isset($langarr[$lang][$key])) {
|
||||
echo "Missing key '".$key."' in language ".$lang."\n";
|
||||
}
|
||||
|
|
@ -31,7 +32,7 @@ echo "\n";
|
|||
/* Check for phrases not used anymore */
|
||||
echo "List of superflous keys\n";
|
||||
echo "-----------------------------\n";
|
||||
foreach(array('en_GB', 'de_DE', 'it_IT', 'sk_SK', 'cs_CZ') as $lang) {
|
||||
foreach($languages as $lang) {
|
||||
$n = 0;
|
||||
foreach($langarr[$lang] as $key=>$value) {
|
||||
if(!isset($allkeys[$key])) {
|
||||
|
|
|
|||
206
doc/README.Converters
Normal file
206
doc/README.Converters
Normal file
|
|
@ -0,0 +1,206 @@
|
|||
Commands for converting documents
|
||||
----------------------------------
|
||||
|
||||
This file contains commands for converting different document types
|
||||
into
|
||||
|
||||
* text (for fulltext search)
|
||||
* png (for preview images)
|
||||
* pdf (for pdf documents)
|
||||
|
||||
Such conversions may not necessarily output an excact equivalent of
|
||||
the input file, but outputs a suitable representation, e.g.
|
||||
converting an mp3 file into text may output the metadata or even the
|
||||
lyrics of the song. Converting it into a preview image may result
|
||||
in a picture of the album cover.
|
||||
|
||||
Please note, that when ever a command outputs anything to stderr,
|
||||
this will considered as a failure of the command. Most command line
|
||||
programs have a parameter (.e.g. `-q`) to suppress such an output.
|
||||
|
||||
If you run php-fpm you may encounter problems with charsets based on
|
||||
UTF-8. Programms like `catdoc` read LANG from the environment to
|
||||
set the correct encoding of the output. php-fpm often clears the
|
||||
environment and programms like `catdoc` will not longer output any
|
||||
UTF-8 chars. In such a case you may want to set `clear_env=no` in
|
||||
php-fpm's configuration. On Debian this is done in the file
|
||||
`/etc/php/<php version>/fpm/pool.d/www.conf`. Search for `clear_env`.
|
||||
|
||||
Conversion to text for fulltext search
|
||||
=======================================
|
||||
|
||||
text/plain
|
||||
text/csv
|
||||
application/csv
|
||||
cat '%s'
|
||||
|
||||
application/pdf
|
||||
pdftotext -q -nopgbrk %s - | sed -e 's/ [a-zA-Z0-9.]\{1\} / /g' -e 's/[0-9.]//g'
|
||||
|
||||
If pdftotext takes too long on large document you may want to pass parameter
|
||||
-l to specify the last page to be converted. -q is for suppressing error/warnings
|
||||
send to stderr
|
||||
|
||||
mutool draw -F txt -q -N -o - %s
|
||||
|
||||
application/vnd.openxmlformats-officedocument.wordprocessingml.document
|
||||
docx2txt '%s' -
|
||||
|
||||
application/msword
|
||||
catdoc %s
|
||||
|
||||
application/vnd.oasis.opendocument.text
|
||||
odt2txt %s
|
||||
|
||||
application/vnd.openxmlformats-officedocument.spreadsheetml.sheet
|
||||
xlsx2csv -d tab %s
|
||||
|
||||
application/vnd.ms-excel
|
||||
xls2csv -d tab %s
|
||||
|
||||
text/html
|
||||
html2text %s
|
||||
|
||||
Many office formats
|
||||
unoconv -d document -f txt --stdout '%s'
|
||||
|
||||
Apache Tika is another option for creating plain text from various document
|
||||
types. Just use curl to send the document to your tika server and get the
|
||||
plain text in return.
|
||||
|
||||
curl -s -T '%s' http://localhost:9998/tika --header 'Accept: text/plain'
|
||||
|
||||
Conversion to pdf for pdf preview
|
||||
==================================
|
||||
|
||||
text/plain
|
||||
text/csv
|
||||
application/csv
|
||||
application/vnd.oasis.opendocument.text
|
||||
application/msword
|
||||
application/vnd.wordperfect
|
||||
text/rtf
|
||||
unoconv -d document -f pdf --stdout -v '%f' > '%o'
|
||||
|
||||
image/png
|
||||
image/jpg
|
||||
image/jpeg
|
||||
convert -density 300 '%f' 'pdf:%o'
|
||||
|
||||
image/svg+xml
|
||||
cairosvg -f pdf -o '%o' '%f'
|
||||
|
||||
application/vnd.ms-powerpoint
|
||||
application/vnd.openxmlformats-officedocument.presentationml.presentation
|
||||
application/vnd.oasis.opendocument.presentation
|
||||
unoconv -d presentation -f pdf --stdout -v '%f' > '%o'
|
||||
|
||||
application/vnd.ms-excel
|
||||
application/vnd.openxmlformats-officedocument.spreadsheetml.sheet
|
||||
application/vnd.oasis.opendocument.spreadsheet
|
||||
unoconv -d spreadsheet -f pdf --stdout -v '%f' > '%o'
|
||||
|
||||
message/rfc822
|
||||
java -jar emailconverter-2.5.3-all.jar '%f' -o '%o'
|
||||
|
||||
The emailconverter can be obtained from https://github.com/nickrussler/email-to-pdf-converter
|
||||
It requires wkhtmltopdf which is part of debian.
|
||||
|
||||
text/plain
|
||||
iconv -c -f utf-8 -t latin1 '%f' | a2ps -1 -q -a1 -R -B -o - - | ps2pdf - -
|
||||
|
||||
The parameter `-q` is important because a2ps sends some statistical
|
||||
data to stderr, which makes SeedDMS believe the command has failed.
|
||||
|
||||
application/x-xopp
|
||||
|
||||
xournalpp -p "%o" "%f"
|
||||
|
||||
Converting from application/x-xopp to pdf only works if the xopp file
|
||||
does not use a pdf document as a background, because this pdf is not
|
||||
stored in the xopp fіle.
|
||||
|
||||
Conversion to png for preview images
|
||||
=====================================
|
||||
|
||||
If you have problems running convert on PDF documents then read this page
|
||||
https://askubuntu.com/questions/1081895/trouble-with-batch-conversion-of-png-to-pdf-using-convert
|
||||
It basically instructs you to comment out the line
|
||||
|
||||
<policy domain="coder" rights="none" pattern="PDF" />
|
||||
|
||||
in /etc/ImageMagick-6/policy.xml
|
||||
|
||||
convert determines the format of the converted image from the extension of
|
||||
the output filename. SeedDMS usually sets a propper extension when running
|
||||
the command, but nevertheless it is good practice to explicitly set the output
|
||||
format by prefixing the output filename with 'png:'. This is of course always
|
||||
needed if the output goes to stdout.
|
||||
|
||||
image/jpg
|
||||
image/jpeg
|
||||
image/png
|
||||
convert -resize %wx '%f' 'png:%o'
|
||||
|
||||
image/svg+xml
|
||||
cairosvg -f png --output-width %w -o '%o' '%f'
|
||||
|
||||
text/plain
|
||||
convert -density 100 -resize %wx 'text:%f[0]' 'png:%o'
|
||||
|
||||
application/pdf
|
||||
gs -dBATCH -dNOPAUSE -sDEVICE=png16m -dPDFFitPage -r72x72 -sOutputFile=- -dFirstPage=1 -dLastPage=1 -q '%f' | convert -resize %wx png:- '%o'
|
||||
|
||||
convert -density 100 -resize %wx '%f[0]' 'png:%o'
|
||||
|
||||
mutool draw -F png -w %w -q -N -o '%o' '%f' 1
|
||||
|
||||
pdftocairo '%f' -png -singlefile -scale-to-x %w -scale-to-y -1 - > '%o'
|
||||
|
||||
pdftocairo needs to output to stdout because the output file name passed
|
||||
to pdftocairo will be suffixed with png
|
||||
|
||||
application/postscript
|
||||
convert -density 100 -resize %wx '%f[0]' 'png:%o'
|
||||
|
||||
text/plain
|
||||
iconv -c -f utf-8 -t latin1 '%f' | a2ps -1 -q -a1 -R -B -o - - | gs -dBATCH -dNOPAUSE -sDEVICE=png16m -dFirstPage=1 -dLastPage=1 -dPDFFitPage -r72x72 -sOutputFile=- -q - | convert -resize %wx png:- 'png:%o'
|
||||
|
||||
On Linux systems you will have to set the desired value in /etc/papersize for a2ps
|
||||
e.g. a4, or letter. Unfortunately, a2ps cannot process utf-8 encoded files. That's
|
||||
why the input needs to be recoded with iconv or recode.
|
||||
|
||||
application/msword
|
||||
application/vnd.oasis.opendocument.spreadsheet
|
||||
application/vnd.oasis.opendocument.text
|
||||
application/vnd.openxmlformats-officedocument.spreadsheetml.sheet
|
||||
application/vnd.ms-excel
|
||||
application/vnd.openxmlformats-officedocument.wordprocessingml.document
|
||||
text/rtf
|
||||
application/vnd.ms-powerpoint
|
||||
text/csv
|
||||
application/csv
|
||||
application/vnd.wordperfect
|
||||
unoconv -d document -e PageRange=1 -f pdf --stdout -v '%f' | gs -dBATCH -dNOPAUSE -sDEVICE=pngalpha -dPDFFitPage -r72x72 -sOutputFile=- -dFirstPage=1 -dLastPage=1 -q - | convert -resize %wx png:- 'png:%o'
|
||||
|
||||
video/webm
|
||||
video/mp4
|
||||
This will take 12th frame of a video and converts into a png. It requires
|
||||
ffmpeg to be installed.
|
||||
|
||||
convert -resize %wx "%f[12]" "png:%o"
|
||||
|
||||
You may as well use ffmpeg right away
|
||||
|
||||
ffmpeg -i "%f" -ss 00:00:02 -frames:v 1 -loglevel quiet -vf scale=%w:-1 -f apng "%o"
|
||||
|
||||
audio/mpeg
|
||||
|
||||
sox "%f" -n spectrogram -x 600 -Y 550 -r -l -o - | convert -resize %wx png:- "png:%o"
|
||||
|
||||
application/x-xopp
|
||||
xournalpp -i "%o" --export-png-width=%w "%f"
|
||||
|
||||
Converting from application/x-xopp to png only works if the xopp file
|
||||
does not use a pdf document as a background, because this pdf is not
|
||||
stored in the xopp fіle.
|
||||
|
|
@ -1,254 +0,0 @@
|
|||
# Commands for converting documents
|
||||
|
||||
SeedDMS has a very sophisticated file conversion process which could
|
||||
be used to convert any format into any other format, if there is either
|
||||
a command (on the command line) or a SeedDMS extension with php code
|
||||
doing the conversion. This could of course use an external service
|
||||
(e.g. Tika) for doing the conversion. There are already several
|
||||
extensions for this purpose and SeedDMS provides some buildin
|
||||
conversions as well. Traditionally, conversion was just used
|
||||
internally by SeedDMS (and this is still the main purpose), but
|
||||
this may not be the only use case.
|
||||
|
||||
This file only contains commands for converting different document
|
||||
types into
|
||||
|
||||
* text (for fulltext search)
|
||||
* png (for preview images)
|
||||
* pdf (for pdf documents)
|
||||
|
||||
Most of the required commands can easily be installed on a Linux
|
||||
server, which is the preferred plattform anyway. Other operating
|
||||
systems may work as well, but your milage may vary.
|
||||
|
||||
The conversion commands can be configured in the settings of SeedDMS.
|
||||
|
||||
A conversion may not necessarily output an excact equivalent of
|
||||
the input file, but outputs a suitable representation, e.g.
|
||||
converting an mp3 file into text may output the metadata or even the
|
||||
lyrics of the song. Converting it into a preview image may result
|
||||
in a picture of the album cover, or a graphical representation
|
||||
of the spectrum.
|
||||
|
||||
Please note, that whenever a command outputs anything to stderr,
|
||||
this will be considered as a failure of the command. Most command line
|
||||
programs have a parameter (.e.g. `-q`) to suppress such an output.
|
||||
|
||||
If you run php-fpm you may encounter problems with charsets based on
|
||||
UTF-8. Programms like `catdoc` read LANG from the environment to
|
||||
set the correct encoding of the output. php-fpm often clears the
|
||||
environment and programms like `catdoc` will not longer output any
|
||||
UTF-8 chars. In such a case you may want to set `clear_env=no` in
|
||||
php-fpm's configuration. On Debian this is done in the file
|
||||
`/etc/php/<php version>/fpm/pool.d/www.conf`. Search for `clear_env`.
|
||||
|
||||
The following sections will list possible conversion commands for
|
||||
extracting text, creating an image, and converting to pdf.
|
||||
|
||||
## Conversion to text for fulltext search
|
||||
|
||||
### text/plain, text/csv, application/csv
|
||||
|
||||
`cat '%s'`
|
||||
|
||||
Unless you run a very old version of SeedDMS, you will never need
|
||||
this command for converting text files. SeedDMS has this trivial
|
||||
converter build in.
|
||||
|
||||
### application/pdf
|
||||
|
||||
`pdftotext -q -nopgbrk %s - | sed -e 's/ [a-zA-Z0-9.]\{1\} / /g' -e 's/[0-9.]//g'`
|
||||
|
||||
If pdftotext takes too long on large document, then you may want to
|
||||
pass parameter `-l` to specify the last page to be converted. `-q` is
|
||||
for suppressing error/warnings send to stderr
|
||||
|
||||
`mutool draw -F txt -q -N -o - %s`
|
||||
|
||||
### application/vnd.openxmlformats-officedocument.wordprocessingml.document
|
||||
|
||||
`docx2txt '%s' -`
|
||||
|
||||
### application/msword
|
||||
|
||||
`catdoc %s`
|
||||
|
||||
### application/vnd.oasis.opendocument.text
|
||||
|
||||
`odt2txt %s`
|
||||
|
||||
### application/vnd.openxmlformats-officedocument.spreadsheetml.sheet
|
||||
|
||||
`xlsx2csv -d tab %s`
|
||||
|
||||
### application/vnd.ms-excel
|
||||
|
||||
`xls2csv -d tab %s`
|
||||
|
||||
### text/html
|
||||
|
||||
`html2text %s`
|
||||
|
||||
### Many office formats
|
||||
|
||||
Many office formats can be converted with `unoconv`, though this turned
|
||||
out in the past to sometimes crash or taking a long time.
|
||||
|
||||
`unoconv -d document -f txt --stdout '%s'`
|
||||
|
||||
Apache Tika is another option for creating plain text from various document
|
||||
types. Just use `curl` to send the document to your tika server and get the
|
||||
plain text in return.
|
||||
|
||||
`curl -s -T '%s' http://localhost:9998/tika --header 'Accept: text/plain'`
|
||||
|
||||
Of course this requires to first install Apache Tika when using the docker
|
||||
image.
|
||||
|
||||
Finally, there is a SeedDMS extension
|
||||
[unoserver](https://codeberg.org/SeedDMS/unoserver) which is based
|
||||
on a project also called
|
||||
[unoserver](https://github.com/unoconv/unoserver) and which is
|
||||
available as docker image, making it quite easy to setup. Read the
|
||||
documentation of the extension for more information.
|
||||
|
||||
## Conversion to pdf for pdf preview
|
||||
|
||||
### text/plain, text/csv, application/csv, application/vnd.oasis.opendocument.text application/msword, application/vnd.wordperfect, text/rtf
|
||||
|
||||
`unoconv -d document -f pdf --stdout -v '%f' > '%o'`
|
||||
|
||||
### image/png, image/jpg, image/jpeg
|
||||
|
||||
`convert -density 300 '%f' 'pdf:%o'`
|
||||
|
||||
Actually `convert` can be used for many other image formats. There is
|
||||
also a SeedDMS extension called
|
||||
[convert_image](https://codeberg.org/SeedDMS/convert_image) which
|
||||
embedds the image into a pdf file.
|
||||
|
||||
### image/svg+xml
|
||||
|
||||
`cairosvg -f pdf -o '%o' '%f'`
|
||||
|
||||
### application/vnd.ms-powerpoint, application/vnd.openxmlformats-officedocument.presentationml.presentation, application/vnd.oasis.opendocument.presentation
|
||||
|
||||
`unoconv -d presentation -f pdf --stdout -v '%f' > '%o'`
|
||||
|
||||
### application/vnd.ms-excel, application/vnd.openxmlformats-officedocument.spreadsheetml.sheet, application/vnd.oasis.opendocument.spreadsheet
|
||||
|
||||
`unoconv -d spreadsheet -f pdf --stdout -v '%f' > '%o'`
|
||||
|
||||
### message/rfc822
|
||||
|
||||
`java -jar emailconverter-2.5.3-all.jar '%f' -o '%o'`
|
||||
|
||||
The emailconverter can be obtained from https://github.com/nickrussler/email-to-pdf-converter
|
||||
It requires `wkhtmltopdf` which is part of debian.
|
||||
|
||||
### text/plain
|
||||
|
||||
`iconv -c -f utf-8 -t latin1 '%f' | a2ps -1 -q -a1 -R -B -o - - | ps2pdf - -`
|
||||
|
||||
The parameter `-q` is important because a2ps sends some statistical
|
||||
data to stderr, which makes SeedDMS believe the command has failed.
|
||||
|
||||
### application/x-xopp
|
||||
|
||||
`xournalpp -p "%o" "%f"`
|
||||
|
||||
Converting from application/x-xopp to pdf only works if the xopp file
|
||||
does not use a pdf document as a background, because this pdf is not
|
||||
stored in the xopp fіle.
|
||||
|
||||
### Many office formats
|
||||
|
||||
As already mentioned above, `unoconv` has some disadvantages. It is
|
||||
recommended to the `unoserver` SeedDMS extension already described
|
||||
above.
|
||||
|
||||
## Conversion to png for preview images
|
||||
|
||||
If you have problems running convert on PDF documents then read the page
|
||||
https://askubuntu.com/questions/1081895/trouble-with-batch-conversion-of-png-to-pdf-using-convert
|
||||
It basically instructs you to comment out the line
|
||||
|
||||
```
|
||||
<policy domain="coder" rights="none" pattern="PDF" />
|
||||
```
|
||||
|
||||
in `/etc/ImageMagick-6/policy.xml`
|
||||
|
||||
`convert` determines the format of the converted image from the extension of
|
||||
the output filename. SeedDMS usually sets a propper extension when running
|
||||
the command, but nevertheless it is good practice to explicitly set the output
|
||||
format by prefixing the output filename with 'png:'. This is of course always
|
||||
needed if the output goes to stdout.
|
||||
|
||||
### image/jpg, image/jpeg, image/png
|
||||
|
||||
`convert -resize %wx '%f' 'png:%o'`
|
||||
|
||||
### image/svg+xml
|
||||
|
||||
`cairosvg -f png --output-width %w -o '%o' '%f'`
|
||||
|
||||
### text/plain
|
||||
|
||||
`convert -density 100 -resize %wx 'text:%f[0]' 'png:%o'`
|
||||
|
||||
### application/pdf
|
||||
|
||||
`gs -dBATCH -dNOPAUSE -sDEVICE=png16m -dPDFFitPage -r72x72 -sOutputFile=- -dFirstPage=1 -dLastPage=1 -q '%f' | convert -resize %wx png:- '%o'`
|
||||
|
||||
`convert -density 100 -resize %wx '%f[0]' 'png:%o'`
|
||||
|
||||
`mutool draw -F png -w %w -q -N -o '%o' '%f' 1`
|
||||
|
||||
`pdftocairo '%f' -png -singlefile -scale-to-x %w -scale-to-y -1 - > '%o'`
|
||||
|
||||
`pdftocairo` needs to output to stdout because the output file name passed
|
||||
to pdftocairo will be suffixed with `.png`
|
||||
|
||||
### application/postscript
|
||||
|
||||
`convert -density 100 -resize %wx '%f[0]' 'png:%o'`
|
||||
|
||||
### text/plain
|
||||
|
||||
`iconv -c -f utf-8 -t latin1 '%f' | a2ps -1 -q -a1 -R -B -o - - | gs -dBATCH -dNOPAUSE -sDEVICE=png16m -dFirstPage=1 -dLastPage=1 -dPDFFitPage -r72x72 -sOutputFile=- -q - | convert -resize %wx png:- 'png:%o'`
|
||||
|
||||
On Linux systems you will have to set the desired value in /etc/papersize for a2ps
|
||||
e.g. a4, or letter. Unfortunately, a2ps cannot process utf-8 encoded files. That's
|
||||
why the input needs to be recoded with iconv or recode.
|
||||
|
||||
### application/msword, application/vnd.oasis.opendocument.spreadsheet, application/vnd.oasis.opendocument.text, application/vnd.openxmlformats-officedocument.spreadsheetml.sheet, application/vnd.ms-excel, application/vnd.openxmlformats-officedocument.wordprocessingml.document, text/rtf, application/vnd.ms-powerpoint, text/csv, application/csv, application/vnd.wordperfect,
|
||||
|
||||
`unoconv -d document -e PageRange=1 -f pdf --stdout -v '%f' | gs -dBATCH -dNOPAUSE -sDEVICE=pngalpha -dPDFFitPage -r72x72 -sOutputFile=- -dFirstPage=1 -dLastPage=1 -q - | convert -resize %wx png:- 'png:%o'`
|
||||
|
||||
If you are looking for an easier solution, you should consider to
|
||||
install the `unoserver` SeedDMS extension which was already described
|
||||
above.
|
||||
|
||||
### video/webm, video/mp4
|
||||
|
||||
This will take 12th frame of a video and converts into a png. It requires
|
||||
ffmpeg to be installed.
|
||||
|
||||
`convert -resize %wx "%f[12]" "png:%o"`
|
||||
|
||||
You may as well use ffmpeg right away
|
||||
|
||||
`ffmpeg -i "%f" -ss 00:00:02 -frames:v 1 -loglevel quiet -vf scale=%w:-1 -f apng "%o"`
|
||||
|
||||
### audio/mpeg
|
||||
|
||||
`sox "%f" -n spectrogram -x 600 -Y 550 -r -l -o - | convert -resize %wx png:- "png:%o"`
|
||||
|
||||
### application/x-xopp
|
||||
|
||||
`xournalpp -i "%o" --export-png-width=%w "%f"`
|
||||
|
||||
Converting from application/x-xopp to png only works if the xopp file
|
||||
does not use a pdf document as a background, because this pdf is not
|
||||
stored in the xopp fіle.
|
||||
|
|
@ -4,7 +4,6 @@ Layout of installation
|
|||
SeedDMS allows various kinds of installations with very individual layouts
|
||||
on disc. The proposed layout till version 5.1.6 was as the following:
|
||||
|
||||
```
|
||||
seeddms51x ---+--- data
|
||||
|
|
||||
+--- pear
|
||||
|
|
@ -12,31 +11,29 @@ seeddms51x ---+--- data
|
|||
+--- seeddms-5.1.x
|
||||
|
|
||||
+--- www -> seeddms-5.1.x
|
||||
```
|
||||
|
||||
`data` contains all document files, the sqlite database (if used), the full text
|
||||
'data' contains all document files, the sqlite database (if used), the full text
|
||||
data, the log files, and the cached preview images.
|
||||
|
||||
`pear` contains all third party packages including the four SeedDMS packages SeedDMS_Core,
|
||||
'pear' contains all PEAR packages including the four SeedDMS packages SeedDMS_Core,
|
||||
SeedDMS_Lucene, SeedDMS_Preview, SeedDMS_SQLiteFTS.
|
||||
|
||||
`seeddms-5.1.x` are the sources of seeddms and 'www' being a link on it.
|
||||
'seeddms-5.1.x' are the sources of seeddms and 'www' being a link on it.
|
||||
|
||||
This layout has disadvantages when updating the source of seeddms, because
|
||||
the directories `conf` and `ext` had to be moved from `seeddms-5.1.x` to
|
||||
`seeddms-5.1.(x+1)`. `conf` was also visible over the web unless it was
|
||||
the directories 'conf' and 'ext' had to be moved from 'seeddms-5.1.x' to
|
||||
'seeddms-5.1.(x+1)'. 'conf' was also visible over the web unless it was
|
||||
protected by an .htaccess file. The .htaccess file has been shipped, but it
|
||||
is far better to keep senѕitive data out of the document root in the first
|
||||
place.
|
||||
|
||||
The new layout mostly retains that structure but uses more soft links to place
|
||||
the local data outside of `seeddms-5.1.x` which makes updating a lot easier
|
||||
the local data outside of 'seeddms-5.1.x' which makes updating a lot easier
|
||||
and moves the configuration out of the document root.
|
||||
As MS Windows does not support soft links, this change will only apply to Linux/Unix
|
||||
systems. MS Windows users just skip all the soft links and set seeddms-5.1.x
|
||||
as the document root. The new layout is the following:
|
||||
|
||||
```
|
||||
seeddms51x ---+--- data --+-- log
|
||||
| |
|
||||
| +-- cache
|
||||
|
|
@ -76,12 +73,10 @@ seeddms51x ---+--- data --+-- log
|
|||
+-- index.php -> ../seeddms/index.php
|
||||
|
|
||||
+-- ext
|
||||
```
|
||||
|
||||
In order to convert to this layout you need to do the following in the seeddms51x
|
||||
directory (replace the 'x' in '5.1.x' with the correct number):
|
||||
|
||||
```
|
||||
ln -s seeddms-5.1.x seeddms
|
||||
mv www/conf .
|
||||
mv seeddms-5.1.x/ext www
|
||||
|
|
@ -98,8 +93,3 @@ ln -s ../seeddms/webdav
|
|||
ln -s ../seeddms/restapi
|
||||
ln -s ../seeddms/pdfviewer
|
||||
ln -s ../seeddms/index.php
|
||||
```
|
||||
|
||||
Since version 5.1.42 the layout has changed slightly again. The directory
|
||||
`pear` which had only a subdirectory `vendor` disappeared and the `vendor` has
|
||||
move one level up.
|
||||
|
|
@ -1,11 +1,12 @@
|
|||
# Extensions in SeedDMS
|
||||
Extensions in SeedDMS
|
||||
=====================
|
||||
|
||||
Since verson 5.0.0 SeedDMS can be extended by extensions. Extensions
|
||||
can hook up functions into certain operations, e.g.
|
||||
uploading, removing or displaying a document. They can also be
|
||||
used to modify some of the internal variables like the list of
|
||||
translations and they can even replace classes in the core of
|
||||
SeedDMS and hook up functions into certain operations in the core.
|
||||
seeddms and hook up functions into certain operations in the core.
|
||||
|
||||
All extensions are located in the folder 'ext'. Each extension
|
||||
has its own folder named by the name of the extension. The central
|
||||
|
|
@ -18,13 +19,12 @@ the extension manager if it was changed.
|
|||
|
||||
The integration into SeedDMS is done by hooks, class and file
|
||||
overloading. SeedDMS manages
|
||||
a globally available array of hooks (`$GLOBALS['SEEDDMS_HOOKS']`).
|
||||
This array has the elements `view` and `controller`. All entries
|
||||
a globally available array of hooks ($GLOBALS['SEEDDMS_HOOKS']).
|
||||
This array has the elements 'view' and 'controller'. All entries
|
||||
in those array elements contain instances of self defined classes
|
||||
containing the hook methods. For setting up the hooks in the view
|
||||
`viewFolder` the following code is needed.
|
||||
'viewFolder' the following code is needed.
|
||||
|
||||
```
|
||||
$GLOBALS['SEEDDMS_HOOKS']['view']['viewFolder'][] = new SeedDMS_ExtExample_ViewFolder;
|
||||
|
||||
class SeedDMS_ExtExample_ViewFolder {
|
||||
|
|
@ -39,16 +39,15 @@ $GLOBALS['SEEDDMS_HOOKS']['controller']['removeFolder'][] = new SeedDMS_ExtExamp
|
|||
class SeedDMS_ExtExample_RemoveFolder {
|
||||
...
|
||||
};
|
||||
```
|
||||
|
||||
Based on these two variants of adding hooks to the SeedDMS application code,
|
||||
the SeedDMS core can be extended by implementing the controller hook 'initDMS'
|
||||
Based on these two variants of adding hooks to the seeddms application code,
|
||||
the seeddms core can be extended by implementing the controller hook 'initDMS'
|
||||
which is called right after the class SeedDMS_Core_DMS has been initiated.
|
||||
|
||||
Beside hooks and callbacks another way of modifying SeedDMS is given
|
||||
Beside hooks and callbacks another way of modifying seeddms is given
|
||||
by overloading the files in the directory 'views' and 'controllers'. Both
|
||||
directories contain class files with a single class for either running
|
||||
controller or view code. If an extension provides those file in its
|
||||
own extension dir, they will be used instead of the files shipped with
|
||||
SeedDMS.
|
||||
seeddms.
|
||||
|
||||
18
doc/README.Fail2ban
Normal file
18
doc/README.Fail2ban
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
Adding authentication failure check for fail2ban
|
||||
=================================================
|
||||
|
||||
You will have to use 5.1.10 for this to work.
|
||||
|
||||
Add a filter /etc/fail2ban/filter.d/seeddms.conf with the content
|
||||
|
||||
[Definition]
|
||||
|
||||
failregex = \[error\] -- \(<HOST>\) op.Login login failed
|
||||
|
||||
then configure a new jail in /etc/fail2ban/jail.d/seeddms.conf
|
||||
|
||||
[seeddms]
|
||||
enabled = yes
|
||||
port = http,https
|
||||
filter = seeddms
|
||||
logpath = /home/www-data/seeddms-demo/data/log/*.log
|
||||
|
|
@ -1,33 +0,0 @@
|
|||
Adding authentication failure check for fail2ban
|
||||
=================================================
|
||||
|
||||
Fail2ban is a very mature and sophisticated program to detect attacks on
|
||||
a service by checking its log file. If such an attack was detected an
|
||||
action will be executed, which will mostly ban the IP of the attacker
|
||||
for a configurable amount of time.
|
||||
|
||||
You will have to use at least SeedDMS 5.1.10 for this to work.
|
||||
|
||||
Add a filter `/etc/fail2ban/filter.d/seeddms.conf` with the content
|
||||
|
||||
```
|
||||
[Definition]
|
||||
|
||||
failregex = \[error\] -- \(<HOST>\) op.Login login failed
|
||||
```
|
||||
|
||||
This will tell fail2ban which lines in the log file are considered
|
||||
to be an incident. Here it is a failed login.
|
||||
|
||||
Than configure a new jail in `/etc/fail2ban/jail.d/seeddms.conf`
|
||||
|
||||
```
|
||||
[seeddms]
|
||||
enabled = yes
|
||||
port = http,https
|
||||
filter = seeddms
|
||||
logpath = /home/www-data/seeddms-demo/data/log/*.log
|
||||
```
|
||||
|
||||
It tells fail2ban which log files shall be analysed, and which filter
|
||||
has to be applied.
|
||||
|
|
@ -241,8 +241,6 @@ in your current installation with new versions from the quickstart archive.
|
|||
3. copy the directory `pear` from the unpacked archive into your current
|
||||
installation, replacing the existing directory. Make a backup of `pear` before
|
||||
the replacement if you want to ensure to be able to go back to your old version.
|
||||
Since version 5.1.42 and 6.0.35 of SeeDMS the directory `pear` was replaced
|
||||
by `vendor`, which was previously a ѕubdirectory of `pear`.
|
||||
4. you may compare your `conf/settings.xml` file with the shipped version
|
||||
`conf/settings.xml.template` for new parameters. If you don't do it, the next
|
||||
time you save the configuration the default values will be used.
|
||||
|
|
@ -256,29 +254,6 @@ in your current installation with new versions from the quickstart archive.
|
|||
contain database updates.
|
||||
|
||||
|
||||
Installing from git
|
||||
====================
|
||||
|
||||
SeedDMS is hosted at https://codeberg.org/SeedDMS
|
||||
|
||||
In order to install SeedDMS you need to:
|
||||
|
||||
1. Create a directory, e.g. seeddms
|
||||
`mkdir seeddms`
|
||||
2. Change into that directory
|
||||
`cd seeddms`
|
||||
3. Clone the various SeedDMS repositories
|
||||
`git clone https://codeberg.org/SeedDMS/seeddms.git`
|
||||
`git clone -b seeddms-5.1.x https://codeberg.org/SeedDMS/core.git`
|
||||
`git clone https://codeberg.org/SeedDMS/preview.git`
|
||||
`git clone https://codeberg.org/SeedDMS/lucene.git`
|
||||
`git clone https://codeberg.org/SeedDMS/ѕqlitefts.git`
|
||||
`git clone https://codeberg.org/SeedDMS/http_webdav_server.git`
|
||||
4. Run composer
|
||||
`composer update`
|
||||
5. Create an installable distribution
|
||||
`vendor/bin/phing -Dversion=$(php -r 'include "inc/inc.Version.php"; echo (new SeedDMS_Version())->version();') package`
|
||||
|
||||
THE LONG STORY
|
||||
================
|
||||
|
||||
|
|
|
|||
66
doc/README.Ldap
Normal file
66
doc/README.Ldap
Normal file
|
|
@ -0,0 +1,66 @@
|
|||
Ldap configuration
|
||||
===================
|
||||
|
||||
The configuration for authentication against an ldap server needs to be done
|
||||
in the `settings.xml` file using a text editor. It cannot be edited from within the
|
||||
web gui.
|
||||
|
||||
SeedDMS supports ldap authentication using an Active Directory (AD) or a
|
||||
regular ldap server, e.g. openldap
|
||||
|
||||
The location of the ldap server is specified in two parameters: `host` and
|
||||
`port`. `host` can be either a plain hostname or an ldap URI, including the
|
||||
protocol, the host and optionally the port, e.g. ldap://localhost:389. In case
|
||||
of an URI the port in the configuration must remain empty.
|
||||
|
||||
The authentication itself is a two step process which differs, depending on how
|
||||
to bind to the server. If the configuration sets 'bindDN' and 'bindPW', those
|
||||
values will be used for a initial non anonymous bind to the ldap server
|
||||
otherwise an anonymous bind is executed.
|
||||
|
||||
After the initial bind, a ldap search for either 'uid=<username>' (ldap) or
|
||||
'sAMAccountName=<username>' (AD) below basedn is done. The purpose of this
|
||||
search is to retrieve a working bindDN which is then used to actually
|
||||
authenticate the user. In case of an anonymous first bind the search will
|
||||
likely fail and the bindDN for the second bind will be either
|
||||
'uid=<username>,<basedn>' (ldap) or '<username>@<accountDomainName>' (AD). If
|
||||
the search succeeds the bindDN will be taken from the user's data in the ldap
|
||||
server. This bindDN will be used for a second bind using the users password.
|
||||
If the second bind succeeds the user could be successfully authenticated.
|
||||
|
||||
The data from the ldap server can be used to create an account in SeedDMS
|
||||
if the user trying to login does not exist yet, but was able to authenticate.
|
||||
This will only be done if 'authentication->restricted' in the configuration
|
||||
is set to false. In that case the common name (cn) and email address is taken
|
||||
from ldap. An already existing account in SeedDMS will be updated with data from
|
||||
ldap.
|
||||
|
||||
Since version 5.1.35 and 6.0.28 the field name of the email address in ldap
|
||||
can be set with the attribute `mailField`. If it is not set it defaults to `mail`.
|
||||
|
||||
Since version 5.1.34 and 6.0.27 the groups of a user stored in the ldap directory
|
||||
can be synchronised with the groups in SeedDMS. The ldap field storing
|
||||
the groups can be configured with the attribute `mailField`. This will add
|
||||
new groups in SeedDMS and aѕsign them to the user.
|
||||
|
||||
Examples
|
||||
---------
|
||||
|
||||
Anonymous bind to openldap on localhost, port 389
|
||||
- type = "ldap"
|
||||
- baseDN = "ou=users,dc=mycompany,dc=de"
|
||||
- host = "ldap://localhost"
|
||||
|
||||
During authentication as user 'admin' the following steps are executed
|
||||
|
||||
1. connect to ldap server at localhost:389
|
||||
2. do an anonymous bind
|
||||
3. search for 'uid=admin' below basedn
|
||||
4.1. if search succeeds use the dn from the user
|
||||
4.2. if search fails use 'uid=admin,<basedn>' as dn
|
||||
5. do a non anonymous bind with dn and password entered by user
|
||||
6. if step 5. succeeds the use is authenticated
|
||||
|
||||
If bindDN and bindPW are specified in the configuration, the second step
|
||||
will be a non anonymous bind.
|
||||
|
||||
|
|
@ -1,118 +0,0 @@
|
|||
Ldap configuration
|
||||
===================
|
||||
|
||||
The configuration for authentication against an ldap server needs to be done
|
||||
in the `settings.xml` file using a text editor. It cannot be edited from within the
|
||||
web gui.
|
||||
|
||||
SeedDMS supports ldap authentication using an Active Directory (AD) or a
|
||||
regular ldap server, e.g. openldap
|
||||
|
||||
The location of the ldap server is specified in two parameters: `host` and
|
||||
`port`. `host` can be either a plain hostname or an ldap URI, including the
|
||||
protocol, the host and optionally the port, e.g. `ldap://localhost:389`. In case
|
||||
of an URI the port in the configuration must remain empty.
|
||||
|
||||
The authentication itself is a two step process which differs, depending on how
|
||||
to bind to the server. If the configuration sets `bindDN` and `bindPW`, those
|
||||
values will be used for a initial non anonymous bind to the ldap server
|
||||
otherwise an anonymous bind is executed.
|
||||
|
||||
After the initial bind, a ldap search for either `uid=<username>` (ldap) or
|
||||
`sAMAccountName=<username>` (AD) below basedn is done. The purpose of this
|
||||
search is to retrieve a working bindDN which is then used to actually
|
||||
authenticate the user. In case of a successful anonymous first bind but a
|
||||
failed search (this seems to be the case when connecting to an AD), a second
|
||||
non anonymous bind is tried. The bindDN for that second bind will be either
|
||||
`uid=<username>,<basedn>` (ldap) or `<username>@<accountDomainName>` (AD).
|
||||
If the search after the first anonymous bind succeeds, the bindDN will be
|
||||
taken from the user's data in the ldap
|
||||
server. This bindDN will be used for a second bind using the users password.
|
||||
If the second bind succeeds the user is successfully authenticated.
|
||||
|
||||
The data from the ldap server can be used to create or update an account in SeedDMS
|
||||
if the user trying to login does not exist yet, but was able to authenticate.
|
||||
This will only be done if 'authentication->restricted' in the configuration
|
||||
is set to false. In that case the common name (cn) and email address is taken
|
||||
from ldap. An already existing account in SeedDMS will be updated with data from
|
||||
ldap.
|
||||
|
||||
Since version 5.1.35 and 6.0.28 the field name of the email address in ldap
|
||||
can be set with the attribute `mailField`. If it is not set it defaults to `mail`.
|
||||
|
||||
Since version 5.1.34 and 6.0.27 the groups of a user stored in the ldap directory
|
||||
can be synchronised with the groups in SeedDMS. The ldap field storing
|
||||
the groups can be configured with the attribute `mailField`. This will add
|
||||
new groups in SeedDMS and assign them to the user.
|
||||
|
||||
Using email address for authentication
|
||||
---------------------------------------
|
||||
|
||||
Since version 5.1.34 and 6.0.27 the email can be used for authentication
|
||||
(requires `enableLoginByEmail` to be set in the configuration).
|
||||
This only works if the search after the first bind succeeds, which is usually
|
||||
only the case if it is a none anonymous bind.
|
||||
|
||||
Notes on connecting to an AD
|
||||
-----------------------------
|
||||
|
||||
The ldap authentication was originally implemented for classic LDAP servers
|
||||
like openldap. Before doing the actual authentication the user was searched
|
||||
by combining the user's login name and the configured baseDN. This search was
|
||||
preceded an anonymous or non anonymous bind (depending on wether bindDN and
|
||||
bindPWD are set). The only purpose of that search was to retrieve the
|
||||
distinguished name of the user, which was used in a second non anonymous bind
|
||||
for authenticating the user. If that search fails or didn't return a record
|
||||
(which seems to be always the case for an anonymous bind to an AD)
|
||||
a second non anonymous bind with the user's credentials is tried. That bind
|
||||
uses a dn which is quite different for classic ldap and AD (see examples
|
||||
below). The dn for an AD is of the form '<username>@<domain>'. '<domain>' is
|
||||
the string configured in the parameter `accountDomainName`.
|
||||
|
||||
Examples
|
||||
---------
|
||||
|
||||
### Anonymous bind to openldap on localhost, port 389
|
||||
|
||||
- type = "ldap"
|
||||
- baseDN = "ou=users,dc=mycompany,dc=de"
|
||||
- host = "ldap://localhost"
|
||||
|
||||
During authentication as user 'admin' the following steps are executed
|
||||
|
||||
1. connect to ldap server at localhost:389
|
||||
2. do an anonymous bind
|
||||
3.1 if the bind succeeds, search for `uid=admin` below basedn
|
||||
3.2 if the bind fails use `uid=admin,<basedn>` as dn and continue with step 5
|
||||
4.1. if search succeeds use the dn from the user
|
||||
4.2. if search fails use `uid=admin,<basedn>` as dn
|
||||
5. do a non anonymous bind with dn and password entered by user
|
||||
6. if step 5. succeeds the user is authenticated
|
||||
7. if `restricted` in the settings is *not* set another ldap search for the
|
||||
user is executed to retrieve the full name, and the email and if
|
||||
8.1 the user doesn't exist in SeedDMS, the user will be created or
|
||||
8.2 the user exists in SeedDMS, the use will be updated
|
||||
|
||||
If bindDN and bindPW are specified in the configuration, the second step
|
||||
will be a non anonymous bind.
|
||||
|
||||
### Connecting to an AD
|
||||
|
||||
- type = "AD"
|
||||
- baseDN = "ou=users,dc=mycompany,dc=de"
|
||||
- accountDomainName=mycompany
|
||||
- host = "ldap://localhost"
|
||||
|
||||
During authentication as user 'admin' the following steps are executed
|
||||
|
||||
1. connect to AD server at localhost:389
|
||||
2. do an anonymous bind (which usually succeeds)
|
||||
3. search for `uid=admin` below basedn (which usually returns an empty record)
|
||||
4. if search returns no data use `admin@<accountDomainName>` as dn
|
||||
5. do a non anonymous bind with dn and password entered by user
|
||||
6. if step 5. succeeds the user is authenticated
|
||||
7. if `restricted` in the settings is *not* set another ldap search for the
|
||||
user is executed to retrieve the full name, and the email and if
|
||||
8.1 the user doesn't exist in SeedDMS, the user will be created or
|
||||
8.2 the user exists in SeedDMS, the use will be updated
|
||||
|
||||
|
|
@ -126,3 +126,28 @@ op/op.TriggerWorkflow.php
|
|||
op/op.UpdateDocument.php
|
||||
* document was updated
|
||||
subscribers of the document
|
||||
|
||||
op/op.ReceiptDocument.php
|
||||
* document was received
|
||||
subscribers of the document
|
||||
|
||||
op/op.ReviseDocument.php
|
||||
* document was revised
|
||||
subscribers of the document
|
||||
|
||||
op/op.SetRevisors.php
|
||||
* Revisors were added/deleted
|
||||
subscribers of the document
|
||||
uploader of version
|
||||
revisor
|
||||
|
||||
op/op.ReceiptDocument.php
|
||||
* document was receipt
|
||||
subscribers of the document
|
||||
|
||||
op/op.SetRecipients.php
|
||||
* Recipients were added/deleted
|
||||
subscribers of the document
|
||||
uploader of version
|
||||
recipient
|
||||
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ session which is stored in a local file named `cookies.txt`.
|
|||
The authentication is done with the user `admin`. You may use any other
|
||||
user as well.
|
||||
|
||||
You can pass `-H Authorization: <api key>` instead of `-b cookies.txt`
|
||||
You may as well pass `-H Authorization: <api key>` instead of `-b cookies.txt`
|
||||
to `curl` after setting the api key in the configuration of your SeedDMS.
|
||||
Of course, in that case you will not need the initial call of the `login`
|
||||
endpoint.
|
||||
|
|
@ -48,16 +48,8 @@ curl --silent -H "Authorization: <api key>" -X GET "${BASEURL}restapi/index.php/
|
|||
## Notes
|
||||
|
||||
Make sure to encode the data properly when using restapi functions which uses
|
||||
`put`. If you use curl with PHP, then encode the data as show in the following
|
||||
lines of code:
|
||||
put. If you use curl with PHP, then encode the data as the following
|
||||
|
||||
```
|
||||
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($data));
|
||||
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type: application/x-www-form-urlencoded'));
|
||||
```
|
||||
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($data));
|
||||
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type: application/x-www-form-urlencoded'));
|
||||
|
||||
## Bruno
|
||||
|
||||
[Bruno](https://www.usebruno.com/) is an application for testing and exploring
|
||||
Rest APIs. This [git repository](https://codeberg.org/SeedDMS/bruno) contains
|
||||
the configuration for SeedDMS.
|
||||
|
|
|
|||
26
doc/README.Scheduler.md
Normal file
26
doc/README.Scheduler.md
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
Scheduler
|
||||
==========
|
||||
|
||||
The scheduler in SeedDMS manages frequently run tasks. It is very similar
|
||||
to regular unix cron jobs. A task in SeedDMS is an instanciation of a task
|
||||
class which itself is defined by an extension or SeedDMS itself.
|
||||
SeedDMS has some predefined classes e.g. core::expireddocs.
|
||||
|
||||
In order for tasks to be runnalbe, a user `cli_scheduler` must exists in
|
||||
SeedDMS.
|
||||
|
||||
All tasks are executed by a single cronjob in the directory `utils`
|
||||
|
||||
> */5 * * * * /home/www-data/seeddms60x/seeddms/utils/seeddms-schedulercli --mode=run
|
||||
|
||||
Please keep in mind, that the php interpreter used for the cronjob may be
|
||||
different from the php interpreter used für the web application. Hence, two
|
||||
different php.ini files might be used. php and the php extensions may differ as
|
||||
well. This can cause some extensions to be disabled and consequently some task
|
||||
classes are not defined.
|
||||
|
||||
`utils/seeddms-schedulercli` can also be run on the command line. If you
|
||||
do that, run it with the same system user used for the web server. On Debian
|
||||
this is www-data. Hence run it like
|
||||
|
||||
sudo -u www-data utils/seeddms-schedulercli --mode=list
|
||||
143
doc/README.Ubuntu
Normal file
143
doc/README.Ubuntu
Normal file
|
|
@ -0,0 +1,143 @@
|
|||
This README was written by Eric Smith
|
||||
|
||||
======================================================
|
||||
Steps that I took to install SeedDMS on Ubuntu 12.10
|
||||
- a personal account and not an authoritative guide.
|
||||
======================================================
|
||||
|
||||
Download four tar balls from;
|
||||
http://sourceforge.net/projects/seeddms/files/seeddms-4.0.0-pre5/
|
||||
|
||||
seeddms-4.0.0-pre5.tar.gz
|
||||
SeedDMS_Preview-1.0.0.tgz
|
||||
SeedDMS_Lucene-1.1.1.tgz
|
||||
SeedDMS_Core-4.0.0pre5.tgz
|
||||
|
||||
Install as follows the pear components:
|
||||
sudo pear install SeedDMS_Core-4.0.0pre5.tgz
|
||||
sudo pear install SeedDMS_Preview-1.0.0.tgz
|
||||
sudo pear install SeedDMS_Lucene-1.1.1.tgz
|
||||
|
||||
Download and install the pear Log application:
|
||||
wget http://download.pear.php.net/package/Log-1.12.7.tgz
|
||||
sudo pear install Log-1.12.7.tgz
|
||||
|
||||
And zend:
|
||||
sudo pear channel-discover zend.googlecode.com/svn
|
||||
sudo pear install zend/zend
|
||||
|
||||
I installed the following packages, not all of which may be required
|
||||
and you may require other packages, please check the dependencies on
|
||||
the README.md for example for full text search, you need pdftotext,
|
||||
catdoc, xls2csv or scconvert, cat, id3
|
||||
|
||||
sudo apt-get install php5-mysql php5-mysqlnd libapache2-mod-php5
|
||||
sudo apt-get install pdo_mysql php5-gd id3 scconvert
|
||||
sudo apt-get install php-http-webdav-server
|
||||
sudo apt-get install zend-framework zend-framework-bin
|
||||
sudo apt-get install libzend-framework-zendx-php
|
||||
sudo apt-get install libjs-dojo-core libjs-dojo-dijit libjs-dojo-dojox
|
||||
sudo apt-get install libzend-framework-php (It kept bitching about Zend so I just kept piling on packages until it worked)
|
||||
|
||||
mbstring is already a part of libapache2-mod-php5
|
||||
pepper:~> show libapache2-mod-php5|grep mbstring
|
||||
mbstring mhash openssl pcre Phar posix Reflection session shmop SimpleXML
|
||||
|
||||
|
||||
Define three locations:
|
||||
[1] Some cosy place in yourfile system for the source files to which you
|
||||
will link
|
||||
I chose "/opt/seeddms-4.0.0-pre5/"
|
||||
untar seeddms-4.0.0-pre5.tar.gz into this location
|
||||
|
||||
[2] Make a directory and three subdirectories for the data for your site;
|
||||
I chose to do this under "/opt/dms/seeddms_multisite_test/data"
|
||||
sudo mkdir -p /opt/dms/seeddms_multisite_test/data/lucene/
|
||||
sudo mkdir /opt/dms/seeddms_multisite_test/data/staging/
|
||||
sudo mkdir /opt/dms/seeddms_multisite_test/data/cache/
|
||||
|
||||
Give ownership (or write access) to your httpd process to those directories;
|
||||
sudo chown -cvR www-data /opt/dms/seeddms_multisite_test/data/
|
||||
|
||||
[3] Somewhere under your www root, make a directory for the sources of
|
||||
your site:
|
||||
These can be of course under different virtual domains.
|
||||
/var/www/www.mydomain.eu/seeddms_multisite_test
|
||||
cd /var/www/www.mydomain.eu/seeddms_multisite_test;
|
||||
sudo ln -s /opt/seeddms-4.0.0-pre5 src (README.md does not include the `src'!)
|
||||
ln -s src/inc inc
|
||||
ln -s src/op op
|
||||
ln -s src/out out
|
||||
ln -s src/js js
|
||||
ln -s src/views views
|
||||
ln -s src/languages languages
|
||||
ln -s src/styles styles
|
||||
ln -s src/themes themes
|
||||
ln -s src/install install
|
||||
ln -s src/index.php index.php
|
||||
|
||||
If need be;
|
||||
sudo chown -cvR www-data /var/www/www.mydomain.eu/seeddms_multisite_test/
|
||||
|
||||
Create Dataabse;
|
||||
Run the following sql commands to create your db and a user with
|
||||
appropriate privileges.
|
||||
|
||||
mysql> create database seeddms_multisite_test;
|
||||
mysql> grant all privileges on seeddms_multisite_test.* to seeddms@localhost identified by 'your_passwd';
|
||||
|
||||
|
||||
Point your browser to the location of your instance as in [3] above
|
||||
and /install
|
||||
I resorted to a text browser on my server due to failure to access the
|
||||
db from a remote browser;
|
||||
|
||||
pepper:~> elinks www.mydomain.eu/seeddms_multisite_test/install
|
||||
|
||||
This is how I filled it in;
|
||||
SeedDMS: INSTALL
|
||||
SeedDMS Installation for version 4.0.0
|
||||
|
||||
Server settings
|
||||
Root directory: /opt/seeddms-4.0.0-pre5/_______________________
|
||||
Http Root: /seeddms_multisite_test/_______________________
|
||||
Content directory: /opt/dms/seeddms_multisite_test/data___________
|
||||
Directory for full text index: /opt/dms/seeddms_multisite_test/data/lucene/___
|
||||
Directory for partial uploads: /opt/dms/seeddms_multisite_test/data/staging/__
|
||||
Core SeedDMS directory: _______________________________________________
|
||||
Lucene SeedDMS directory: _______________________________________________
|
||||
Extra PHP include Path: _______________________________________________
|
||||
Database settings
|
||||
Database Type: mysql________________
|
||||
Server name: localhost____________
|
||||
Database: seeddms_multisite_tes
|
||||
Username: seeddms______________
|
||||
Password: ********_____________
|
||||
Create database tables: [X]
|
||||
|
||||
[ Apply ]
|
||||
|
||||
|
||||
If all is okay (and I hope this happens more quickly for you than for me),
|
||||
you should be notified accordingly and invited to login to your new site
|
||||
with credentials admin/admin. (This password is cleverly set to expire
|
||||
in a couple of days. So do not get a shock like I did when it suddenly
|
||||
does not work).
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
To make additional sites;
|
||||
|
||||
If you wish to make additional sites, you need to copy the data directories thusly;
|
||||
sudo cp -avr /opt/dms/seeddms_multisite_test /opt/dms/seeddms_multisite_test_2
|
||||
And the sources thusly;
|
||||
sudo cp -avr /var/www/www.mydomain.eu/seeddms_multisite_test /var/www/www.mydomain.eu/seeddms_multisite_test_2
|
||||
|
||||
And of course make data directories for this site:
|
||||
sudo mkdir -p /opt/dms/seeddms_multisite_test_2/data/lucene/
|
||||
sudo mkdir /opt/dms/seeddms_multisite_test_2/data/staging/
|
||||
sudo mkdir /opt/dms/seeddms_multisite_test_2/data/cache/
|
||||
|
||||
Then create another database as shown above but of course give the db
|
||||
another name.
|
||||
Run the install again from the new location.
|
||||
|
|
@ -3,7 +3,7 @@ WebDAV
|
|||
|
||||
SeedDMS has support for WebDAV which allows to easily add, delete,
|
||||
move, copy and modify documents. All operating systems have support
|
||||
for WebDAV, but the implemtation and their behaviour varys
|
||||
for WebDAV as well, but the implemtations and their behaviour varys
|
||||
and consequently you may run into various problems. If this happens
|
||||
just file a bug report at https://sourceforge.net/projects/seeddms
|
||||
|
||||
|
|
@ -34,35 +34,27 @@ Configuring davfs2
|
|||
On Linux it is quite simple to mount the SeedDMS WebDAV server with
|
||||
davfs2. Just place a line like the following in your /etc/fstab
|
||||
|
||||
```
|
||||
http://seeddms.your-domain.com/webdav/index.php /media/webdav davfs noauto,user,rw,uid=1000,gid=1000
|
||||
```
|
||||
|
||||
and mount it as root with
|
||||
|
||||
```
|
||||
mount /media/webdav davfs
|
||||
```
|
||||
|
||||
You may as well want to configure davfs2 in /etc/davfs2/davfs2.conf by setting
|
||||
|
||||
```
|
||||
[/media/webdav]
|
||||
use_locks 0
|
||||
gui_optimize 1
|
||||
```
|
||||
|
||||
and possibly add your login data to `/etc/davfs2/secrets`
|
||||
and possibly add your login data to /etc/davfs2/secrets
|
||||
|
||||
```
|
||||
/media/webdav admin secret
|
||||
```
|
||||
|
||||
Making applications work with WebDAV
|
||||
-------------------------------------
|
||||
|
||||
Various programms have differnt strategies to save files to disc and
|
||||
to prevent data lost under all circumstances. Those strategies often don't
|
||||
prevent data lost under all circumstances. Those strategies often don't
|
||||
work very well an a WebDAV-Server. The following will list some of those
|
||||
strategies.
|
||||
|
||||
|
|
@ -87,25 +79,19 @@ the old document. If you don't want this behaviour, then tell vim
|
|||
to not create the backup file. You can do that by either passing additional
|
||||
parameters to vim
|
||||
|
||||
```
|
||||
vi "+set nobackup" "+set nowritebackup" -n test.txt
|
||||
```
|
||||
|
||||
or by setting them in your .vimrc
|
||||
|
||||
```
|
||||
set nobackup
|
||||
set nowritebackup
|
||||
set noswapfile
|
||||
```
|
||||
|
||||
If you want to restrict the settings to the directory where the dms
|
||||
is mounted by webdav, e.g. /media/webdav, you can set an auto command
|
||||
in `.vimrc`
|
||||
in .vimrc
|
||||
|
||||
```
|
||||
autocmd BufNewFile,BufRead /media/webdav/* set nobackup nowritebackup noswapfile
|
||||
```
|
||||
|
||||
Creating the backup file in a directory outside of WebDAV doesn't help in
|
||||
this case, because it still does the file renaming which is turned off by
|
||||
|
|
@ -121,9 +107,7 @@ If webdav access isn't working, this client is probably the best for testing.
|
|||
|
||||
Just run
|
||||
|
||||
```
|
||||
cadaver https://<your-domain>/<your-basedir>/webdav/index.php
|
||||
```
|
||||
|
||||
It will ask for the user name and password. Once you are logged in just
|
||||
type `help` for a list of commands.
|
||||
|
|
@ -131,27 +115,19 @@ type `help` for a list of commands.
|
|||
SeedDMS stores a lot more properties not covered by the webdav standard.
|
||||
Those have its own namespace called 'SeedDMS:'. Just type
|
||||
|
||||
```
|
||||
propget <resource>
|
||||
```
|
||||
|
||||
with `resource` being either the name of a folder or document. You will
|
||||
get a list of all properties stored for this resource. Setting a property
|
||||
requires to set the namespace first
|
||||
|
||||
```
|
||||
set namespace SeedDMS:
|
||||
```
|
||||
|
||||
Afterwards, you may set a property, e.g. the comment, with
|
||||
|
||||
```
|
||||
propset <resource> comment 'Just a comment'
|
||||
```
|
||||
|
||||
or even delete a property
|
||||
|
||||
```
|
||||
propdel <resource> comment
|
||||
```
|
||||
|
||||
42
doc/README.cron
Normal file
42
doc/README.cron
Normal file
|
|
@ -0,0 +1,42 @@
|
|||
Running the scheduler
|
||||
======================
|
||||
|
||||
Since version 6 of SeedDMS a scheduler is implemented which runs
|
||||
scheduled tasks. Such tasks must be implemented in an extension
|
||||
and can be scheduled by the administrator within the user interface.
|
||||
|
||||
In order to check frequently for tasks ready to run, a system cron job
|
||||
must be installed. On Linux this can be done by adding the following line
|
||||
to the crontab
|
||||
|
||||
*/5 * * * * /var/www/seeddms60x/seeddms/utils/seeddms-schedulercli --mode=run
|
||||
|
||||
(Of course you need to change the path to `seeddms-schedulercli`)
|
||||
|
||||
This will install a cronjob running every 5 minutes. `seeddms-schedulercli` will check
|
||||
for tasks ready to run and execute them in that case. You can decrease the time between
|
||||
two calls of the cronjob, but keep in mind that seeddms tasks may take longer and
|
||||
are being started again before the previous task has been ended.
|
||||
|
||||
If the configuration file of SeedDMS is not found, its path can be passed
|
||||
on the command, though this should not be needed in a regular installation
|
||||
obeying the directory structure of the quickstart archive.
|
||||
|
||||
*/5 * * * * /var/www/seeddms60x/seeddms/utils/seeddms-schedulercli --config /var/www/seeddms60x/seeddms/conf/settings.xml --mode=run
|
||||
|
||||
For testing purposes it may be usefull to run `seeddms-schedulercli` in list mode.
|
||||
|
||||
seeddms-schedulercli --mode=list
|
||||
|
||||
This will just list all tasks and its scheduled exection time. Tasks ready to run,
|
||||
because its scheduled execution time is already in the past will be marked with
|
||||
a `*`. Tasks which are disabled will be marked with a `-`.
|
||||
|
||||
Executing `seeddms-schedulercli` in `dryrun` mode will behave just like in `run` mode
|
||||
but instead of running the task it will just issue a line.
|
||||
|
||||
Instead of running utils/seeddms-schedulercli you may as well access
|
||||
op/op.Cron.php which also runs all scheduled tasks. On Linux you do this
|
||||
by setting up a cronjob like
|
||||
|
||||
*/5 * * * * wget -q -O - "http://<your domain>/op/op.Cron.php"
|
||||
59
doc/README.ocr
Normal file
59
doc/README.ocr
Normal file
|
|
@ -0,0 +1,59 @@
|
|||
OCR
|
||||
====
|
||||
|
||||
SeedDMS itself has no support for optical character recognition (OCR)
|
||||
because it does not care about the content of file. Though, external
|
||||
OCR software can be used to convert an image into text and index it
|
||||
by the full text search engine.
|
||||
|
||||
The following script can be use to convert a scanned image into pdf
|
||||
with a text layer added. The script actually takes this file to
|
||||
ran it through pdftotext. It was published in the seeddms forum
|
||||
https://sourceforge.net/p/seeddms/discussion/general/thread/4ec5973d/
|
||||
|
||||
|
||||
#!/bin/bash
|
||||
inputpdf=$1
|
||||
temp_folder=/tmp/seedinput/$(date +"%Y_%m_%d_%H%M%S")/
|
||||
lockfile=/tmp/seed
|
||||
protokolldatei=./tesser_syslog
|
||||
cores=2
|
||||
|
||||
mkdir -p $lockfile
|
||||
|
||||
while [ -e "$lockfile"/"`basename $0`" ];
|
||||
do
|
||||
sleep 5
|
||||
done
|
||||
|
||||
if ( set -o noclobber; echo "locked" > "$lockfile"/"`basename $0`"); then
|
||||
|
||||
trap 'rm -f "$lockfile"/"`basename $0`"; echo $(date) " Lockdatei wird geloescht: " $lockfile"/"`basename $0` Aufrufparameter: $* >> $protokolldatei ;rm -r $temp_folder; exit $?' INT TERM KILL EXIT
|
||||
#das Datum mit dem Scriptnamen in die Protokolldatei schreiben
|
||||
echo $(date) " Lockdatei erstellt: " $lockfile"/"`basename $0` >> $protokolldatei
|
||||
|
||||
else
|
||||
#Script beenden falls Lockdatei nicht erstellt werden konnte
|
||||
echo $(date) " Programm wird beendet, Lockdatei konnte nicht erstellt werden: $lockfile"/"`basename $0` Aufrufparameter: $* " >> $protokolldatei
|
||||
exit 1
|
||||
fi
|
||||
|
||||
mkdir -p $temp_folder
|
||||
|
||||
$(pdftotext -raw $1 - 1> $temp_folder''tmp.txt )
|
||||
pdf_contents=`cat $temp_folder''tmp.txt`
|
||||
pdf_contents=`echo "$pdf_contents" | tr -dc '[:print:]'`
|
||||
if [ -z "$pdf_contents" ]; then
|
||||
convert -density 300 -quality 95 $inputpdf +adjoin $temp_folder''image%03d.jpg
|
||||
find $temp_folder -name '*.jpg'| parallel --gnu -j $cores tesseract -l deu --psm 6 {} {} pdf
|
||||
|
||||
num=`find $temp_folder -name '*.pdf'| wc -l`
|
||||
if [ "$num" -gt "1" ]; then
|
||||
pdfunite $temp_folder*.pdf $temp_folder''tmp.pdf
|
||||
else
|
||||
mv $temp_folder*.pdf $temp_folder''tmp.pdf
|
||||
fi
|
||||
pdftotext $temp_folder''tmp.pdf $temp_folder''tmp.txt
|
||||
mv $temp_folder''tmp.pdf $1
|
||||
fi
|
||||
cat $temp_folder''tmp.txt
|
||||
|
|
@ -1,63 +0,0 @@
|
|||
OCR
|
||||
====
|
||||
|
||||
SeedDMS itself has no support for optical character recognition (OCR)
|
||||
because it does not care about the content of file. Though, external
|
||||
OCR software can be used to convert an image into text and index it
|
||||
by the full text search engine. From SeedDMS point of view, it would
|
||||
be sufficient to have a conversion service which converts an image
|
||||
into text. This can be implemented in any possible way, but most
|
||||
likely as a SeedDMS extension.
|
||||
|
||||
The following script can be use to convert a pdf with scanned images
|
||||
into a text. The script converts any page into a image, runs it through
|
||||
tesseract, which creates a pdf again containing a text layer. All those
|
||||
pdf documents will be united into a single pdf and through `pdftotext` again.
|
||||
It was published in the SeedDMS forum
|
||||
https://sourceforge.net/p/seeddms/discussion/general/thread/4ec5973d/
|
||||
|
||||
```
|
||||
#!/bin/bash
|
||||
inputpdf=$1
|
||||
temp_folder=/tmp/seedinput/$(date +"%Y_%m_%d_%H%M%S")/
|
||||
lockfile=/tmp/seed
|
||||
protokolldatei=./tesser_syslog
|
||||
cores=2
|
||||
|
||||
mkdir -p $lockfile
|
||||
|
||||
while [ -e "$lockfile"/"`basename $0`" ];
|
||||
do
|
||||
sleep 5
|
||||
done
|
||||
|
||||
if ( set -o noclobber; echo "locked" > "$lockfile"/"`basename $0`"); then
|
||||
trap 'rm -f "$lockfile"/"`basename $0`"; echo $(date) " Lock file will be deleted: " $lockfile"/"`basename $0` Aufrufparameter: $* >> $protokolldatei ;rm -r $temp_folder; exit $?' INT TERM KILL EXIT
|
||||
# write date and script name into log file
|
||||
echo $(date) " Lock file created: " $lockfile"/"`basename $0` >> $protokolldatei
|
||||
else
|
||||
# Exit script if lock file could not be created
|
||||
echo $(date) " Script will exit, because lock file could not be created: $lockfile"/"`basename $0` Aufrufparameter: $* " >> $protokolldatei
|
||||
exit 1
|
||||
fi
|
||||
|
||||
mkdir -p $temp_folder
|
||||
|
||||
$(pdftotext -raw $1 - 1> $temp_folder''tmp.txt )
|
||||
pdf_contents=`cat $temp_folder''tmp.txt`
|
||||
pdf_contents=`echo "$pdf_contents" | tr -dc '[:print:]'`
|
||||
if [ -z "$pdf_contents" ]; then
|
||||
convert -density 300 -quality 95 $inputpdf +adjoin $temp_folder''image%03d.jpg
|
||||
find $temp_folder -name '*.jpg'| parallel --gnu -j $cores tesseract -l deu --psm 6 {} {} pdf
|
||||
|
||||
num=`find $temp_folder -name '*.pdf'| wc -l`
|
||||
if [ "$num" -gt "1" ]; then
|
||||
pdfunite $temp_folder*.pdf $temp_folder''tmp.pdf
|
||||
else
|
||||
mv $temp_folder*.pdf $temp_folder''tmp.pdf
|
||||
fi
|
||||
pdftotext $temp_folder''tmp.pdf $temp_folder''tmp.txt
|
||||
mv $temp_folder''tmp.pdf $1
|
||||
fi
|
||||
cat $temp_folder''tmp.txt
|
||||
```
|
||||
|
|
@ -177,7 +177,32 @@ class SeedDMS_ExtExample_ViewFolder {
|
|||
* @package SeedDMS
|
||||
* @subpackage example
|
||||
*/
|
||||
class SeedDMS_ExtExample_Task {
|
||||
public function execute() {
|
||||
class SeedDMS_ExtExample_Task extends SeedDMS_SchedulerTaskBase {
|
||||
|
||||
/**
|
||||
* Run the task
|
||||
*
|
||||
* @param $task task to be executed
|
||||
* @return boolean true if task was executed succesfully, otherwise false
|
||||
*/
|
||||
public function execute($task) {
|
||||
$dms = $this->dms;
|
||||
$user = $this->user;
|
||||
$settings = $this->settings;
|
||||
$logger = $this->logger;
|
||||
$taskparams = $task->getParameter();
|
||||
return true;
|
||||
}
|
||||
|
||||
public function getDescription() {
|
||||
return 'Description';
|
||||
}
|
||||
|
||||
public function getAdditionalParams() {
|
||||
return array(array(
|
||||
'name'=>'email',
|
||||
'type'=>'string',
|
||||
'description'=> '',
|
||||
));
|
||||
}
|
||||
}
|
||||
|
|
@ -1,7 +1,7 @@
|
|||
<?php
|
||||
$EXT_CONF['example'] = array(
|
||||
'title' => 'Example Extension',
|
||||
'description' => 'This sample extension demonstrate the use of various hooks',
|
||||
'description' => 'This sample extension demonstrates the use of various hooks',
|
||||
'disable' => true,
|
||||
'version' => '1.0.1',
|
||||
'releasedate' => '2018-03-21',
|
||||
|
Before Width: | Height: | Size: 5.1 KiB After Width: | Height: | Size: 5.1 KiB |
9
ext/example/lang.php
Normal file
9
ext/example/lang.php
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
<?php
|
||||
$__lang['de_DE'] = array(
|
||||
'folder_contents' => 'Dies war mal "Ordner enthält". Wurde von sample Extension geändert.',
|
||||
'task_example_example_email' => 'Email',
|
||||
);
|
||||
$__lang['en_GB'] = array(
|
||||
'folder_contents' => 'This used to be "Folder contents". Was changed by sample Extension.',
|
||||
'task_example_example_email' => 'Email',
|
||||
);
|
||||
|
|
@ -12,8 +12,6 @@
|
|||
* @version Release: @package_version@
|
||||
*/
|
||||
|
||||
use Seeddms\Seeddms\Session;
|
||||
|
||||
require_once("inc.ClassSession.php");
|
||||
require_once("inc.ClassAccessOperation.php");
|
||||
|
||||
|
|
@ -23,17 +21,23 @@ if (!strncmp("/op", $refer, 3)) {
|
|||
} else {
|
||||
$refer = urlencode($refer);
|
||||
}
|
||||
|
||||
/* Check if this is a ajax call. In that case do not redirect to any page */
|
||||
$isajax = isset($_GET['action']) && ($_GET['action'] != 'show');
|
||||
|
||||
if (!isset($_COOKIE["mydms_session"])) {
|
||||
if($settings->_enableGuestLogin && $settings->_enableGuestAutoLogin) {
|
||||
$session = new Session($db);
|
||||
$session = new SeedDMS_Session($db);
|
||||
if(!$dms_session = $session->create(array('userid'=>$settings->_guestID, 'theme'=>$settings->_theme, 'lang'=>$settings->_language))) {
|
||||
header("Location: " . $settings->_httpRoot . "out/out.Login.php?referuri=".$refer);
|
||||
if(!$isajax)
|
||||
header("Location: " . $settings->_httpRoot . "out/out.Login.php?referuri=".$refer);
|
||||
exit;
|
||||
}
|
||||
$resArr = $session->load($dms_session);
|
||||
} elseif($settings->_autoLoginUser) {
|
||||
if(!($user = $dms->getUser($settings->_autoLoginUser))/* || !$user->isGuest()*/) {
|
||||
header("Location: " . $settings->_httpRoot . "out/out.Login.php?referuri=".$refer);
|
||||
if(!$isajax)
|
||||
header("Location: " . $settings->_httpRoot . "out/out.Login.php?referuri=".$refer);
|
||||
exit;
|
||||
}
|
||||
$theme = $user->getTheme();
|
||||
|
|
@ -46,29 +50,30 @@ if (!isset($_COOKIE["mydms_session"])) {
|
|||
$lang = $settings->_language;
|
||||
$user->setLanguage($lang);
|
||||
}
|
||||
$session = new Session($db);
|
||||
$session = new SeedDMS_Session($db);
|
||||
if(!$dms_session = $session->create(array('userid'=>$user->getID(), 'theme'=>$theme, 'lang'=>$lang))) {
|
||||
header("Location: " . $settings->_httpRoot . "out/out.Login.php?referuri=".$refer);
|
||||
if(!$isajax)
|
||||
header("Location: " . $settings->_httpRoot . "out/out.Login.php?referuri=".$refer);
|
||||
exit;
|
||||
}
|
||||
$resArr = $session->load($dms_session);
|
||||
} else {
|
||||
header("Location: " . $settings->_httpRoot . "out/out.Login.php?referuri=".$refer);
|
||||
if(!$isajax)
|
||||
header("Location: " . $settings->_httpRoot . "out/out.Login.php?referuri=".$refer);
|
||||
exit;
|
||||
}
|
||||
} else {
|
||||
/* Load session */
|
||||
$dms_session = $_COOKIE["mydms_session"];
|
||||
$session = new Session($db);
|
||||
$session = new SeedDMS_Session($db);
|
||||
if(!$resArr = $session->load($dms_session)) {
|
||||
setcookie("mydms_session", $dms_session, time()-3600, $settings->_httpRoot); //delete cookie
|
||||
header("Location: " . $settings->_httpRoot . "out/out.Login.php?referuri=".$refer);
|
||||
if(!$isajax)
|
||||
header("Location: " . $settings->_httpRoot . "out/out.Login.php?referuri=".$refer);
|
||||
exit;
|
||||
}
|
||||
}
|
||||
|
||||
$translator->setDefaultLanguage($session->getLanguage());
|
||||
|
||||
/* Update last access time */
|
||||
if((int)$resArr['lastAccess']+60 < time())
|
||||
$session->updateAccess($dms_session);
|
||||
|
|
@ -77,13 +82,16 @@ if((int)$resArr['lastAccess']+60 < time())
|
|||
$user = $dms->getUser($resArr["userID"]);
|
||||
if (!is_object($user)) {
|
||||
setcookie("mydms_session", $dms_session, time()-3600, $settings->_httpRoot); //delete cookie
|
||||
header("Location: " . $settings->_httpRoot . "out/out.Login.php?referuri=".$refer);
|
||||
if(!$isajax)
|
||||
header("Location: " . $settings->_httpRoot . "out/out.Login.php?referuri=".$refer);
|
||||
exit;
|
||||
}
|
||||
|
||||
if($user->isAdmin()) {
|
||||
if($resArr["su"]) {
|
||||
$user = $dms->getUser($resArr["su"]);
|
||||
$origuser = null;
|
||||
if($resArr["su"] && $su = $dms->getUser($resArr["su"])) {
|
||||
if($user->isAdmin() || $user->maySwitchToUser($su)) {
|
||||
$origuser = $user;
|
||||
$user = $su;
|
||||
} else {
|
||||
// $session->resetSu();
|
||||
}
|
||||
|
|
@ -96,6 +104,8 @@ if($settings->_useHomeAsRootFolder && !$user->isAdmin() && $user->getHomeFolder(
|
|||
$dms->checkWithinRootDir = true;
|
||||
$dms->setRootFolderID($user->getHomeFolder());
|
||||
}
|
||||
$role = $user->getRole();
|
||||
$dms->noReadForStatus = $role->getNoAccess();
|
||||
|
||||
/* Include additional language file for view
|
||||
* This file must set $LANG[xx][]
|
||||
|
|
@ -104,13 +114,17 @@ if(file_exists($settings->_rootDir . "view/".$theme."/languages/" . $lang . "/la
|
|||
include $settings->_rootDir . "view/".$theme."/languages/" . $lang . "/lang.inc";
|
||||
}
|
||||
|
||||
/* if this is a ajax call, then exit early as the rest of the script is irrelevant */
|
||||
if($isajax)
|
||||
return;
|
||||
|
||||
/* Check if password needs to be changed because it expired. If it needs
|
||||
* to be changed redirect to out/out.ForcePasswordChange.php. Do this
|
||||
* check only if password expiration is turned on, we are not on the
|
||||
* page to change the password or the page that changes the password, the
|
||||
* current user is not admin, and no user substitution has occured. */
|
||||
|
||||
if (!$user->isAdmin() && !$resArr['su']) {
|
||||
if (!$user->isAdmin() && $origuser == null) {
|
||||
if($settings->_passwordExpiration > 0) {
|
||||
if(basename($_SERVER['SCRIPT_NAME']) != 'out.ForcePasswordChange.php' && basename($_SERVER['SCRIPT_NAME']) != 'op.EditUserData.php' && basename($_SERVER['SCRIPT_NAME']) != 'op.Logout.php') {
|
||||
$pwdexp = $user->getPwdExpiration();
|
||||
|
|
@ -125,6 +139,17 @@ if (!$user->isAdmin() && !$resArr['su']) {
|
|||
}
|
||||
}
|
||||
|
||||
/* Check if secret is set for 2-factor authentication. Redirect to Setup2Factor.php
|
||||
* if secret is not set and 2-factor authentication is turned on. Also check if
|
||||
* already on the page Setup2Factor.php and no user substiation has occured.
|
||||
*/
|
||||
if($settings->_enable2FactorAuthentication && $settings->_guestID != $user->getID() && $settings->_autoLoginUser != $user->getID() && $origuser == null && $user->getSecret() == '') {
|
||||
if(basename($_SERVER['SCRIPT_NAME']) != 'out.Setup2Factor.php' && basename($_SERVER['SCRIPT_NAME']) != 'op.Setup2Factor.php') {
|
||||
header("Location: ../out/out.Setup2Factor.php");
|
||||
exit;
|
||||
}
|
||||
}
|
||||
|
||||
/* Update cookie lifetime */
|
||||
if($settings->_cookieLifetime) {
|
||||
$lifetime = time() + intval($settings->_cookieLifetime);
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@ require_once('inc.ClassAuthenticationService.php');
|
|||
require_once('inc.ClassDbAuthentication.php');
|
||||
require_once('inc.ClassLdapAuthentication.php');
|
||||
|
||||
global $logger;
|
||||
$authenticator = new SeedDMS_AuthenticationService($logger, $settings);
|
||||
|
||||
if(isset($GLOBALS['SEEDDMS_HOOKS']['authentication'])) {
|
||||
|
|
|
|||
41
inc/inc.BasicAuthentication.php
Normal file
41
inc/inc.BasicAuthentication.php
Normal file
|
|
@ -0,0 +1,41 @@
|
|||
<?php
|
||||
/**
|
||||
* Do authentication of users and session management
|
||||
*
|
||||
* @category DMS
|
||||
* @package SeedDMS
|
||||
* @license GPL 2
|
||||
* @version @version@
|
||||
* @author Markus Westphal, Malcolm Cowe, Uwe Steinmann <uwe@steinmann.cx>
|
||||
* @copyright Copyright (C) 2002-2005 Markus Westphal,
|
||||
* 2006-2008 Malcolm Cowe, 2010 Uwe Steinmann
|
||||
* @version Release: @package_version@
|
||||
*/
|
||||
|
||||
require_once("inc.Utils.php");
|
||||
require_once("inc.ClassNotificationService.php");
|
||||
require_once("inc.ClassEmailNotify.php");
|
||||
require_once("inc.ClassSession.php");
|
||||
require_once("inc.ClassAccessOperation.php");
|
||||
|
||||
if (!isset($_SERVER['PHP_AUTH_USER'])) {
|
||||
header('WWW-Authenticate: Basic realm="'.$settings->_siteName.'"');
|
||||
header('HTTP/1.0 401 Unauthorized');
|
||||
echo getMLText('cancel_basic_authentication');
|
||||
exit;
|
||||
} else {
|
||||
if(!($user = $authenticator->authenticate($_SERVER['PHP_AUTH_USER'], $_SERVER['PHP_AUTH_PW']))) {
|
||||
header('WWW-Authenticate: Basic realm="'.$settings->_siteName.'"');
|
||||
header('HTTP/1.0 401 Unauthorized');
|
||||
echo getMLText('cancel_basic_authentication');
|
||||
exit;
|
||||
}
|
||||
}
|
||||
|
||||
/* Clear login failures if login was successful */
|
||||
$user->clearLoginFailures();
|
||||
|
||||
$dms->setUser($user);
|
||||
|
||||
require_once('inc/inc.Notification.php');
|
||||
|
||||
|
|
@ -11,6 +11,8 @@
|
|||
* @version Release: @package_version@
|
||||
*/
|
||||
|
||||
require_once "inc.ClassAcl.php";
|
||||
|
||||
/**
|
||||
* Class to check certain access restrictions
|
||||
*
|
||||
|
|
@ -27,33 +29,32 @@ class SeedDMS_AccessOperation {
|
|||
*/
|
||||
private $dms;
|
||||
|
||||
/**
|
||||
* @var object $obj object being accessed
|
||||
* @access protected
|
||||
*/
|
||||
private $obj;
|
||||
|
||||
/**
|
||||
* @var object $user user requesting the access
|
||||
* @access protected
|
||||
*/
|
||||
private $user;
|
||||
protected $user;
|
||||
|
||||
/**
|
||||
* @var object $settings SeedDMS Settings
|
||||
* @access protected
|
||||
*/
|
||||
private $settings;
|
||||
protected $settings;
|
||||
|
||||
/**
|
||||
* @var array $legacy_access list of objects with access
|
||||
* @var object $aro access request object for caching
|
||||
* @access protected
|
||||
*/
|
||||
private $_aro;
|
||||
|
||||
/**
|
||||
* @var array $legacy_access list of objects with access use for view and controller
|
||||
* @access protected
|
||||
*/
|
||||
private $legacy_access;
|
||||
|
||||
function __construct($dms, $obj, $user, $settings) { /* {{{ */
|
||||
function __construct($dms, $user, $settings) { /* {{{ */
|
||||
$this->dms = $dms;
|
||||
$this->obj = $obj;
|
||||
$this->user = $user;
|
||||
$this->settings = $settings;
|
||||
$this->legacy_access['guest'] = array(
|
||||
|
|
@ -80,6 +81,7 @@ class SeedDMS_AccessOperation {
|
|||
'CategoryChooser',
|
||||
'ChangePassword',
|
||||
'CheckInDocument',
|
||||
'CheckOutDocument',
|
||||
'Clipboard',
|
||||
'Dashboard',
|
||||
'DocumentAccess',
|
||||
|
|
@ -163,15 +165,15 @@ class SeedDMS_AccessOperation {
|
|||
* document may delete versions. The admin may even delete a version
|
||||
* even if is disallowed in the settings.
|
||||
*/
|
||||
function mayEditVersion($vno=0) { /* {{{ */
|
||||
if($this->obj->isType('document')) {
|
||||
function mayEditVersion($document, $vno=0) { /* {{{ */
|
||||
if($document->isType('document')) {
|
||||
if($vno)
|
||||
$version = $this->obj->getContentByVersion($vno);
|
||||
$version = $document->getContentByVersion($vno);
|
||||
else
|
||||
$version = $this->obj->getLatestContent();
|
||||
$version = $document->getLatestContent();
|
||||
if (!isset($this->settings->_editOnlineFileTypes) || !is_array($this->settings->_editOnlineFileTypes) || (!in_array(strtolower($version->getFileType()), $this->settings->_editOnlineFileTypes) && !in_array(strtolower($version->getMimeType()), $this->settings->_editOnlineFileTypes)))
|
||||
return false;
|
||||
if ($this->obj->getAccessMode($this->user) == M_ALL || $this->user->isAdmin()) {
|
||||
if ($document->getAccessMode($this->user) == M_ALL || $this->user->isAdmin()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
@ -187,10 +189,10 @@ class SeedDMS_AccessOperation {
|
|||
* document may delete versions. The admin may even delete a version
|
||||
* even if is disallowed in the settings.
|
||||
*/
|
||||
function mayRemoveVersion() { /* {{{ */
|
||||
if($this->obj->isType('document')) {
|
||||
$versions = $this->obj->getContent();
|
||||
if ((($this->settings->_enableVersionDeletion && ($this->obj->getAccessMode($this->user, 'removeVersion') == M_ALL)) || $this->user->isAdmin() ) && (count($versions) > 1)) {
|
||||
function mayRemoveVersion($document) { /* {{{ */
|
||||
if($document->isType('document')) {
|
||||
$versions = $document->getContent();
|
||||
if ((($this->settings->_enableVersionDeletion && ($document->getAccessMode($this->user, 'removeVersion') == M_ALL)) || $this->user->isAdmin() ) && (count($versions) > 1)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
@ -207,11 +209,11 @@ class SeedDMS_AccessOperation {
|
|||
* The admin may even modify the status
|
||||
* even if is disallowed in the settings.
|
||||
*/
|
||||
function mayOverwriteStatus() { /* {{{ */
|
||||
if($this->obj->isType('document')) {
|
||||
if($latestContent = $this->obj->getLatestContent()) {
|
||||
function mayOverrideStatus($document) { /* {{{ */
|
||||
if($document->isType('document')) {
|
||||
if($latestContent = $document->getLatestContent()) {
|
||||
$status = $latestContent->getStatus();
|
||||
if ((($this->settings->_enableVersionModification && ($this->obj->getAccessMode($this->user) == M_ALL)) || $this->user->isAdmin()) && ($status["status"]==S_RELEASED || $status["status"]==S_OBSOLETE )) {
|
||||
if ((($this->settings->_enableVersionModification && ($document->getAccessMode($this->user) == M_ALL)) || $this->user->isAdmin()) && ($status["status"]==S_DRAFT || $status["status"]==S_RELEASED || $status["status"]==S_REJECTED || $status["status"]==S_OBSOLETE || $status["status"]==S_NEEDS_CORRECTION)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
@ -226,12 +228,13 @@ class SeedDMS_AccessOperation {
|
|||
* reviewers/approvers is only allowed if version modification is turned on
|
||||
* in the settings and the document has not been reviewed/approved by any
|
||||
* user/group already.
|
||||
* The admin may even set reviewers/approvers if is disallowed in the
|
||||
* settings.
|
||||
* The admin may even set reviewers/approvers after the review/approval
|
||||
* process has been started, but only if _allowChangeRevAppInProcess
|
||||
* explicitly allows it.
|
||||
*/
|
||||
function maySetReviewersApprovers() { /* {{{ */
|
||||
if($this->obj->isType('document')) {
|
||||
if($latestContent = $this->obj->getLatestContent()) {
|
||||
function maySetReviewersApprovers($document) { /* {{{ */
|
||||
if($document->isType('document')) {
|
||||
if($latestContent = $document->getLatestContent()) {
|
||||
$status = $latestContent->getStatus();
|
||||
$reviewstatus = $latestContent->getReviewStatus();
|
||||
$hasreview = false;
|
||||
|
|
@ -245,7 +248,49 @@ class SeedDMS_AccessOperation {
|
|||
if($r['status'] == 1 || $r['status'] == -1)
|
||||
$hasapproval = true;
|
||||
}
|
||||
if ((($this->settings->_enableVersionModification && ($this->obj->getAccessMode($this->user) == M_ALL)) || $this->user->isAdmin()) && (($status["status"]==S_DRAFT_REV && !$hasreview) || ($status["status"]==S_DRAFT_APP && !$hasreview && !$hasapproval))) {
|
||||
if ((($this->settings->_enableVersionModification && ($document->getAccessMode($this->user) == M_ALL)) || $this->user->isAdmin()) && (($status["status"]==S_DRAFT_REV && (!$hasreview || ($this->user->isAdmin() && $this->settings->_allowChangeRevAppInProcess))) || ($status["status"]==S_DRAFT_APP && ((!$hasreview && !$hasapproval) || ($this->user->isAdmin() && $this->settings->_allowChangeRevAppInProcess))) || $status["status"]==S_DRAFT)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
} /* }}} */
|
||||
|
||||
/**
|
||||
* Check if recipients may be edited
|
||||
*
|
||||
* This check can only be done for documents. Setting the document
|
||||
* recipients is only allowed if version modification is turned on
|
||||
* in the settings. The
|
||||
* admin may even set recipients if is disallowed in the
|
||||
* settings.
|
||||
*/
|
||||
function maySetRecipients($document) { /* {{{ */
|
||||
if($document->isType('document')) {
|
||||
if($latestContent = $document->getLatestContent()) {
|
||||
$status = $latestContent->getStatus();
|
||||
if (($this->settings->_enableVersionModification && ($document->getAccessMode($this->user) >= M_READWRITE)) || $this->user->isAdmin()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
} /* }}} */
|
||||
|
||||
/**
|
||||
* Check if revisors may be edited
|
||||
*
|
||||
* This check can only be done for documents. Setting the document
|
||||
* revisors is only allowed if version modification is turned on
|
||||
* in the settings. The
|
||||
* admin may even set revisors if is disallowed in the
|
||||
* settings.
|
||||
*/
|
||||
function maySetRevisors($document) { /* {{{ */
|
||||
if($document->isType('document')) {
|
||||
if($latestContent = $document->getLatestContent()) {
|
||||
$status = $latestContent->getStatus();
|
||||
if ((($this->settings->_enableVersionModification && ($document->getAccessMode($this->user) == M_ALL)) || $this->user->isAdmin()) && ($status["status"]==S_RELEASED || $status["status"]==S_IN_REVISION)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
@ -262,12 +307,12 @@ class SeedDMS_AccessOperation {
|
|||
* admin may even set the workflow if is disallowed in the
|
||||
* settings.
|
||||
*/
|
||||
function maySetWorkflow() { /* {{{ */
|
||||
if($this->obj->isType('document')) {
|
||||
if($latestContent = $this->obj->getLatestContent()) {
|
||||
function maySetWorkflow($document) { /* {{{ */
|
||||
if($document->isType('document')) {
|
||||
if($latestContent = $document->getLatestContent()) {
|
||||
$workflow = $latestContent->getWorkflow();
|
||||
$workflowstate = $latestContent->getWorkflowState();
|
||||
if ((($this->settings->_enableVersionModification && ($this->obj->getAccessMode($this->user) == M_ALL)) || $this->user->isAdmin()) && (!$workflow || ($workflowstate && ($workflow->getInitState()->getID() == $workflowstate->getID())))) {
|
||||
if ((($this->settings->_enableVersionModification && ($document->getAccessMode($this->user) == M_ALL)) || $this->user->isAdmin()) && (!$workflow || ($workflowstate && ($workflow->getInitState()->getID() == $workflowstate->getID())))) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
@ -281,11 +326,11 @@ class SeedDMS_AccessOperation {
|
|||
* This check can only be done for documents. Setting the documents
|
||||
* expiration date is only allowed if the document has not been obsoleted.
|
||||
*/
|
||||
function maySetExpires() { /* {{{ */
|
||||
if($this->obj->isType('document')) {
|
||||
if($latestContent = $this->obj->getLatestContent()) {
|
||||
function maySetExpires($document) { /* {{{ */
|
||||
if($document->isType('document')) {
|
||||
if($latestContent = $document->getLatestContent()) {
|
||||
$status = $latestContent->getStatus();
|
||||
if ((($this->obj->getAccessMode($this->user) == M_ALL) || $this->user->isAdmin()) && ($status["status"]!=S_OBSOLETE)) {
|
||||
if ((($document->getAccessMode($this->user) >= M_READWRITE) || $this->user->isAdmin()) && ($status["status"]!=S_OBSOLETE)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
@ -302,17 +347,17 @@ class SeedDMS_AccessOperation {
|
|||
* The admin may set the comment even if is
|
||||
* disallowed in the settings.
|
||||
*/
|
||||
function mayEditComment() { /* {{{ */
|
||||
if($this->obj->isType('document')) {
|
||||
if($this->obj->getAccessMode($this->user) < M_READWRITE)
|
||||
function mayEditComment($document) { /* {{{ */
|
||||
if($document->isType('document')) {
|
||||
if($document->getAccessMode($this->user) < M_READWRITE)
|
||||
return false;
|
||||
if($this->obj->isLocked()) {
|
||||
$lockingUser = $this->obj->getLockingUser();
|
||||
if (($lockingUser->getID() != $this->user->getID()) && ($this->obj->getAccessMode($this->user) != M_ALL)) {
|
||||
if($document->isLocked()) {
|
||||
$lockingUser = $document->getLockingUser();
|
||||
if (($lockingUser->getID() != $this->user->getID()) && ($document->getAccessMode($this->user) != M_ALL)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if($latestContent = $this->obj->getLatestContent()) {
|
||||
if($latestContent = $document->getLatestContent()) {
|
||||
$status = $latestContent->getStatus();
|
||||
if (($this->settings->_enableVersionModification || $this->user->isAdmin()) && !in_array($status["status"], array(S_OBSOLETE, S_EXPIRED))) {
|
||||
return true;
|
||||
|
|
@ -330,15 +375,15 @@ class SeedDMS_AccessOperation {
|
|||
* the settings or the document is still in an approval/review
|
||||
* or intial workflow step.
|
||||
*/
|
||||
function mayEditAttributes() { /* {{{ */
|
||||
if($this->obj->isType('document')) {
|
||||
if($latestContent = $this->obj->getLatestContent()) {
|
||||
function mayEditAttributes($document) { /* {{{ */
|
||||
if($document->isType('document')) {
|
||||
if($latestContent = $document->getLatestContent()) {
|
||||
$status = $latestContent->getStatus();
|
||||
$workflow = $latestContent->getWorkflow();
|
||||
$workflowstate = $latestContent->getWorkflowState();
|
||||
if($this->obj->getAccessMode($this->user) < M_READWRITE)
|
||||
if($document->getAccessMode($this->user) < M_READWRITE)
|
||||
return false;
|
||||
if ($this->settings->_enableVersionModification || in_array($status["status"], array(S_DRAFT_REV, S_DRAFT_APP)) || ($workflow && $workflowstate && $workflow->getInitState()->getID() == $workflowstate->getID())) {
|
||||
if ($this->settings->_enableVersionModification || in_array($status["status"], array(S_DRAFT_REV, S_DRAFT_APP, S_IN_REVISION)) || ($workflow && $workflowstate && $workflow->getInitState()->getID() == $workflowstate->getID())) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
@ -353,11 +398,11 @@ class SeedDMS_AccessOperation {
|
|||
* review. There are other requirements which are not taken into
|
||||
* account here.
|
||||
*/
|
||||
function mayReview() { /* {{{ */
|
||||
if($this->obj->isType('document')) {
|
||||
if($latestContent = $this->obj->getLatestContent()) {
|
||||
function mayReview($document) { /* {{{ */
|
||||
if($document->isType('document')) {
|
||||
if($latestContent = $document->getLatestContent()) {
|
||||
$status = $latestContent->getStatus();
|
||||
if ($status["status"]==S_DRAFT_REV) {
|
||||
if ($document->getAccessMode($this->user) >= M_READ && $status["status"]==S_DRAFT_REV) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
@ -371,9 +416,24 @@ class SeedDMS_AccessOperation {
|
|||
* A review may only be updated by the user who originaly addedd the
|
||||
* review and if it is allowed in the settings
|
||||
*/
|
||||
function mayUpdateReview($updateUser) { /* {{{ */
|
||||
if($this->obj->isType('document')) {
|
||||
if($this->settings->_enableUpdateRevApp && ($updateUser == $this->user) && !$this->obj->hasExpired()) {
|
||||
function mayUpdateReview($document, $updateUser) { /* {{{ */
|
||||
if($document->isType('document')) {
|
||||
if($this->settings->_enableUpdateRevApp && ($updateUser == $this->user) && $document->getAccessMode($this->user) >= M_READ && !$document->hasExpired()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
} /* }}} */
|
||||
|
||||
/**
|
||||
* Check if a approval maybe edited
|
||||
*
|
||||
* An approval may only be updated by the user who originaly addedd the
|
||||
* approval and if it is allowed in the settings
|
||||
*/
|
||||
function mayUpdateApproval($document, $updateUser) { /* {{{ */
|
||||
if($document->isType('document')) {
|
||||
if($this->settings->_enableUpdateRevApp && ($updateUser == $this->user) && $document->getAccessMode($this->user) >= M_READ && !$document->hasExpired()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
@ -389,11 +449,11 @@ class SeedDMS_AccessOperation {
|
|||
* There are other requirements which are not taken into
|
||||
* account here.
|
||||
*/
|
||||
function mayApprove() { /* {{{ */
|
||||
if($this->obj->isType('document')) {
|
||||
if($latestContent = $this->obj->getLatestContent()) {
|
||||
function mayApprove($document) { /* {{{ */
|
||||
if($document->isType('document')) {
|
||||
if($latestContent = $document->getLatestContent()) {
|
||||
$status = $latestContent->getStatus();
|
||||
if ($status["status"]==S_DRAFT_APP) {
|
||||
if ($document->getAccessMode($this->user) >= M_READ && $status["status"]==S_DRAFT_APP) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
@ -402,14 +462,70 @@ class SeedDMS_AccessOperation {
|
|||
} /* }}} */
|
||||
|
||||
/**
|
||||
* Check if a approval maybe edited
|
||||
* Check if document content may be receipted
|
||||
*
|
||||
* An approval may only be updated by the user who originaly addedd the
|
||||
* approval and if it is allowed in the settings
|
||||
* Reviewing a document content is only allowed if the document was not
|
||||
* obsoleted. There are other requirements which are not taken into
|
||||
* account here.
|
||||
*/
|
||||
function mayUpdateApproval($updateUser) { /* {{{ */
|
||||
if($this->obj->isType('document')) {
|
||||
if($this->settings->_enableUpdateRevApp && ($updateUser == $this->user) && !$this->obj->hasExpired()) {
|
||||
function mayReceipt($document) { /* {{{ */
|
||||
if($document->isType('document')) {
|
||||
if($latestContent = $document->getLatestContent()) {
|
||||
$status = $latestContent->getStatus();
|
||||
if ($document->getAccessMode($this->user) >= M_READ && $status["status"]==S_RELEASED) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
} /* }}} */
|
||||
|
||||
/**
|
||||
* Check if a review maybe edited
|
||||
*
|
||||
* A review may only be updated by the user who originaly addedd the
|
||||
* review and if it is allowed in the settings
|
||||
*/
|
||||
function mayUpdateReceipt($document, $updateUser) { /* {{{ */
|
||||
if($document->isType('document')) {
|
||||
if($this->settings->_enableUpdateReceipt && ($updateUser == $this->user) && $document->getAccessMode($this->user) >= M_READ && !$document->hasExpired()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
} /* }}} */
|
||||
|
||||
/**
|
||||
* Check if document content may be revised
|
||||
*
|
||||
* Revising a document content is only allowed if the document was not
|
||||
* obsoleted. There may be other requirements which are not taken into
|
||||
* account here.
|
||||
*/
|
||||
function mayRevise($document) { /* {{{ */
|
||||
if($document->isType('document')) {
|
||||
if($latestContent = $document->getLatestContent()) {
|
||||
$status = $latestContent->getStatus();
|
||||
if ($document->getAccessMode($this->user) >= M_READ && $status["status"]!=S_OBSOLETE) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
} /* }}} */
|
||||
|
||||
/**
|
||||
* Check if document content may be checked in
|
||||
*
|
||||
*
|
||||
*/
|
||||
function mayCheckIn($document) { /* {{{ */
|
||||
if($document->isType('document')) {
|
||||
$checkoutinfo = $document->getCheckOutInfo();
|
||||
if(!$checkoutinfo)
|
||||
return false;
|
||||
$info = $checkoutinfo[0];
|
||||
if($this->user->getID() == $info['userID'] || $document->getAccessMode($this->user) == M_ALL) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
@ -448,11 +564,44 @@ class SeedDMS_AccessOperation {
|
|||
return false;
|
||||
} /* }}} */
|
||||
|
||||
protected function check_controller_legacy_access($controller, $get=array()) { /* {{{ */
|
||||
if($this->user->isAdmin())
|
||||
return true;
|
||||
|
||||
if(is_string($controller)) {
|
||||
$scripts = array($controller);
|
||||
} elseif(is_array($controller)) {
|
||||
$scripts = $controller;
|
||||
} elseif(is_subclass_of($controller, 'SeedDMS_Controller_Common')) {
|
||||
$scripts = array($controller->getParam('class'));
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
|
||||
if($this->user->isGuest()) {
|
||||
$user_allowed = $this->legacy_access['guest'];
|
||||
} else {
|
||||
$user_allowed = $this->legacy_access['user'];
|
||||
}
|
||||
|
||||
if(array_intersect($scripts, $user_allowed))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
} /* }}} */
|
||||
|
||||
/**
|
||||
* Check for access permission on view
|
||||
*
|
||||
* This function will always return true because it was added to smooth
|
||||
* migration from 5.1.x to 6.0.x
|
||||
* If the parameter $view is an array then each element is considered the
|
||||
* name of a view and true will be returned if one of them is accessible.
|
||||
* Whether access is allowed also depends on the currently logged in user
|
||||
* stored in the view object. If the user is an admin the access
|
||||
* on a view must be explicitly disallowed. For regular users the access
|
||||
* must be explicitly allowed.
|
||||
*
|
||||
* If advanced access control is turn off, this function will always return
|
||||
* true for admins and false for other users.
|
||||
*
|
||||
* @param mixed $view Instanz of view, name of view or array of view names
|
||||
* @param string $get query parameters possible containing the element 'action'
|
||||
|
|
@ -460,20 +609,79 @@ class SeedDMS_AccessOperation {
|
|||
* no specific access right is set, otherwise false
|
||||
*/
|
||||
function check_view_access($view, $get=array()) { /* {{{ */
|
||||
return $this->check_view_legacy_access($view, $get);
|
||||
if(!$this->settings->_advancedAcl) {
|
||||
return $this->check_view_legacy_access($view, $get);
|
||||
}
|
||||
if(is_string($view)) {
|
||||
$scripts = array($view);
|
||||
} elseif(is_array($view)) {
|
||||
$scripts = $view;
|
||||
} elseif(is_subclass_of($view, 'SeedDMS_View_Common')) {
|
||||
$scripts = array($view->getParam('class'));
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
$scope = 'Views';
|
||||
$action = (isset($get['action']) && $get['action']) ? $get['action'] : 'show';
|
||||
$acl = new SeedDMS_Acl($this->dms);
|
||||
if(!$this->_aro)
|
||||
$this->_aro = SeedDMS_Aro::getInstance($this->user->getRole(), $this->dms);
|
||||
foreach($scripts as $script) {
|
||||
$aco = SeedDMS_Aco::getInstance($scope.'/'.$script.'/'.$action, $this->dms);
|
||||
$ll = $acl->check($this->_aro, $aco);
|
||||
if($ll === 1 && !$this->user->isAdmin() || $ll !== -1 && $this->user->isAdmin())
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
} /* }}} */
|
||||
|
||||
/**
|
||||
* Check for access permission on controller
|
||||
*
|
||||
* This function will always return true because it was added to smooth
|
||||
* migration from 5.1.x to 6.0.x
|
||||
* If the parameter $controller is an array then each element is considered the
|
||||
* name of a controller and true will be returned if one is accesible.
|
||||
* If advanced access controll is turn off, this function will return false
|
||||
* for guest users and true otherwise.
|
||||
*
|
||||
* @param mixed $controller Instanz of controller, name of controller or array of controller names
|
||||
* @param string $get query parameters
|
||||
* @return boolean true if access is allowed otherwise false
|
||||
*/
|
||||
function check_controller_access($controller, $get=array()) { /* {{{ */
|
||||
return true;
|
||||
if(!$this->settings->_advancedAcl) {
|
||||
return $this->check_controller_legacy_access($controller, $get);
|
||||
/*
|
||||
if($this->user->isGuest())
|
||||
return false;
|
||||
elseif($this->user->isAdmin())
|
||||
return true;
|
||||
else {
|
||||
if($controller == 'AddDocument' && isset($get['action']) && $get['action'] == 'setOwner')
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
*/
|
||||
}
|
||||
if(is_string($controller)) {
|
||||
$scripts = array($controller);
|
||||
} elseif(is_array($controller)) {
|
||||
$scripts = $controller;
|
||||
} elseif(is_subclass_of($controller, 'SeedDMS_Controller_Common')) {
|
||||
$scripts = array($controller->getParam('class'));
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
$scope = 'Controllers';
|
||||
$action = (isset($get['action']) && $get['action']) ? $get['action'] : 'run';
|
||||
$acl = new SeedDMS_Acl($this->dms);
|
||||
if(!$this->_aro)
|
||||
$this->_aro = SeedDMS_Aro::getInstance($this->user->getRole(), $this->dms);
|
||||
foreach($scripts as $script) {
|
||||
$aco = SeedDMS_Aco::getInstance($scope.'/'.$script.'/'.$action, $this->dms);
|
||||
$ll = $acl->check($this->_aro, $aco);
|
||||
if($ll === 1 && !$this->user->isAdmin() || $ll !== -1 && $this->user->isAdmin())
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
} /* }}} */
|
||||
}
|
||||
|
|
|
|||
390
inc/inc.ClassAcl.php
Normal file
390
inc/inc.ClassAcl.php
Normal file
|
|
@ -0,0 +1,390 @@
|
|||
<?php
|
||||
/**
|
||||
* Implementation of a access control list.
|
||||
*
|
||||
* SeedDMS uses access control list for setting permission,
|
||||
* on various operations.
|
||||
*
|
||||
* @category DMS
|
||||
* @package SeedDMS
|
||||
* @license GPL 2
|
||||
* @version @version@
|
||||
* @author Uwe Steinmann <uwe@steinmann.cx>
|
||||
* @copyright 2016 Uwe Steinmann
|
||||
* @version Release: @package_version@
|
||||
*/
|
||||
|
||||
/**
|
||||
* Class to represent an access request object
|
||||
*
|
||||
* This class provides a model for access request objects.
|
||||
*
|
||||
* @category DMS
|
||||
* @package SeedDMS
|
||||
* @author Uwe Steinmann <uwe@steinmann.cx>
|
||||
* @copyright 2016 Uwe Steinmann
|
||||
* @version Release: @package_version@
|
||||
*/
|
||||
class SeedDMS_Acl { /* {{{ */
|
||||
/**
|
||||
* @var object $dms reference to dms object.
|
||||
* @access public
|
||||
*/
|
||||
public $_dms;
|
||||
|
||||
/**
|
||||
* Create a new instance of an acl
|
||||
*
|
||||
* @param object $dms object of dms
|
||||
* @return object instance of SeedDMS_Acl
|
||||
*/
|
||||
public function __construct($dms) { /* {{{ */
|
||||
$this->_dms = $dms;
|
||||
} /* }}} */
|
||||
|
||||
/**
|
||||
* Check if Aro has access on Aco
|
||||
*
|
||||
* @param object $aro access request object
|
||||
* @param object $aco access control object
|
||||
* @return integer/boolean -1 if access is explictly denied, 1 if access
|
||||
* is explictly allow, 0 if no access restrictions exists, false if
|
||||
* an error occured.
|
||||
*/
|
||||
public function check($aro, $aco) { /* {{{ */
|
||||
$db = $this->_dms->getDB();
|
||||
|
||||
while($aco) {
|
||||
$acoid = $aco->getID();
|
||||
$queryStr = "SELECT * FROM `tblArosAcos` WHERE `aro`=".$aro->getID()." AND `aco`=".$acoid;
|
||||
$resArr = $db->getResultArray($queryStr);
|
||||
if (is_bool($resArr) && $resArr === false)
|
||||
return false;
|
||||
if (count($resArr) == 1)
|
||||
return((int) $resArr[0]['read']);
|
||||
|
||||
$aco = $aco->getParent();
|
||||
}
|
||||
|
||||
return 0;
|
||||
} /* }}} */
|
||||
|
||||
public function toggle($aro, $aco) { /* {{{ */
|
||||
$db = $this->_dms->getDB();
|
||||
$queryStr = "SELECT * FROM `tblArosAcos` WHERE `aro`=".$aro->getID()." AND `aco`=".$aco->getID();
|
||||
$resArr = $db->getResultArray($queryStr);
|
||||
if (is_bool($resArr) && $resArr === false)
|
||||
return false;
|
||||
if (count($resArr) != 1)
|
||||
return false;
|
||||
$resArr = $resArr[0];
|
||||
|
||||
$newperm = $resArr['read'] == 1 ? -1 : 1;
|
||||
$queryStr = "UPDATE `tblArosAcos` SET `read`=".$newperm." WHERE `aro`=".$aro->getID()." AND `aco`=".$aco->getID();
|
||||
if (!$db->getResult($queryStr))
|
||||
return false;
|
||||
return true;
|
||||
|
||||
} /* }}} */
|
||||
|
||||
public function add($aro, $aco, $perm=-1) { /* {{{ */
|
||||
$db = $this->_dms->getDB();
|
||||
$queryStr = "SELECT * FROM `tblArosAcos` WHERE `aro`=".$aro->getID()." AND `aco`=".$aco->getID();
|
||||
$resArr = $db->getResultArray($queryStr);
|
||||
if (is_bool($resArr) && $resArr === false)
|
||||
return false;
|
||||
if (count($resArr) == 1) {
|
||||
$resArr = $resArr[0];
|
||||
|
||||
$newperm = $resArr['read'] == 1 ? -1 : 1;
|
||||
$queryStr = "UPDATE `tblArosAcos` SET `read`=".$newperm." WHERE `aro`=".$aro->getID()." AND `aco`=".$aco->getID();
|
||||
if (!$db->getResult($queryStr))
|
||||
return false;
|
||||
} else {
|
||||
$queryStr = "INSERT INTO `tblArosAcos` (`aro`, `aco`, `read`) VALUES (".$aro->getID().", ".$aco->getID().", ".$perm.")";
|
||||
if (!$db->getResult($queryStr))
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
|
||||
} /* }}} */
|
||||
|
||||
public function remove($aro, $aco) { /* {{{ */
|
||||
$db = $this->_dms->getDB();
|
||||
$queryStr = "DELETE FROM `tblArosAcos` WHERE `aro`=".$aro->getID()." AND `aco`=".$aco->getID();
|
||||
if (!$db->getResult($queryStr))
|
||||
return false;
|
||||
return true;
|
||||
} /* }}} */
|
||||
} /* }}} */
|
||||
|
||||
/**
|
||||
* Class to represent an access request/controll object
|
||||
*
|
||||
* This class provides a model for access request/controll objects.
|
||||
*
|
||||
* @category DMS
|
||||
* @package SeedDMS
|
||||
* @author Uwe Steinmann <uwe@steinmann.cx>
|
||||
* @copyright 2016 Uwe Steinmann
|
||||
* @version Release: @package_version@
|
||||
*/
|
||||
class SeedDMS_AroAco { /* {{{ */
|
||||
/**
|
||||
* @var object $dms reference to dms object.
|
||||
* @access protected
|
||||
*/
|
||||
public $_dms;
|
||||
|
||||
/**
|
||||
* @var integer id of access request object
|
||||
*/
|
||||
protected $_id;
|
||||
|
||||
/**
|
||||
* @var integer id of parent of access request object
|
||||
*/
|
||||
protected $_parent;
|
||||
|
||||
/**
|
||||
* @var string alias of access request object
|
||||
*/
|
||||
protected $_alias;
|
||||
|
||||
/**
|
||||
* @var object object of access request object
|
||||
*/
|
||||
protected $_object;
|
||||
|
||||
/**
|
||||
* Create a new instance of an aro
|
||||
*
|
||||
* @param object $dms object of dms
|
||||
* @return object instance of SeedDMS_Aco
|
||||
*/
|
||||
function __construct($dms, $id, $parent, $object, $alias) { /* {{{ */
|
||||
$this->_dms = $dms;
|
||||
$this->_id = $id;
|
||||
$this->_parent = $parent;
|
||||
$this->_object = $object;
|
||||
$this->_alias = $alias;
|
||||
} /* }}} */
|
||||
|
||||
public function setDMS($dms) { /* {{{ */
|
||||
$this->_dms = $dms;
|
||||
} /* }}} */
|
||||
|
||||
public function getDMS() { /* {{{ */
|
||||
return($this->_dms);
|
||||
} /* }}} */
|
||||
|
||||
public function getID() { /* {{{ */
|
||||
return $this->_id;
|
||||
} /* }}} */
|
||||
|
||||
public function getAlias() { /* {{{ */
|
||||
return $this->_alias;
|
||||
} /* }}} */
|
||||
|
||||
public function getObject() { /* {{{ */
|
||||
return $this->_object;
|
||||
} /* }}} */
|
||||
} /* }}} */
|
||||
|
||||
/**
|
||||
* Class to represent an access request object
|
||||
*
|
||||
* This class provides a model for access request objects.
|
||||
*
|
||||
* @category DMS
|
||||
* @package SeedDMS
|
||||
* @author Uwe Steinmann <uwe@steinmann.cx>
|
||||
* @copyright 2016 Uwe Steinmann
|
||||
* @version Release: @package_version@
|
||||
*/
|
||||
class SeedDMS_Aro extends SeedDMS_AroAco { /* {{{ */
|
||||
|
||||
/**
|
||||
* Create a new instance of an aro
|
||||
*
|
||||
* @param object $dms object to access the underlying database
|
||||
* @return object instance of SeedDMS_Aro
|
||||
*/
|
||||
public static function getInstance($id, $dms) { /* {{{ */
|
||||
$db = $dms->getDB();
|
||||
if(is_int($id)) {
|
||||
$queryStr = "SELECT * FROM `tblAros` WHERE `id` = " . (int) $id;
|
||||
$resArr = $db->getResultArray($queryStr);
|
||||
if (is_bool($resArr) && $resArr === false)
|
||||
return null;
|
||||
if (count($resArr) != 1)
|
||||
return null;
|
||||
$resArr = $resArr[0];
|
||||
} elseif(is_object($id)) {
|
||||
if($dms->getClassname('role') == get_class($id)) {
|
||||
$model = 'Role';
|
||||
$queryStr = "SELECT * FROM `tblAros` WHERE `model`=".$db->qstr($model)." AND `foreignid`=".$id->getID();
|
||||
$resArr = $db->getResultArray($queryStr);
|
||||
if (is_bool($resArr) && $resArr === false)
|
||||
return null;
|
||||
if (count($resArr) == 0) {
|
||||
$queryStr = "INSERT INTO `tblAros` (`parent`, `model`, `foreignid`) VALUES (0, ".$db->qstr($model).", ".$id->getID().")";
|
||||
if (!$db->getResult($queryStr))
|
||||
return null;
|
||||
$id = $db->getInsertID();
|
||||
$queryStr = "SELECT * FROM `tblAros` WHERE `id` = " . $id;
|
||||
$resArr = $db->getResultArray($queryStr);
|
||||
}
|
||||
$resArr = $resArr[0];
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
if($resArr['model'] == 'Role') {
|
||||
$classname = $dms->getClassname('role');
|
||||
$object = $classname::getInstance($resArr['foreignid'], $dms);
|
||||
} else {
|
||||
$object = null;
|
||||
}
|
||||
|
||||
$aro = new SeedDMS_Aro($dms, $resArr["id"], $resArr['parent'], $object, $resArr['alias']);
|
||||
$aro->setDMS($dms);
|
||||
return $aro;
|
||||
} /* }}} */
|
||||
|
||||
} /* }}} */
|
||||
|
||||
/**
|
||||
* Class to represent an access control object
|
||||
*
|
||||
* This class provides a model for access control objects.
|
||||
*
|
||||
* @category DMS
|
||||
* @package SeedDMS
|
||||
* @author Uwe Steinmann <uwe@steinmann.cx>
|
||||
* @copyright 2016 Uwe Steinmann
|
||||
* @version Release: @package_version@
|
||||
*/
|
||||
class SeedDMS_Aco extends SeedDMS_AroAco{ /* {{{ */
|
||||
|
||||
/**
|
||||
* Create a new instance of an aco
|
||||
*
|
||||
* @param object $dms object to access the underlying database
|
||||
* @return object instance of SeedDMS_Aco
|
||||
*/
|
||||
public static function getInstance($id, $dms) { /* {{{ */
|
||||
$db = $dms->getDB();
|
||||
if(is_int($id)) {
|
||||
$queryStr = "SELECT * FROM `tblAcos` WHERE `id` = " . (int) $id;
|
||||
$resArr = $db->getResultArray($queryStr);
|
||||
if (is_bool($resArr) && $resArr === false)
|
||||
return null;
|
||||
if (count($resArr) == 0) {
|
||||
return null;
|
||||
}
|
||||
$resArr = $resArr[0];
|
||||
} elseif(is_string($id)) {
|
||||
$tmp = explode('/', $id);
|
||||
$parentid = 0;
|
||||
foreach($tmp as $part) {
|
||||
$queryStr = "SELECT * FROM `tblAcos` WHERE `alias` = " . $db->qstr($part);
|
||||
// if($parentid)
|
||||
$queryStr .= " AND parent=".$parentid;
|
||||
$resArr = $db->getResultArray($queryStr);
|
||||
if (is_bool($resArr) && $resArr === false)
|
||||
return null;
|
||||
if (count($resArr) == 0) {
|
||||
$queryStr = "INSERT INTO `tblAcos` (`parent`, `alias`, `model`) VALUES (".$parentid.",".$db->qstr($part).", '')";
|
||||
if (!$db->getResult($queryStr))
|
||||
return null;
|
||||
$id = $db->getInsertID();
|
||||
$queryStr = "SELECT * FROM `tblAcos` WHERE `id` = " . $id;
|
||||
$resArr = $db->getResultArray($queryStr);
|
||||
}
|
||||
$parentid = (int) $resArr[0]['id'];
|
||||
}
|
||||
$resArr = $resArr[0];
|
||||
}
|
||||
|
||||
if($resArr['model'] == 'Document') {
|
||||
$classname = $dms->getClassname('document');
|
||||
$object = $classname::getInstance($resArr['foreignid'], $dms);
|
||||
} elseif($resArr['model'] == 'Folder') {
|
||||
$classname = $dms->getClassname('focument');
|
||||
$object = $classname::getInstance($resArr['foreignid'], $dms);
|
||||
} else {
|
||||
$object = null;
|
||||
}
|
||||
|
||||
$aco = new SeedDMS_Aco($dms, $resArr["id"], $resArr['parent'], $object, $resArr['alias']);
|
||||
$aco->setDMS($dms);
|
||||
return $aco;
|
||||
} /* }}} */
|
||||
|
||||
public function getChildren() { /* {{{ */
|
||||
$dms = $this->getDMS();
|
||||
$db = $dms->getDB();
|
||||
$queryStr = "SELECT * FROM `tblAcos` WHERE `parent` = ".$this->_id." ORDER BY `alias`";
|
||||
$resArr = $db->getResultArray($queryStr);
|
||||
if (is_bool($resArr) && $resArr === false)
|
||||
return null;
|
||||
if (count($resArr) == 0)
|
||||
return null;
|
||||
|
||||
$acos = array();
|
||||
foreach($resArr as $row) {
|
||||
$aco = new SeedDMS_Aco($dms, $row["id"], $row['parent'], null, $row['alias']);
|
||||
$aco->setDMS($dms);
|
||||
$acos[] = $aco;
|
||||
}
|
||||
return $acos;
|
||||
} /* }}} */
|
||||
|
||||
public function getPermission($aro) { /* {{{ */
|
||||
if(!$aro)
|
||||
return 0;
|
||||
$dms = $this->getDMS();
|
||||
$db = $dms->getDB();
|
||||
$queryStr = "SELECT * FROM `tblArosAcos` WHERE `aro`=".$aro->getID()." AND `aco`=".$this->_id;
|
||||
$resArr = $db->getResultArray($queryStr);
|
||||
if (is_bool($resArr) && $resArr === false)
|
||||
return false;
|
||||
if (count($resArr) != 1)
|
||||
return 0;
|
||||
return (int) $resArr[0]['read'];
|
||||
} /* }}} */
|
||||
|
||||
public static function getRoot($dms) { /* {{{ */
|
||||
$db = $dms->getDB();
|
||||
$queryStr = "SELECT * FROM `tblAcos` WHERE `parent` = 0 ORDER BY `alias`";
|
||||
$resArr = $db->getResultArray($queryStr);
|
||||
if (is_bool($resArr) && $resArr === false)
|
||||
return null;
|
||||
|
||||
$acos = array();
|
||||
foreach($resArr as $row) {
|
||||
$aco = new SeedDMS_Aco($dms, $row["id"], $row['parent'], null, $row['alias']);
|
||||
$aco->setDMS($dms);
|
||||
$acos[] = $aco;
|
||||
}
|
||||
return $acos;
|
||||
} /* }}} */
|
||||
|
||||
public function getParent() { /* {{{ */
|
||||
$dms = $this->getDMS();
|
||||
$db = $dms->getDB();
|
||||
$queryStr = "SELECT * FROM `tblAcos` WHERE `id` = ".$this->_parent;
|
||||
$resArr = $db->getResultArray($queryStr);
|
||||
if (is_bool($resArr) && $resArr === false)
|
||||
return null;
|
||||
if (count($resArr) != 1)
|
||||
return null;
|
||||
|
||||
$row = $resArr[0];
|
||||
$aco = new SeedDMS_Aco($dms, $row["id"], $row['parent'], null, $row['alias']);
|
||||
$aco->setDMS($dms);
|
||||
return $aco;
|
||||
} /* }}} */
|
||||
} /* }}} */
|
||||
|
|
@ -30,18 +30,13 @@
|
|||
* @link https://www.seeddms.org Main Site
|
||||
*/
|
||||
|
||||
use Seeddms\Seeddms\Session;
|
||||
|
||||
/* Middleware for authentication based on session */
|
||||
class SeedDMS_Auth_Middleware_Session { /* {{{ */
|
||||
|
||||
private $container;
|
||||
|
||||
private $responsefactory;
|
||||
|
||||
public function __construct($container, $responsefactory) {
|
||||
public function __construct($container) {
|
||||
$this->container = $container;
|
||||
$this->responsefactory = $responsefactory;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -68,9 +63,9 @@ class SeedDMS_Auth_Middleware_Session { /* {{{ */
|
|||
return $response;
|
||||
}
|
||||
|
||||
$logger->log("Invoke AuthSessionMiddleware for method " . $request->getMethod() . " on '" . $request->getUri()->getPath() . "'", PEAR_LOG_INFO);
|
||||
// require_once("inc/inc.ClassSession.php");
|
||||
$session = new Session($dms->getDb());
|
||||
$logger->log("Invoke middleware for method " . $request->getMethod() . " on '" . $request->getUri()->getPath() . "'", PEAR_LOG_INFO);
|
||||
require_once("inc/inc.ClassSession.php");
|
||||
$session = new SeedDMS_Session($dms->getDb());
|
||||
if (isset($_COOKIE["mydms_session"])) {
|
||||
$dms_session = $_COOKIE["mydms_session"];
|
||||
$logger->log("Session key: " . $dms_session, PEAR_LOG_DEBUG);
|
||||
|
|
@ -78,7 +73,6 @@ class SeedDMS_Auth_Middleware_Session { /* {{{ */
|
|||
/* Delete Cookie */
|
||||
setcookie("mydms_session", $dms_session, time() - 3600, $settings->_httpRoot);
|
||||
$logger->log("Session for id '" . $dms_session . "' has gone", PEAR_LOG_ERR);
|
||||
$response = $this->responsefactory->createResponse();
|
||||
return $response->withStatus(403);
|
||||
}
|
||||
|
||||
|
|
@ -89,7 +83,6 @@ class SeedDMS_Auth_Middleware_Session { /* {{{ */
|
|||
setcookie("mydms_session", $dms_session, time() - 3600, $settings->_httpRoot);
|
||||
if ($settings->_enableGuestLogin) {
|
||||
if (!($userobj = $dms->getUser($settings->_guestID))) {
|
||||
$response = $this->responsefactory->createResponse();
|
||||
return $response->withStatus(403);
|
||||
}
|
||||
} else {
|
||||
|
|
@ -99,14 +92,12 @@ class SeedDMS_Auth_Middleware_Session { /* {{{ */
|
|||
if ($userobj->isAdmin()) {
|
||||
if ($resArr["su"]) {
|
||||
if (!($userobj = $dms->getUser($resArr["su"]))) {
|
||||
$response = $this->responsefactory->createResponse();
|
||||
return $response->withStatus(403);
|
||||
}
|
||||
}
|
||||
}
|
||||
$dms->setUser($userobj);
|
||||
} else {
|
||||
$response = $this->responsefactory->createResponse();
|
||||
return $response->withStatus(403);
|
||||
}
|
||||
$this->container->set('userobj', $userobj);
|
||||
|
|
@ -115,174 +106,3 @@ class SeedDMS_Auth_Middleware_Session { /* {{{ */
|
|||
return $response;
|
||||
}
|
||||
} /* }}} */
|
||||
|
||||
/**
|
||||
* Middleware for authentication based on basic authentication
|
||||
*
|
||||
**/
|
||||
class SeedDMS_Auth_Middleware_Basic { /* {{{ */
|
||||
|
||||
private $container;
|
||||
|
||||
private $responsefactory;
|
||||
|
||||
public function __construct($container, $responsefactory) {
|
||||
$this->container = $container;
|
||||
$this->responsefactory = $responsefactory;
|
||||
}
|
||||
|
||||
/**
|
||||
* Basic authentication middleware invokable class
|
||||
*
|
||||
* @param \Psr\Http\Message\ServerRequestInterface $request PSR7 request
|
||||
* @param \Psr\Http\Message\ResponseInterface $response PSR7 response
|
||||
* @param callable $next Next middleware
|
||||
*
|
||||
* @return \Psr\Http\Message\ResponseInterface
|
||||
*/
|
||||
public function __invoke($request, $handler) {
|
||||
$dms = $this->container->get('dms');
|
||||
$settings = $this->container->get('config');
|
||||
$logger = $this->container->get('logger');
|
||||
$userobj = null;
|
||||
if ($this->container->has('userobj')) {
|
||||
$userobj = $this->container->get('userobj');
|
||||
}
|
||||
|
||||
if ($userobj) {
|
||||
$response = $handler->handle($request);
|
||||
return $response;
|
||||
}
|
||||
|
||||
$logger->log("Invoke AuthBasicMiddleware for method " . $request->getMethod() . " on '" . $request->getUri()->getPath() . "'", PEAR_LOG_INFO);
|
||||
$environment = $request->getServerParams();
|
||||
if(!empty($environment['HTTP_AUTHORIZATION'])) {
|
||||
$tmp = explode(' ', $environment['HTTP_AUTHORIZATION'], 2);
|
||||
switch($tmp[0]) {
|
||||
case 'Basic':
|
||||
$logger->log("Basic authentication with ".$tmp[0]."=".$tmp[1], PEAR_LOG_INFO);
|
||||
$authenticator = $this->container->get('authenticator');
|
||||
$kk = explode(':', base64_decode($tmp[1]));
|
||||
$userobj = $authenticator->authenticate($kk[0], $kk[1]);
|
||||
if(!$userobj) {
|
||||
$logger->log("Login with basic authentication for '".$kk[0]."' failed", PEAR_LOG_ERR);
|
||||
$response = $this->responsefactory->createResponse();
|
||||
return $response->withStatus(403);
|
||||
}
|
||||
$dms->setUser($userobj);
|
||||
if($this->container instanceof \Slim\Container)
|
||||
$this->container['userobj'] = $userobj;
|
||||
else
|
||||
$this->container->set('userobj', $userobj);
|
||||
$logger->log("Login with basic authentication as '".$userobj->getLogin()."' successful", PEAR_LOG_INFO);
|
||||
break;
|
||||
}
|
||||
}
|
||||
$this->container->set('userobj', $userobj);
|
||||
|
||||
if(!$userobj)
|
||||
$logger->log("Not yet authenticated. Pass on to next middleware", PEAR_LOG_INFO);
|
||||
else
|
||||
$logger->log("Authenticated as ".(is_object($userobj) ? $userobj->getLogin() : "annon").". Pass on to next middleware", PEAR_LOG_INFO);
|
||||
|
||||
/* Always pass on to the next middleware. If that middleware does
|
||||
* authentication, then it should first check if 'userobj' in the container
|
||||
* is already set. The authentication shipped with seeddms restapi does that
|
||||
* and skips its own authentication, if userobj already exists.
|
||||
*/
|
||||
$response = $handler->handle($request);
|
||||
return $response;
|
||||
}
|
||||
} /* }}} */
|
||||
|
||||
/**
|
||||
* Middleware for authentication based on token
|
||||
*
|
||||
**/
|
||||
class SeedDMS_Auth_Middleware_Token { /* {{{ */
|
||||
|
||||
private $container;
|
||||
|
||||
private $responsefactory;
|
||||
|
||||
public function __construct($container, $responsefactory) {
|
||||
$this->container = $container;
|
||||
$this->responsefactory = $responsefactory;
|
||||
}
|
||||
|
||||
/**
|
||||
* Basic authentication middleware invokable class
|
||||
*
|
||||
* @param \Psr\Http\Message\ServerRequestInterface $request PSR7 request
|
||||
* @param \Psr\Http\Message\ResponseInterface $response PSR7 response
|
||||
* @param callable $next Next middleware
|
||||
*
|
||||
* @return \Psr\Http\Message\ResponseInterface
|
||||
*/
|
||||
public function __invoke($request, $handler) {
|
||||
$dms = $this->container->get('dms');
|
||||
$settings = $this->container->get('config');
|
||||
$logger = $this->container->get('logger');
|
||||
$userobj = null;
|
||||
if ($this->container->has('userobj')) {
|
||||
$userobj = $this->container->get('userobj');
|
||||
}
|
||||
|
||||
if ($userobj) {
|
||||
$response = $handler->handle($request);
|
||||
return $response;
|
||||
}
|
||||
|
||||
$logger->log("Invoke AuthTokenMiddleware for method " . $request->getMethod() . " on '" . $request->getUri()->getPath() . "'", PEAR_LOG_INFO);
|
||||
$environment = $request->getServerParams();
|
||||
/* Do not even try to authenticate if HTTP_AUTHORIZATION is empty, contains
|
||||
* a ' ' (in case of Basic authentication), the api key is not set, the api
|
||||
* user is not set.
|
||||
*/
|
||||
if (!empty($environment['HTTP_AUTHORIZATION']) && strstr($environment['HTTP_AUTHORIZATION'], ' ') === false && !empty($settings->_apiKey) && !empty($settings->_apiUserId)) {
|
||||
$logger->log("Authorization key: ".$environment['HTTP_AUTHORIZATION'], PEAR_LOG_DEBUG);
|
||||
if($settings->_apiKey == $environment['HTTP_AUTHORIZATION']) {
|
||||
if(!($userobj = $dms->getUser($settings->_apiUserId))) {
|
||||
$response = $this->responsefactory->createResponse();
|
||||
$response = $response->withHeader('Content-Type', 'application/json');
|
||||
$response = $response->withStatus(403);
|
||||
$response->getBody()->write(
|
||||
(string)json_encode(
|
||||
['success'=>false, 'message'=>'Invalid user associated with api key', 'data'=>''],
|
||||
JSON_UNESCAPED_SLASHES | JSON_PARTIAL_OUTPUT_ON_ERROR
|
||||
)
|
||||
);
|
||||
return $response;
|
||||
}
|
||||
} else {
|
||||
$response = $this->responsefactory->createResponse();
|
||||
$response = $response->withHeader('Content-Type', 'application/json');
|
||||
$response = $response->withStatus(403);
|
||||
$response->getBody()->write(
|
||||
(string)json_encode(
|
||||
['success'=>false, 'message'=>'Wrong api key', 'data'=>''],
|
||||
JSON_UNESCAPED_SLASHES | JSON_PARTIAL_OUTPUT_ON_ERROR
|
||||
)
|
||||
);
|
||||
return $response;
|
||||
}
|
||||
$logger->log("Login with apikey as '".$userobj->getLogin()."' successful", PEAR_LOG_INFO);
|
||||
}
|
||||
|
||||
$this->container->set('userobj', $userobj);
|
||||
|
||||
if(!$userobj)
|
||||
$logger->log("Not yet authenticated. Pass on to next middleware", PEAR_LOG_INFO);
|
||||
else
|
||||
$logger->log("Authenticated as ".(is_object($userobj) ? $userobj->getLogin() : "annon").". Pass on to next middleware", PEAR_LOG_INFO);
|
||||
|
||||
/* Always pass on to the next middleware. If that middleware does
|
||||
* authentication, then it should first check if 'userobj' in the container
|
||||
* is already set. The authentication shipped with seeddms restapi does that
|
||||
* and skips its own authentication, if userobj already exists.
|
||||
*/
|
||||
$response = $handler->handle($request);
|
||||
return $response;
|
||||
}
|
||||
} /* }}} */
|
||||
|
||||
|
|
|
|||
|
|
@ -30,19 +30,14 @@ class Controller {
|
|||
* @return object an object of a class implementing the view
|
||||
*/
|
||||
static function factory($class, $params=array()) { /* {{{ */
|
||||
foreach(['settings', 'session', 'extmgr', 'request', 'logger', 'notifier', 'fulltextservice', 'translator'] as $vn) {
|
||||
if(isset($params[$vn]))
|
||||
${$vn} = $params[$vn];
|
||||
else
|
||||
${$vn} = $GLOBALS[$vn] ?? null;
|
||||
}
|
||||
global $settings, $session, $extMgr, $request, $logger, $notifier;
|
||||
if(!$class) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$classname = "SeedDMS_Controller_".$class;
|
||||
$filename = '';
|
||||
foreach($extmgr->getExtensionConfiguration() as $extname=>$extconf) {
|
||||
foreach($extMgr->getExtensionConfiguration() as $extname=>$extconf) {
|
||||
$filename = $settings->_rootDir.'ext/'.$extname.'/controllers/class.'.$class.".php";
|
||||
if(file_exists($filename)) {
|
||||
break;
|
||||
|
|
@ -57,6 +52,7 @@ class Controller {
|
|||
require_once($filename);
|
||||
$controller = new $classname($params);
|
||||
/* Set some configuration parameters */
|
||||
$controller->setParam('class', $class);
|
||||
$controller->setParam('postVars', $_POST);
|
||||
$controller->setParam('getVars', $_GET);
|
||||
$controller->setParam('requestVars', $_REQUEST);
|
||||
|
|
@ -65,8 +61,6 @@ class Controller {
|
|||
$controller->setParam('settings', $settings);
|
||||
$controller->setParam('logger', $logger);
|
||||
$controller->setParam('notifier', $notifier);
|
||||
$controller->setParam('fulltextservice', $fulltextservice);
|
||||
$controller->setParam('translator', $translator);
|
||||
return $controller;
|
||||
}
|
||||
return null;
|
||||
|
|
|
|||
|
|
@ -285,7 +285,7 @@ class SeedDMS_Controller_Common {
|
|||
if(is_string($tmpret)) {
|
||||
$ret = ($ret === null) ? $tmpret : (is_string($ret) ? $ret.$tmpret : array_merge($ret, array($tmpret)));
|
||||
} elseif(is_array($tmpret)) { // || is_object($tmpret)) {
|
||||
$ret = ($ret === null) ? $tmpret : (is_string($ret) ? (array($ret) + $tmpret) : ($ret + $tmpret));
|
||||
$ret = ($ret === null) ? $tmpret : (is_string($ret) ? array_merge(array($ret), $tmpret) : array_merge($ret, $tmpret));
|
||||
} else
|
||||
$ret = $tmpret;
|
||||
}
|
||||
|
|
@ -317,4 +317,26 @@ class SeedDMS_Controller_Common {
|
|||
}
|
||||
return false;
|
||||
} /* }}} */
|
||||
|
||||
/**
|
||||
* Check if the access on the contoller with given name or the current
|
||||
* controller itself may be accessed.
|
||||
*
|
||||
* The function requires the parameter 'accessobject' to be available in the
|
||||
* controller, because it calls SeedDMS_AccessOperation::check_controller_access()
|
||||
* to check access rights. If the the optional $name is not set the
|
||||
* current controller is used.
|
||||
*
|
||||
* @param string|array $name name of controller or list of controller names
|
||||
* @return boolean true if access is allowed otherwise false
|
||||
*/
|
||||
protected function check_access($name='') { /* {{{ */
|
||||
if(!$name)
|
||||
$name = $this;
|
||||
if(!isset($this->params['accessobject']))
|
||||
return false;
|
||||
$access = $this->params['accessobject']->check_controller_access($name);
|
||||
return $access;
|
||||
} /* }}} */
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -93,18 +93,6 @@ class SeedDMS_Download_Mgr {
|
|||
*/
|
||||
protected $filenames;
|
||||
|
||||
/**
|
||||
* @var bool $includereviewers whether to include reviewers
|
||||
* @access protected
|
||||
*/
|
||||
protected $includereviewers;
|
||||
|
||||
/**
|
||||
* @var bool $includeapprovers whether to include approvers
|
||||
* @access protected
|
||||
*/
|
||||
protected $includeapprovers;
|
||||
|
||||
/**
|
||||
* @var boolean $skipdefaultcols skip default columns, will only export extracols
|
||||
* @access protected
|
||||
|
|
|
|||
|
|
@ -36,8 +36,6 @@ class SeedDMS_EmailNotify extends SeedDMS_Notify {
|
|||
*/
|
||||
protected $_dms;
|
||||
|
||||
protected $_translator;
|
||||
|
||||
protected $smtp_server;
|
||||
|
||||
protected $smtp_port;
|
||||
|
|
@ -54,9 +52,8 @@ class SeedDMS_EmailNotify extends SeedDMS_Notify {
|
|||
|
||||
protected $debug;
|
||||
|
||||
function __construct($dms, $translator, $from_address='', $smtp_server='', $smtp_port='', $smtp_username='', $smtp_password='', $lazy_ssl=true, $force_from=false) { /* {{{ */
|
||||
function __construct($dms, $from_address='', $smtp_server='', $smtp_port='', $smtp_username='', $smtp_password='', $lazy_ssl=true, $force_from=false) { /* {{{ */
|
||||
$this->_dms = $dms;
|
||||
$this->_translator = $translator;
|
||||
$this->smtp_server = $smtp_server;
|
||||
$this->smtp_port = $smtp_port;
|
||||
$this->smtp_user = $smtp_username;
|
||||
|
|
@ -125,42 +122,41 @@ class SeedDMS_EmailNotify extends SeedDMS_Notify {
|
|||
$from = $this->from_address;
|
||||
}
|
||||
|
||||
|
||||
$body = '';
|
||||
if(!isset($params['__skip_header__']) || !$params['__skip_header__']) {
|
||||
if(!isset($params['__header__']))
|
||||
$body .= $this->_translator->translate("email_header", $params, null, $lang)."\r\n\r\n";
|
||||
$body .= getMLText("email_header", $params, "", $lang)."\r\n\r\n";
|
||||
elseif($params['__header__'])
|
||||
$body .= $this->_translator->translate($params['__header__'], $params, null, $lang)."\r\n\r\n";
|
||||
$body .= getMLText($params['__header__'], $params, "", $lang)."\r\n\r\n";
|
||||
}
|
||||
if(isset($params['__body__']))
|
||||
$body .= $params['__body__'];
|
||||
else
|
||||
$body .= $this->_translator->translate($messagekey, $params, null, $lang);
|
||||
$body .= getMLText($messagekey, $params, "", $lang);
|
||||
if(!isset($params['__skip_footer__']) || !$params['__skip_footer__']) {
|
||||
if(!isset($params['__footer__']))
|
||||
$body .= "\r\n\r\n".$this->_translator->translate("email_footer", $params, null, $lang);
|
||||
$body .= "\r\n\r\n".getMLText("email_footer", $params, "", $lang);
|
||||
elseif($params['__footer__'])
|
||||
$body .= "\r\n\r\n".$this->_translator->translate($params['__footer__'], $params, null, $lang);
|
||||
$body .= "\r\n\r\n".getMLText($params['__footer__'], $params, "", $lang);
|
||||
}
|
||||
|
||||
$bodyhtml = '';
|
||||
if(isset($params['__body_html__']) || $this->_translator->translate($messagekey.'_html', $params, null, $lang)) {
|
||||
if(isset($params['__body_html__']) || getMLText($messagekey.'_html', $params, "", $lang)) {
|
||||
if(!isset($params['__skip_header__']) || !$params['__skip_header__']) {
|
||||
if(!isset($params['__header_html__']))
|
||||
$bodyhtml .= $this->_translator->translate("email_header_html", $params, null, $lang)."\r\n\r\n";
|
||||
$bodyhtml .= getMLText("email_header_html", $params, "", $lang)."\r\n\r\n";
|
||||
elseif($params['__header_html__'])
|
||||
$bodyhtml .= $this->_translator->translate($params['__header_html__'], $params, null, $lang)."\r\n\r\n";
|
||||
$bodyhtml .= getMLText($params['__header_html__'], $params, "", $lang)."\r\n\r\n";
|
||||
}
|
||||
if(isset($params['__body_html__']))
|
||||
$bodyhtml .= $params['__body_html__'];
|
||||
else
|
||||
$bodyhtml .= $this->_translator->translate($messagekey.'_html', $params, null, $lang);
|
||||
$bodyhtml .= getMLText($messagekey.'_html', $params, "", $lang);
|
||||
if(!isset($params['__skip_footer__']) || !$params['__skip_footer__']) {
|
||||
if(!isset($params['__footer_html__']))
|
||||
$bodyhtml .= "\r\n\r\n".$this->_translator->translate("email_footer_html", $params, null, $lang);
|
||||
$bodyhtml .= "\r\n\r\n".getMLText("email_footer_html", $params, "", $lang);
|
||||
elseif($params['__footer_html__'])
|
||||
$bodyhtml .= "\r\n\r\n".$this->_translator->translate($params['__footer_html__'], $params, null, $lang);
|
||||
$bodyhtml .= "\r\n\r\n".getMLText($params['__footer_html__'], $params, "", $lang);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -210,7 +206,7 @@ class SeedDMS_EmailNotify extends SeedDMS_Notify {
|
|||
$headers['Return-Path'] = $returnpath;
|
||||
$headers['To'] = $to;
|
||||
$preferences = array("input-charset" => "UTF-8", "output-charset" => "UTF-8", "scheme"=>"Q");
|
||||
$encoded_subject = iconv_mime_encode("Subject", $this->_translator->translate($subject, $params, null, $lang), $preferences);
|
||||
$encoded_subject = iconv_mime_encode("Subject", getMLText($subject, $params, null, $lang), $preferences);
|
||||
$headers['Subject'] = substr($encoded_subject, strlen('Subject: '));
|
||||
$headers['Date'] = date('r', time());
|
||||
$headers['MIME-Version'] = "1.0";
|
||||
|
|
@ -243,7 +239,7 @@ class SeedDMS_EmailNotify extends SeedDMS_Notify {
|
|||
if (isset($GLOBALS['SEEDDMS_HOOKS']['mailqueue'])) {
|
||||
foreach($GLOBALS['SEEDDMS_HOOKS']['mailqueue'] as $queueService) {
|
||||
if(method_exists($queueService, 'queueMailJob')) {
|
||||
$ret = $queueService->queueMailJob($mail_params, $to, $hdrs, $this->_translator->translate($subject, $params, null, $lang), $message);
|
||||
$ret = $queueService->queueMailJob($mail_params, $to, $hdrs, getMLText($subject, $params, "", $lang), $message);
|
||||
if($ret !== null)
|
||||
return $ret;
|
||||
}
|
||||
|
|
@ -283,10 +279,12 @@ class SeedDMS_EmailNotify extends SeedDMS_Notify {
|
|||
* The dispatching is now done in SeedDMS_NotificationService::toList()
|
||||
*/
|
||||
function toList($sender, $recipients, $subject, $message, $params=array()) { /* {{{ */
|
||||
/*
|
||||
if ((!is_object($sender) && strcasecmp(get_class($sender), $this->_dms->getClassname('user'))) ||
|
||||
(!is_array($recipients) && count($recipients)==0)) {
|
||||
return false;
|
||||
}
|
||||
*/
|
||||
|
||||
$ret = true;
|
||||
foreach ($recipients as $recipient) {
|
||||
|
|
|
|||
|
|
@ -22,20 +22,18 @@
|
|||
* This copyright notice MUST APPEAR in all copies of the script!
|
||||
***************************************************************/
|
||||
|
||||
namespace Seeddms\Seeddms;
|
||||
|
||||
/**
|
||||
* Base class for extensions
|
||||
*
|
||||
* @author Uwe Steinmann <uwe@steinmann.cx>
|
||||
* @package SeedDMS
|
||||
*/
|
||||
class ExtensionBase {
|
||||
class SeedDMS_ExtBase {
|
||||
var $settings;
|
||||
var $dms;
|
||||
var $logger;
|
||||
|
||||
public function __construct(Settings $settings, $dms, $logger) {
|
||||
public function __construct($settings, $dms, $logger) {
|
||||
$this->settings = $settings;
|
||||
$this->dms = $dms;
|
||||
$this->logger = $logger;
|
||||
|
|
|
|||
|
|
@ -14,10 +14,6 @@
|
|||
* @version Release: @package_version@
|
||||
*/
|
||||
|
||||
namespace Seeddms\Seeddms;
|
||||
|
||||
use Seeddms\Seeddms\Utilities;
|
||||
|
||||
/**
|
||||
* Class to represent an extension manager
|
||||
*
|
||||
|
|
@ -29,7 +25,7 @@ use Seeddms\Seeddms\Utilities;
|
|||
* @copyright 2011 Uwe Steinmann
|
||||
* @version Release: @package_version@
|
||||
*/
|
||||
class ExtensionMgr {
|
||||
class SeedDMS_Extension_Mgr {
|
||||
/**
|
||||
* @var string $extdir directory where extensions are located
|
||||
* @access protected
|
||||
|
|
@ -85,12 +81,6 @@ class ExtensionMgr {
|
|||
*/
|
||||
protected $errmsgs;
|
||||
|
||||
/**
|
||||
* @var string[] $warnmsg list of warning message from last operation
|
||||
* @access protected
|
||||
*/
|
||||
protected $warnmsgs;
|
||||
|
||||
/*
|
||||
* Name of json file containg available extension from repository
|
||||
*/
|
||||
|
|
@ -158,6 +148,10 @@ class ExtensionMgr {
|
|||
}
|
||||
} /* }}} */
|
||||
|
||||
public function getRepositoryUrl() { /* {{{ */
|
||||
return $this->reposurl;
|
||||
} /* }}} */
|
||||
|
||||
private function getStreamContext() { /* {{{ */
|
||||
if(!$this->proxyurl)
|
||||
return null;
|
||||
|
|
@ -185,10 +179,6 @@ class ExtensionMgr {
|
|||
return $this->cachedir."/extensions.php";
|
||||
} /* }}} */
|
||||
|
||||
public function setRepositoryUrl($reposurl) { /* {{{ */
|
||||
$this->reposurl = $reposurl;
|
||||
} /* }}} */
|
||||
|
||||
/**
|
||||
* Get the configuration of extensions
|
||||
*
|
||||
|
|
@ -272,14 +262,14 @@ $EXT_CONF = '.var_export($EXT_CONF, true).';');
|
|||
unlink ($destination);
|
||||
}
|
||||
|
||||
$zip = new \ZipArchive();
|
||||
if (!$zip->open($destination, \ZipArchive::CREATE)) {
|
||||
$zip = new ZipArchive();
|
||||
if (!$zip->open($destination, ZIPARCHIVE::CREATE)) {
|
||||
return false;
|
||||
}
|
||||
$source = str_replace('\\', '/', realpath($source));
|
||||
|
||||
if (is_dir($source) === true) {
|
||||
$files = new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator($source), \RecursiveIteratorIterator::SELF_FIRST);
|
||||
$files = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($source), RecursiveIteratorIterator::SELF_FIRST);
|
||||
|
||||
if ($include_dir) {
|
||||
$arr = explode("/",$source);
|
||||
|
|
@ -328,19 +318,13 @@ $EXT_CONF = '.var_export($EXT_CONF, true).';');
|
|||
* @param string $version version of extension (x.y.z)
|
||||
* @return string name of temporary file with archive
|
||||
*/
|
||||
public function createArchive($extname, $version, $dir = null) { /* {{{ */
|
||||
public function createArchive($extname, $version) { /* {{{ */
|
||||
if(!is_dir($this->extdir ."/". $extname))
|
||||
return false;
|
||||
|
||||
if ($dir) {
|
||||
if (!is_dir($dir))
|
||||
return false;
|
||||
$tmpfile = $dir."/".$extname."-".$version.".zip";
|
||||
} else {
|
||||
$tmpfile = $this->cachedir."/".$extname."-".$version.".zip";
|
||||
}
|
||||
$tmpfile = $this->cachedir."/".$extname."-".$version.".zip";
|
||||
|
||||
if(!ExtensionMgr::Zip($this->extdir."/".$extname, $tmpfile)) {
|
||||
if(!SeedDMS_Extension_Mgr::Zip($this->extdir."/".$extname, $tmpfile)) {
|
||||
return false;
|
||||
}
|
||||
// $cmd = "cd ".$this->extdir."/".$extname."; zip -r ".$tmpfile." .";
|
||||
|
|
@ -413,22 +397,17 @@ $EXT_CONF = '.var_export($EXT_CONF, true).';');
|
|||
return false;
|
||||
|
||||
return self::checkExtensionByName($extname, $extconf, $options);
|
||||
} /* }}} */
|
||||
}
|
||||
|
||||
/**
|
||||
* Check configuration of extension
|
||||
* Check content of extension directory or configuration of extension
|
||||
*
|
||||
* This method checks if the configurations of an extension is complete
|
||||
* and all dependencies specified in the configuration are met.
|
||||
*
|
||||
* @param string $extname not used anymore. Was previously use to store
|
||||
* result of the check into $this->configcache, but this method can be
|
||||
* used for installed extensions and those in the repository, which makes
|
||||
* the use of a cache useless.
|
||||
* @param array $extconf extension configuration to be checked
|
||||
* @param array $options array with option element 'noconstraints'.
|
||||
* Set 'noconstraints' to true if constraints to local seeddms
|
||||
* installation shall not be checked.
|
||||
* @param string|array $dir full path to extension directory or extension name
|
||||
* or an array containing the configuration.
|
||||
* @param array $options array with options elements 'noconstraints' and 'nofiles'.
|
||||
* Set 'noconstraints' to true if
|
||||
* constraints to local seeddms installation shall not be checked. Set 'nofiles'
|
||||
* to true to turn off checking of files
|
||||
* @return boolean true if check was successful, otherwise false
|
||||
*/
|
||||
public function checkExtensionByName($extname, $extconf, $options=array()) { /* {{{ */
|
||||
|
|
@ -437,7 +416,6 @@ $EXT_CONF = '.var_export($EXT_CONF, true).';');
|
|||
}
|
||||
|
||||
$this->errmsgs = array();
|
||||
$this->warnmsgs = array();
|
||||
|
||||
if(!isset($extconf['constraints']['depends']['seeddms'])) {
|
||||
$this->errmsgs[] = "Missing dependency on SeedDMS";
|
||||
|
|
@ -454,16 +432,13 @@ $EXT_CONF = '.var_export($EXT_CONF, true).';');
|
|||
if(!isset($extconf['author'])) {
|
||||
$this->errmsgs[] = "Missing author";
|
||||
}
|
||||
if(!isset($extconf['changes'])) {
|
||||
$this->warnmsgs[] = "Missing changes";
|
||||
}
|
||||
|
||||
if(!isset($options['noconstraints']) || $options['noconstraints'] == false) {
|
||||
if(isset($extconf['constraints']['depends'])) {
|
||||
foreach($extconf['constraints']['depends'] as $dkey=>$dval) {
|
||||
switch($dkey) {
|
||||
case 'seeddms':
|
||||
$version = new Version;
|
||||
$version = new SeedDMS_Version;
|
||||
if(is_array($dval)) {
|
||||
$fullfill = false;
|
||||
foreach($dval as $ddval) {
|
||||
|
|
@ -540,13 +515,13 @@ $EXT_CONF = '.var_export($EXT_CONF, true).';');
|
|||
$newdir = addDirSep($this->cachedir)."ext.new";
|
||||
/* First remove a left over from a previous extension */
|
||||
if(file_exists($newdir)) {
|
||||
Utilities::rrmdir($newdir);
|
||||
SeedDMS_Utils::rrmdir($newdir);
|
||||
}
|
||||
if(!mkdir($newdir, 0755)) {
|
||||
$this->errmsgs[] = "Cannot create temp. extension directory";
|
||||
return false;
|
||||
}
|
||||
$zip = new \ZipArchive;
|
||||
$zip = new ZipArchive;
|
||||
$res = $zip->open($file);
|
||||
if ($res === TRUE) {
|
||||
$zip->extractTo($newdir);
|
||||
|
|
@ -560,7 +535,7 @@ $EXT_CONF = '.var_export($EXT_CONF, true).';');
|
|||
|
||||
/* Check if extension is complete and fullfills the constraints */
|
||||
if(!self::checkExtensionByDir($newdir)) {
|
||||
Utilities::rrmdir($newdir);
|
||||
SeedDMS_Utils::rrmdir($newdir);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
@ -571,11 +546,11 @@ $EXT_CONF = '.var_export($EXT_CONF, true).';');
|
|||
if(!is_dir($this->extdir)) {
|
||||
if(!mkdir($this->extdir, 0755)) {
|
||||
$this->errmsgs[] = "Cannot create extension directory";
|
||||
Utilities::rrmdir($newdir);
|
||||
SeedDMS_Utils::rrmdir($newdir);
|
||||
return false;
|
||||
}
|
||||
} elseif(is_dir($this->extdir ."/". $extname)) {
|
||||
Utilities::rrmdir($this->extdir ."/". $extname);
|
||||
SeedDMS_Utils::rrmdir($this->extdir ."/". $extname);
|
||||
}
|
||||
/* Move the temp. created ext directory to the final location */
|
||||
/* rename() may fail if dirs are moved from one device to another.
|
||||
|
|
@ -597,15 +572,10 @@ $EXT_CONF = '.var_export($EXT_CONF, true).';');
|
|||
* has been copied.
|
||||
*/
|
||||
$this->errmsgs[] = "Cannot move temp. extension directory to final destination";
|
||||
Utilities::rrmdir($this->extdir ."/". $extname);
|
||||
SeedDMS_Utils::rrmdir($this->extdir ."/". $extname);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!$this->createExtensionConf()) {
|
||||
// $this->errmsgs[] = "Cannot update extension configuration";
|
||||
// return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
} /* }}} */
|
||||
|
||||
|
|
@ -616,7 +586,7 @@ $EXT_CONF = '.var_export($EXT_CONF, true).';');
|
|||
* single lines. Each line is either a comment if it starts with an '#'
|
||||
* or a json encoded array containing the extension configuration.
|
||||
*
|
||||
* Run Seeddms\Seeddms\ExtensionMgr::updateExtensionList() to ensure the
|
||||
* Run SeedDMS_Extension_Mgr::updateExtensionList() to ensure the
|
||||
* currently cached extension list file is up to date.
|
||||
*
|
||||
* @return string[] list of json strings or comments
|
||||
|
|
@ -636,7 +606,7 @@ $EXT_CONF = '.var_export($EXT_CONF, true).';');
|
|||
* a list of extension configurations. Only the most recent version
|
||||
* of an extension will be included.
|
||||
*
|
||||
* Run Seeddms\Seeddms\ExtensionMgr::updateExtensionList() to ensure the
|
||||
* Run SeedDMS_Extension_Mgr::updateExtensionList() to ensure the
|
||||
* currently cached extension list file is up to date.
|
||||
*
|
||||
* @return array[] list of extension configurations
|
||||
|
|
@ -646,14 +616,15 @@ $EXT_CONF = '.var_export($EXT_CONF, true).';');
|
|||
$result = array();
|
||||
$vcache = array(); // keep highest version of extension
|
||||
foreach($list as $e) {
|
||||
if($e[0] != '#') {
|
||||
$re = json_decode($e, true);
|
||||
if(!isset($result[$re['name']])) {
|
||||
$result[$re['name']] = $re;
|
||||
$vcache[$re['name']] = $re['version'];
|
||||
} elseif(self::cmpVersion($re['version'], $vcache[$re['name']]) > 0) {
|
||||
$result[$re['name']] = $re;
|
||||
$vcache[$re['name']] = $re['version'];
|
||||
if($e[0] != '#' && trim($e)) {
|
||||
if($re = json_decode($e, true)) {
|
||||
if(!isset($result[$re['name']])) {
|
||||
$result[$re['name']] = $re;
|
||||
$vcache[$re['name']] = $re['version'];
|
||||
} elseif(self::cmpVersion($re['version'], $vcache[$re['name']]) > 0) {
|
||||
$result[$re['name']] = $re;
|
||||
$vcache[$re['name']] = $re['version'];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -667,7 +638,7 @@ $EXT_CONF = '.var_export($EXT_CONF, true).';');
|
|||
* a list of extension configurations. Only those extensions will
|
||||
* be included which maches the given name.
|
||||
*
|
||||
* Run Seeddms\Seeddms\ExtensionMgr::updateExtensionList() to ensure the
|
||||
* Run SeedDMS_Extension_Mgr::updateExtensionList() to ensure the
|
||||
* currently cached extension list file is up to date.
|
||||
*
|
||||
* @return array[] list of extension configurations
|
||||
|
|
@ -683,16 +654,13 @@ $EXT_CONF = '.var_export($EXT_CONF, true).';');
|
|||
}
|
||||
}
|
||||
}
|
||||
uksort($result, function($a, $b){return ExtensionMgr::cmpVersion($b, $a);});
|
||||
uksort($result, function($a, $b){return SeedDMS_Extension_Mgr::cmpVersion($b, $a);});
|
||||
return $result;
|
||||
} /* }}} */
|
||||
|
||||
/**
|
||||
* Import list of extension from repository
|
||||
*
|
||||
* Will also update the list in the cache, which is used by getExtensionList()
|
||||
* and getExtensionListByName().
|
||||
*
|
||||
* @param boolean $force force download even if file already exists
|
||||
*/
|
||||
public function updateExtensionList($version='', $force=false) { /* {{{ */
|
||||
|
|
@ -730,13 +698,9 @@ $EXT_CONF = '.var_export($EXT_CONF, true).';');
|
|||
*/
|
||||
public function getExtensionFromRepository($file) { /* {{{ */
|
||||
$content = file_get_contents($this->reposurl."/".$file, false, $this->getStreamContext());
|
||||
if ($content) {
|
||||
$tmpfile = tempnam(sys_get_temp_dir(), '');
|
||||
file_put_contents($tmpfile, $content);
|
||||
return $tmpfile;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
$tmpfile = tempnam(sys_get_temp_dir(), '');
|
||||
file_put_contents($tmpfile, $content);
|
||||
return $tmpfile;
|
||||
} /* }}} */
|
||||
|
||||
/**
|
||||
|
|
@ -759,13 +723,4 @@ $EXT_CONF = '.var_export($EXT_CONF, true).';');
|
|||
public function getErrorMsgs() { /* {{{ */
|
||||
return $this->errmsgs;
|
||||
} /* }}} */
|
||||
|
||||
/**
|
||||
* Return all warning messages
|
||||
*
|
||||
* @return string[]
|
||||
*/
|
||||
public function getWarningMsgs() { /* {{{ */
|
||||
return $this->warnmsgs;
|
||||
} /* }}} */
|
||||
}
|
||||
|
|
|
|||
|
|
@ -28,12 +28,12 @@ class SeedDMS_LdapAuthentication extends SeedDMS_Authentication {
|
|||
|
||||
var $settings;
|
||||
|
||||
protected function addUser($username, $info) { /* {{{ */
|
||||
protected function addUser($username, $info) {
|
||||
$mailfield = !empty($this->settings->_ldapMailField) ? $this->settings->_ldapMailField : 'mail';
|
||||
return $this->dms->addUser($username, null, $info['cn'][0], isset($info[$mailfield]) ? $info[$mailfield][0] : '', $this->settings->_language, $this->settings->_theme, "User was added from LDAP");
|
||||
} /* }}} */
|
||||
}
|
||||
|
||||
protected function updateUser($user, $info) { /* {{{ */
|
||||
protected function updateUser($user, $info) {
|
||||
$mailfield = !empty($this->settings->_ldapMailField) ? $this->settings->_ldapMailField : 'mail';
|
||||
if(isset($info['cn'][0]) && ($info['cn'][0] != $user->getFullName())) {
|
||||
$user->setFullName($info['cn'][0]);
|
||||
|
|
@ -41,9 +41,9 @@ class SeedDMS_LdapAuthentication extends SeedDMS_Authentication {
|
|||
if(isset($info[$mailfield][0]) && ($info[$mailfield][0] != $user->getEmail())) {
|
||||
$user->setEmail($info[$mailfield][0]);
|
||||
}
|
||||
} /* }}} */
|
||||
}
|
||||
|
||||
protected function syncGroups($user, $ldapgroups) { /* {{{ */
|
||||
protected function syncGroups($user, $ldapgroups) {
|
||||
$groupnames = [];
|
||||
$count = 0;
|
||||
if(isset($ldapgroups['count']))
|
||||
|
|
@ -88,7 +88,7 @@ class SeedDMS_LdapAuthentication extends SeedDMS_Authentication {
|
|||
}
|
||||
}
|
||||
}
|
||||
} /* }}} */
|
||||
}
|
||||
|
||||
public function __construct($dms, $settings) { /* {{{ */
|
||||
$this->dms = $dms;
|
||||
|
|
@ -233,7 +233,7 @@ class SeedDMS_LdapAuthentication extends SeedDMS_Authentication {
|
|||
}
|
||||
|
||||
/* Check if user already exists in the database. Return with an error
|
||||
* only if the sql statements fails, but not if the user wasn't found.
|
||||
* only if the sql statements fails, but not if no user was found.
|
||||
* The username may not be the one passed to this function anymore. It
|
||||
* could have been overwritten by uid (or sAMAccountName) derived from
|
||||
* the above ldap search.
|
||||
|
|
|
|||
|
|
@ -41,11 +41,6 @@ class SeedDMS_NotificationService {
|
|||
*/
|
||||
protected $settings;
|
||||
|
||||
/*
|
||||
* Translator
|
||||
*/
|
||||
protected $translator;
|
||||
|
||||
/*
|
||||
* Possible types of receivers
|
||||
*/
|
||||
|
|
@ -56,13 +51,14 @@ class SeedDMS_NotificationService {
|
|||
const RECV_APPROVER = 4;
|
||||
const RECV_WORKFLOW = 5;
|
||||
const RECV_UPLOADER = 6;
|
||||
const RECV_REVISOR = 7;
|
||||
const RECV_RECIPIENT = 8;
|
||||
|
||||
public function __construct($logger = null, $settings = null, $translator=null) { /* {{{ */
|
||||
public function __construct($logger = null, $settings = null) { /* {{{ */
|
||||
$this->services = array();
|
||||
$this->errors = array();
|
||||
$this->logger = $logger;
|
||||
$this->settings = $settings;
|
||||
$this->translator = $translator;
|
||||
} /* }}} */
|
||||
|
||||
public function addService($service, $name='') { /* {{{ */
|
||||
|
|
@ -72,10 +68,6 @@ class SeedDMS_NotificationService {
|
|||
$this->errors[$name] = true;
|
||||
} /* }}} */
|
||||
|
||||
public function getTranslator() { /* {{{ */
|
||||
return $this->translator;
|
||||
} /* }}} */
|
||||
|
||||
public function getServices() { /* {{{ */
|
||||
return $this->services;
|
||||
} /* }}} */
|
||||
|
|
@ -693,64 +685,6 @@ class SeedDMS_NotificationService {
|
|||
}
|
||||
} /* }}} */
|
||||
|
||||
public function sendChangedVersionAttributesMail($version, $user, $oldattributes) { /* {{{ */
|
||||
$document = $version->getDocument();
|
||||
$dms = $document->getDMS();
|
||||
$folder = $document->getFolder();
|
||||
$notifyList = $document->getNotifyList();
|
||||
|
||||
$newattributes = $version->getAttributes();
|
||||
if($oldattributes) {
|
||||
foreach($oldattributes as $attrdefid=>$attribute) {
|
||||
if(!isset($newattributes[$attrdefid]) || $newattributes[$attrdefid]->getValueAsArray() !== $oldattributes[$attrdefid]->getValueAsArray()) {
|
||||
$subject = "attribute_changed_email_subject";
|
||||
$message = "attribute_changed_email_body";
|
||||
$params = array();
|
||||
$params['name'] = $document->getName();
|
||||
$params['version'] = $version->getVersion();
|
||||
$params['attribute_name'] = $attribute->getAttributeDefinition()->getName();
|
||||
$params['attribute_old_value'] = $oldattributes[$attrdefid]->getValue();
|
||||
$params['attribute_new_value'] = isset($newattributes[$attrdefid]) ? $newattributes[$attrdefid]->getValue() : '';
|
||||
$params['folder_path'] = $folder->getFolderPathPlain();
|
||||
$params['username'] = $user->getFullName();
|
||||
$params['url'] = getBaseUrl().$this->settings->_httpRoot."out/out.ViewDocument.php?documentid=".$document->getID();
|
||||
$params['sitename'] = $this->settings->_siteName;
|
||||
$params['http_root'] = $this->settings->_httpRoot;
|
||||
|
||||
$this->toList($user, $notifyList["users"], $subject, $message, $params, SeedDMS_NotificationService::RECV_NOTIFICATION);
|
||||
foreach ($notifyList["groups"] as $grp) {
|
||||
$this->toGroup($user, $grp, $subject, $message, $params, SeedDMS_NotificationService::RECV_NOTIFICATION);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
/* Check for new attributes which didn't have a value before */
|
||||
if($newattributes) {
|
||||
foreach($newattributes as $attrdefid=>$attribute) {
|
||||
if(!isset($oldattributes[$attrdefid]) && $attribute) {
|
||||
$subject = "attribute_changed_email_subject";
|
||||
$message = "attribute_changed_email_body";
|
||||
$params = array();
|
||||
$params['name'] = $document->getName();
|
||||
$params['version'] = $version->getVersion();
|
||||
$params['attribute_name'] = $dms->getAttributeDefinition($attrdefid)->getName();
|
||||
$params['attribute_old_value'] = '';
|
||||
$params['attribute_new_value'] = $attribute->getValue();
|
||||
$params['folder_path'] = $folder->getFolderPathPlain();
|
||||
$params['username'] = $user->getFullName();
|
||||
$params['url'] = getBaseUrl().$this->settings->_httpRoot."out/out.ViewDocument.php?documentid=".$document->getID();
|
||||
$params['sitename'] = $this->settings->_siteName;
|
||||
$params['http_root'] = $this->settings->_httpRoot;
|
||||
|
||||
$this->toList($user, $notifyList["users"], $subject, $message, $params, SeedDMS_NotificationService::RECV_NOTIFICATION);
|
||||
foreach ($notifyList["groups"] as $grp) {
|
||||
$this->toGroup($user, $grp, $subject, $message, $params, SeedDMS_NotificationService::RECV_NOTIFICATION);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} /* }}} */
|
||||
|
||||
public function sendChangedFolderAttributesMail($folder, $user, $oldattributes) { /* {{{ */
|
||||
$dms = $folder->getDMS();
|
||||
$notifyList = $folder->getNotifyList();
|
||||
|
|
@ -1243,6 +1177,80 @@ class SeedDMS_NotificationService {
|
|||
$this->toIndividual($user, $content->getUser(), $subject, $message, $params, SeedDMS_NotificationService::RECV_UPLOADER);
|
||||
} /* }}} */
|
||||
|
||||
public function sendSubmittedReceiptMail($content, $user, $receiptlog) { /* {{{ */
|
||||
$document = $content->getDocument();
|
||||
$nl=$document->getNotifyList();
|
||||
$folder = $document->getFolder();
|
||||
$subject = "receipt_submit_email_subject";
|
||||
$message = "receipt_submit_email_body";
|
||||
$params = array();
|
||||
$params['name'] = $document->getName();
|
||||
$params['document_id'] = $document->getId();
|
||||
$params['version'] = $content->getVersion();
|
||||
$params['folder_path'] = $folder->getFolderPathPlain();
|
||||
$params['status'] = getReceiptStatusText($receiptlog["status"]);
|
||||
$params['comment'] = $receiptlog['comment'];
|
||||
$params['username'] = $user->getFullName();
|
||||
$params['url'] = getBaseUrl().$this->settings->_httpRoot."out/out.ViewDocument.php?documentid=".$document->getID();
|
||||
$params['sitename'] = $this->settings->_siteName;
|
||||
$params['http_root'] = $this->settings->_httpRoot;
|
||||
$this->toList($user, $nl["users"], $subject, $message, $params, SeedDMS_NotificationService::RECV_NOTIFICATION);
|
||||
foreach ($nl["groups"] as $grp) {
|
||||
$this->toGroup($user, $grp, $subject, $message, $params, SeedDMS_NotificationService::RECV_NOTIFICATION);
|
||||
}
|
||||
/* Send mail to owner only if the currently logged in user is not the
|
||||
* owner and the owner is not already in the list of notifiers.
|
||||
*/
|
||||
/*
|
||||
if($user->getID() != $document->getOwner()->getID() && false === SeedDMS_Core_DMS::inList($document->getOwner(), $nl['users']))
|
||||
$this->toIndividual($user, $document->getOwner(), $subject, $message, $params, SeedDMS_NotificationService::RECV_OWNER);
|
||||
*/
|
||||
|
||||
/* Send mail to uploader of version only if the uploader is not the owner and
|
||||
* the currently logged in user is not the
|
||||
* owner and the owner is not already in the list of notifiers.
|
||||
*/
|
||||
if($user->getID() != $content->getUser()->getID() /* && $content->getUser()->getID() != $document->getOwner()->getID() */ && false === SeedDMS_Core_DMS::inList($content->getUser(), $nl['users']))
|
||||
$this->toIndividual($user, $content->getUser(), $subject, $message, $params, SeedDMS_NotificationService::RECV_UPLOADER);
|
||||
} /* }}} */
|
||||
|
||||
public function sendSubmittedRevisionMail($content, $user, $revisionlog) { /* {{{ */
|
||||
$document = $content->getDocument();
|
||||
$nl=$document->getNotifyList();
|
||||
$folder = $document->getFolder();
|
||||
$subject = "revision_submit_email_subject";
|
||||
$message = "revision_submit_email_body";
|
||||
$params = array();
|
||||
$params['name'] = $document->getName();
|
||||
$params['document_id'] = $document->getId();
|
||||
$params['version'] = $content->getVersion();
|
||||
$params['folder_path'] = $folder->getFolderPathPlain();
|
||||
$params['status'] = getRevisionStatusText($revisionlog["status"]);
|
||||
$params['comment'] = $revisionlog['comment'];
|
||||
$params['username'] = $user->getFullName();
|
||||
$params['url'] = getBaseUrl().$this->settings->_httpRoot."out/out.ViewDocument.php?documentid=".$document->getID();
|
||||
$params['sitename'] = $this->settings->_siteName;
|
||||
$params['http_root'] = $this->settings->_httpRoot;
|
||||
$this->toList($user, $nl["users"], $subject, $message, $params, SeedDMS_NotificationService::RECV_NOTIFICATION);
|
||||
foreach ($nl["groups"] as $grp) {
|
||||
$this->toGroup($user, $grp, $subject, $message, $params, SeedDMS_NotificationService::RECV_NOTIFICATION);
|
||||
}
|
||||
/* Send mail to owner only if the currently logged in user is not the
|
||||
* owner and the owner is not already in the list of notifiers.
|
||||
*/
|
||||
/*
|
||||
if($user->getID() != $document->getOwner()->getID() && false === SeedDMS_Core_DMS::inList($document->getOwner(), $nl['users']))
|
||||
$this->toIndividual($user, $document->getOwner(), $subject, $message, $params, SeedDMS_NotificationService::RECV_OWNER);
|
||||
*/
|
||||
|
||||
/* Send mail to uploader of version only if the uploader is not the owner and
|
||||
* the currently logged in user is not the
|
||||
* owner and the owner is not already in the list of notifiers.
|
||||
*/
|
||||
if($user->getID() != $content->getUser()->getID() /* && $content->getUser()->getID() != $document->getOwner()->getID() */ && false === SeedDMS_Core_DMS::inList($content->getUser(), $nl['users']))
|
||||
$this->toIndividual($user, $content->getUser(), $subject, $message, $params, SeedDMS_NotificationService::RECV_UPLOADER);
|
||||
} /* }}} */
|
||||
|
||||
public function sendDeleteApprovalMail($content, $user, $approver) { /* {{{ */
|
||||
$document = $content->getDocument();
|
||||
$folder = $document->getFolder();
|
||||
|
|
@ -1276,7 +1284,11 @@ class SeedDMS_NotificationService {
|
|||
$params['folder_path'] = $folder->getFolderPathPlain();
|
||||
$params['version'] = $content->getVersion();
|
||||
$params['comment'] = $content->getComment();
|
||||
$params['username'] = $user->getFullName();
|
||||
if($reviewer->isType('user'))
|
||||
$params['reviewer'] = $reviewer->getFullName();
|
||||
elseif($reviewer->isType('group'))
|
||||
$params['reviewer'] = $reviewer->getName();
|
||||
$params['username'] = $user->getName();
|
||||
$params['sitename'] = $this->settings->_siteName;
|
||||
$params['http_root'] = $this->settings->_httpRoot;
|
||||
$params['url'] = getBaseUrl().$this->settings->_httpRoot."out/out.ViewDocument.php?documentid=".$document->getID();
|
||||
|
|
@ -1287,6 +1299,58 @@ class SeedDMS_NotificationService {
|
|||
$this->toGroup($user, $reviewer, $subject, $message, $params, SeedDMS_NotificationService::RECV_REVIEWER);
|
||||
} /* }}} */
|
||||
|
||||
public function sendDeleteRevisionMail($content, $user, $revisor) { /* {{{ */
|
||||
$document = $content->getDocument();
|
||||
$folder = $document->getFolder();
|
||||
$subject = "revision_deletion_email_subject";
|
||||
$message = "revision_deletion_email_body";
|
||||
$params = array();
|
||||
$params['name'] = $document->getName();
|
||||
$params['document_id'] = $document->getId();
|
||||
$params['folder_path'] = $folder->getFolderPathPlain();
|
||||
$params['version'] = $content->getVersion();
|
||||
$params['comment'] = $content->getComment();
|
||||
if($revisor->isType('user'))
|
||||
$params['revisor'] = $revisor->getFullName();
|
||||
elseif($revisor->isType('group'))
|
||||
$params['revisor'] = $revisor->getName();
|
||||
$params['username'] = $user->getFullName();
|
||||
$params['sitename'] = $this->settings->_siteName;
|
||||
$params['http_root'] = $this->settings->_httpRoot;
|
||||
$params['url'] = getBaseUrl().$this->settings->_httpRoot."out/out.ViewDocument.php?documentid=".$document->getID();
|
||||
|
||||
if($revisor->isType('user'))
|
||||
$this->toIndividual($user, $revisor, $subject, $message, $params, SeedDMS_NotificationService::RECV_REVISOR);
|
||||
elseif($revisor->isType('group'))
|
||||
$this->toGroup($user, $revisor, $subject, $message, $params, SeedDMS_NotificationService::RECV_REVISOR);
|
||||
} /* }}} */
|
||||
|
||||
public function sendDeleteReceiptMail($content, $user, $recipient) { /* {{{ */
|
||||
$document = $content->getDocument();
|
||||
$folder = $document->getFolder();
|
||||
$subject = "receipt_deletion_email_subject";
|
||||
$message = "receipt_deletion_email_body";
|
||||
$params = array();
|
||||
$params['name'] = $document->getName();
|
||||
$params['document_id'] = $document->getId();
|
||||
$params['folder_path'] = $folder->getFolderPathPlain();
|
||||
$params['version'] = $content->getVersion();
|
||||
$params['comment'] = $content->getComment();
|
||||
if($recipient->isType('user'))
|
||||
$params['recipient'] = $recipient->getFullName();
|
||||
elseif($recipient->isType('group'))
|
||||
$params['recipient'] = $recipient->getName();
|
||||
$params['username'] = $user->getFullName();
|
||||
$params['sitename'] = $this->settings->_siteName;
|
||||
$params['http_root'] = $this->settings->_httpRoot;
|
||||
$params['url'] = getBaseUrl().$this->settings->_httpRoot."out/out.ViewDocument.php?documentid=".$document->getID();
|
||||
|
||||
if($recipient->isType('user'))
|
||||
$this->toIndividual($user, $recipient, $subject, $message, $params, SeedDMS_NotificationService::RECV_RECIPIENT);
|
||||
elseif($recipient->isType('group'))
|
||||
$this->toGroup($user, $recipient, $subject, $message, $params, SeedDMS_NotificationService::RECV_RECIPIENT);
|
||||
} /* }}} */
|
||||
|
||||
/**
|
||||
* This notification is send if a new approver is added.
|
||||
*
|
||||
|
|
@ -1338,6 +1402,10 @@ class SeedDMS_NotificationService {
|
|||
$params['folder_path'] = $folder->getFolderPathPlain();
|
||||
$params['version'] = $content->getVersion();
|
||||
$params['comment'] = $content->getComment();
|
||||
if($reviewer->isType('user'))
|
||||
$params['reviewer'] = $reviewer->getFullName();
|
||||
elseif($reviewer->isType('group'))
|
||||
$params['reviewer'] = $reviewer->getName();
|
||||
$params['username'] = $user->getFullName();
|
||||
$params['url'] = getBaseUrl().$this->settings->_httpRoot."out/out.ViewDocument.php?documentid=".$document->getID();
|
||||
$params['sitename'] = $this->settings->_siteName;
|
||||
|
|
@ -1349,6 +1417,89 @@ class SeedDMS_NotificationService {
|
|||
$this->toGroup($user, $reviewer, $subject, $message, $params, SeedDMS_NotificationService::RECV_REVIEWER);
|
||||
} /* }}} */
|
||||
|
||||
public function sendAddRevisionMail($content, $user, $revisor) { /* {{{ */
|
||||
$document = $content->getDocument();
|
||||
$folder = $document->getFolder();
|
||||
|
||||
$subject = "revision_request_email_subject";
|
||||
$message = "revision_request_email_body";
|
||||
$params = array();
|
||||
$params['name'] = $document->getName();
|
||||
$params['document_id'] = $document->getId();
|
||||
$params['folder_path'] = $folder->getFolderPathPlain();
|
||||
$params['version'] = $content->getVersion();
|
||||
$params['comment'] = $content->getComment();
|
||||
if($revisor->isType('user'))
|
||||
$params['revisor'] = $revisor->getFullName();
|
||||
elseif($revisor->isType('group'))
|
||||
$params['revisor'] = $user->getName();
|
||||
$params['username'] = $user->getFullName();
|
||||
$params['url'] = getBaseUrl().$this->settings->_httpRoot."out/out.ViewDocument.php?documentid=".$document->getID();
|
||||
$params['sitename'] = $this->settings->_siteName;
|
||||
$params['http_root'] = $this->settings->_httpRoot;
|
||||
|
||||
if($revisor->isType('user'))
|
||||
$this->toIndividual($user, $revisor, $subject, $message, $params, SeedDMS_NotificationService::RECV_REVISOR);
|
||||
elseif($revisor->isType('group'))
|
||||
$this->toGroup($user, $revisor, $subject, $message, $params, SeedDMS_NotificationService::RECV_REVISOR);
|
||||
} /* }}} */
|
||||
|
||||
public function sendAddReceiptMail($content, $user, $recipient) { /* {{{ */
|
||||
$document = $content->getDocument();
|
||||
$folder = $document->getFolder();
|
||||
|
||||
$subject = "receipt_request_email_subject";
|
||||
$message = "receipt_request_email_body";
|
||||
$params = array();
|
||||
$params['name'] = $document->getName();
|
||||
$params['document_id'] = $document->getId();
|
||||
$params['folder_path'] = $folder->getFolderPathPlain();
|
||||
$params['version'] = $content->getVersion();
|
||||
$params['comment'] = $content->getComment();
|
||||
if($recipient->isType('user'))
|
||||
$params['recipient'] = $recipient->getFullName();
|
||||
elseif($recipient->isType('group'))
|
||||
$params['recipient'] = $user->getName();
|
||||
$params['username'] = $user->getFullName();
|
||||
$params['url'] = getBaseUrl().$this->settings->_httpRoot."out/out.ViewDocument.php?documentid=".$document->getID();
|
||||
$params['sitename'] = $this->settings->_siteName;
|
||||
$params['http_root'] = $this->settings->_httpRoot;
|
||||
|
||||
if($recipient->isType('user'))
|
||||
$this->toIndividual($user, $recipient, $subject, $message, $params, SeedDMS_NotificationService::RECV_RECIPIENT);
|
||||
elseif($recipient->isType('group'))
|
||||
$this->toGroup($user, $recipient, $subject, $message, $params, SeedDMS_NotificationService::RECV_RECIPIENT);
|
||||
} /* }}} */
|
||||
|
||||
/**
|
||||
* Send a request receipt notification to all recipients of the document content
|
||||
*
|
||||
* This method can be called when the status of a document content changes
|
||||
* to 'released'. The recipients haven't been informed when the
|
||||
* document content was created but not immediatly released.
|
||||
*/
|
||||
public function sendToAllReceiptMail($content, $user) { /* {{{ */
|
||||
$dms = $content->getDMS();
|
||||
|
||||
$receiptStatus = $content->getReceiptStatus();
|
||||
if (!empty($receiptStatus)) {
|
||||
foreach ($receiptStatus as $r) {
|
||||
if($r['status'] == 0) {
|
||||
switch ($r["type"]) {
|
||||
case 0: // Recipient is an individual.
|
||||
if($recipient = $dms->getUser($r["required"]))
|
||||
$this->sendAddReceiptMail($content, $user, $recipient);
|
||||
break;
|
||||
case 1: // Recipient is a group.
|
||||
if($recipient = $dms->getGroup($r["required"]))
|
||||
$this->sendAddReceiptMail($content, $user, $recipient);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} /* }}} */
|
||||
|
||||
public function sendChangedDocumentOwnerMail($document, $user, $oldowner) { /* {{{ */
|
||||
if($oldowner->getID() != $document->getOwner()->getID()) {
|
||||
$notifyList = $document->getNotifyList();
|
||||
|
|
|
|||
74
inc/inc.ClassScheduler.php
Normal file
74
inc/inc.ClassScheduler.php
Normal file
|
|
@ -0,0 +1,74 @@
|
|||
<?php
|
||||
/**
|
||||
* Implementation of an SchedulerTask.
|
||||
*
|
||||
* SeedDMS can be extended by extensions. Extension usually implement
|
||||
* hook.
|
||||
*
|
||||
* @category DMS
|
||||
* @package SeedDMS
|
||||
* @license GPL 2
|
||||
* @version @version@
|
||||
* @author Uwe Steinmann <uwe@steinmann.cx>
|
||||
* @copyright 2018 Uwe Steinmann
|
||||
* @version Release: @package_version@
|
||||
*/
|
||||
|
||||
/**
|
||||
* Class to represent a SchedulerTask
|
||||
*
|
||||
* This class provides some very basic methods to manage extensions.
|
||||
*
|
||||
* @category DMS
|
||||
* @package SeedDMS
|
||||
* @author Markus Westphal, Malcolm Cowe, Uwe Steinmann <uwe@steinmann.cx>
|
||||
* @copyright 2011 Uwe Steinmann
|
||||
* @version Release: @package_version@
|
||||
*/
|
||||
class SeedDMS_Scheduler {
|
||||
|
||||
/**
|
||||
* Instanz of database
|
||||
*/
|
||||
protected $db;
|
||||
|
||||
public function getTask($id) { /* {{{ */
|
||||
return SeedDMS_SchedulerTask::getInstance($id, $this->db);
|
||||
} /* }}} */
|
||||
|
||||
public function getTasksByExtension($extname, $taskname) { /* {{{ */
|
||||
return SeedDMS_SchedulerTask::getInstancesByExtension($extname, $taskname, $this->db);
|
||||
} /* }}} */
|
||||
|
||||
public function getTasks() { /* {{{ */
|
||||
return SeedDMS_SchedulerTask::getInstances($this->db);
|
||||
} /* }}} */
|
||||
|
||||
public function addTask($extname, $taskname, $name, $description, $frequency, $disabled, $params) { /* {{{ */
|
||||
$db = $this->db;
|
||||
if(!$extname)
|
||||
return false;
|
||||
if(!$taskname)
|
||||
return false;
|
||||
try {
|
||||
$cron = Cron\CronExpression::factory($frequency);
|
||||
} catch (Exception $e) {
|
||||
return false;
|
||||
}
|
||||
$nextrun = $cron->getNextRunDate()->format('Y-m-d H:i:s');
|
||||
|
||||
$queryStr = "INSERT INTO `tblSchedulerTask` (`extension`, `task`, `name`, `description`, `frequency`, `disabled`, `params`, `nextrun`, `lastrun`) VALUES (".$db->qstr($extname).", ".$db->qstr($taskname).", ".$db->qstr($name).", ".$db->qstr($description).", ".$db->qstr($frequency).", ".intval($disabled).", ".$db->qstr(json_encode($params)).", '".$nextrun."', NULL)";
|
||||
$res = $db->getResult($queryStr);
|
||||
if (!$res)
|
||||
return false;
|
||||
|
||||
$task = SeedDMS_SchedulerTask::getInstance($db->getInsertID('tblSchedulerTask'), $db);
|
||||
|
||||
return $task;
|
||||
} /* }}} */
|
||||
|
||||
function __construct($db) {
|
||||
$this->db = $db;
|
||||
}
|
||||
|
||||
}
|
||||
347
inc/inc.ClassSchedulerTask.php
Normal file
347
inc/inc.ClassSchedulerTask.php
Normal file
|
|
@ -0,0 +1,347 @@
|
|||
<?php
|
||||
/**
|
||||
* Implementation of an SchedulerTask.
|
||||
*
|
||||
* SeedDMS can be extended by extensions. Extension usually implement
|
||||
* hook.
|
||||
*
|
||||
* @category DMS
|
||||
* @package SeedDMS
|
||||
* @license GPL 2
|
||||
* @version @version@
|
||||
* @author Uwe Steinmann <uwe@steinmann.cx>
|
||||
* @copyright 2018 Uwe Steinmann
|
||||
* @version Release: @package_version@
|
||||
*/
|
||||
|
||||
/**
|
||||
* Class to represent a SchedulerTask
|
||||
*
|
||||
* This class provides some very basic methods to manage extensions.
|
||||
*
|
||||
* @category DMS
|
||||
* @package SeedDMS
|
||||
* @author Markus Westphal, Malcolm Cowe, Uwe Steinmann <uwe@steinmann.cx>
|
||||
* @copyright 2011 Uwe Steinmann
|
||||
* @version Release: @package_version@
|
||||
*/
|
||||
class SeedDMS_SchedulerTask {
|
||||
/**
|
||||
* Instanz of database
|
||||
*/
|
||||
protected $db;
|
||||
|
||||
/**
|
||||
* @var integer unique id of task
|
||||
*/
|
||||
protected $_id;
|
||||
|
||||
/**
|
||||
* @var string name of task
|
||||
*/
|
||||
protected $_name;
|
||||
|
||||
/**
|
||||
* @var string description of task
|
||||
*/
|
||||
protected $_description;
|
||||
|
||||
/**
|
||||
* @var string extension of task
|
||||
*/
|
||||
protected $_extension;
|
||||
|
||||
/**
|
||||
* @var string task of task
|
||||
*/
|
||||
protected $_task;
|
||||
|
||||
/**
|
||||
* @var string frequency of task
|
||||
*/
|
||||
protected $_frequency;
|
||||
|
||||
/**
|
||||
* @var integer set if disabled
|
||||
*/
|
||||
protected $_disabled;
|
||||
|
||||
/**
|
||||
* @var array list of parameters
|
||||
*/
|
||||
protected $_params;
|
||||
|
||||
/**
|
||||
* @var integer last run
|
||||
*/
|
||||
protected $_lastrun;
|
||||
|
||||
/**
|
||||
* @var integer next run
|
||||
*/
|
||||
protected $_nextrun;
|
||||
|
||||
public static function getInstance($id, $db) { /* {{{ */
|
||||
$queryStr = "SELECT * FROM `tblSchedulerTask` WHERE `id` = " . (int) $id;
|
||||
$resArr = $db->getResultArray($queryStr);
|
||||
if (is_bool($resArr) && $resArr == false)
|
||||
return false;
|
||||
if (count($resArr) != 1)
|
||||
return null;
|
||||
$row = $resArr[0];
|
||||
|
||||
$task = new self($row["id"], $row['name'], $row["description"], $row["extension"], $row["task"], $row["frequency"], $row['disabled'], json_decode($row['params'], true), $row["nextrun"], $row["lastrun"]);
|
||||
$task->setDB($db);
|
||||
|
||||
return $task;
|
||||
} /* }}} */
|
||||
|
||||
public static function getInstances($db) { /* {{{ */
|
||||
$queryStr = "SELECT * FROM `tblSchedulerTask`";
|
||||
$resArr = $db->getResultArray($queryStr);
|
||||
if (is_bool($resArr) && $resArr == false)
|
||||
return false;
|
||||
if (count($resArr) == 0)
|
||||
return array();
|
||||
|
||||
$tasks = array();
|
||||
foreach($resArr as $row) {
|
||||
$task = new self($row["id"], $row['name'], $row["description"], $row["extension"], $row["task"], $row["frequency"], $row['disabled'], json_decode($row['params'], true), $row["nextrun"], $row["lastrun"]);
|
||||
$task->setDB($db);
|
||||
$tasks[] = $task;
|
||||
}
|
||||
|
||||
return $tasks;
|
||||
} /* }}} */
|
||||
|
||||
public static function getInstancesByExtension($extname, $taskname, $db) { /* {{{ */
|
||||
$queryStr = "SELECT * FROM `tblSchedulerTask` WHERE `extension` = '".$extname."' AND `task` = '".$taskname."'";
|
||||
$resArr = $db->getResultArray($queryStr);
|
||||
if (is_bool($resArr) && $resArr == false)
|
||||
return false;
|
||||
if (count($resArr) == 0)
|
||||
return array();
|
||||
|
||||
$tasks = array();
|
||||
foreach($resArr as $row) {
|
||||
$task = new self($row["id"], $row['name'], $row["description"], $row["extension"], $row["task"], $row["frequency"], $row['disabled'], json_decode($row['params'], true), $row["nextrun"], $row["lastrun"]);
|
||||
$task->setDB($db);
|
||||
$tasks[] = $task;
|
||||
}
|
||||
|
||||
return $tasks;
|
||||
} /* }}} */
|
||||
|
||||
function __construct($id, $name, $description, $extension, $task, $frequency, $disabled, $params, $nextrun, $lastrun) {
|
||||
$this->_id = $id;
|
||||
$this->_name = $name;
|
||||
$this->_description = $description;
|
||||
$this->_extension = $extension;
|
||||
$this->_task = $task;
|
||||
$this->_frequency = $frequency;
|
||||
$this->_disabled = $disabled;
|
||||
$this->_params = $params;
|
||||
$this->_nextrun = $nextrun;
|
||||
$this->_lastrun = $lastrun;
|
||||
}
|
||||
|
||||
public function setDB($db) {
|
||||
$this->db = $db;
|
||||
}
|
||||
|
||||
public function getID() {
|
||||
return $this->_id;
|
||||
}
|
||||
|
||||
public function getName() {
|
||||
return $this->_name;
|
||||
}
|
||||
|
||||
public function setName($newName) { /* {{{ */
|
||||
$db = $this->db;
|
||||
|
||||
$queryStr = "UPDATE `tblSchedulerTask` SET `name` =".$db->qstr($newName)." WHERE `id` = " . $this->_id;
|
||||
$res = $db->getResult($queryStr);
|
||||
if (!$res)
|
||||
return false;
|
||||
|
||||
$this->_name = $newName;
|
||||
return true;
|
||||
} /* }}} */
|
||||
|
||||
public function getDescription() {
|
||||
return $this->_description;
|
||||
}
|
||||
|
||||
public function setDescription($newDescripion) { /* {{{ */
|
||||
$db = $this->db;
|
||||
|
||||
$queryStr = "UPDATE `tblSchedulerTask` SET `description` =".$db->qstr($newDescripion)." WHERE `id` = " . $this->_id;
|
||||
$res = $db->getResult($queryStr);
|
||||
if (!$res)
|
||||
return false;
|
||||
|
||||
$this->_description = $newDescripion;
|
||||
return true;
|
||||
} /* }}} */
|
||||
|
||||
public function getExtension() {
|
||||
return $this->_extension;
|
||||
}
|
||||
|
||||
public function getTask() {
|
||||
return $this->_task;
|
||||
}
|
||||
|
||||
public function getFrequency() {
|
||||
return $this->_frequency;
|
||||
}
|
||||
|
||||
public function setFrequency($newFrequency) { /* {{{ */
|
||||
$db = $this->db;
|
||||
|
||||
try {
|
||||
$cron = Cron\CronExpression::factory($newFrequency);
|
||||
} catch (Exception $e) {
|
||||
return false;
|
||||
}
|
||||
$nextrun = $cron->getNextRunDate()->format('Y-m-d H:i:s');
|
||||
|
||||
$queryStr = "UPDATE `tblSchedulerTask` SET `frequency` =".$db->qstr($newFrequency).", `nextrun` = '".$nextrun."' WHERE `id` = " . $this->_id;
|
||||
$res = $db->getResult($queryStr);
|
||||
if (!$res)
|
||||
return false;
|
||||
|
||||
$this->_frequency = $newFrequency;
|
||||
$this->_nextrun = $nextrun;
|
||||
return true;
|
||||
} /* }}} */
|
||||
|
||||
public function getNextRun() {
|
||||
return $this->_nextrun;
|
||||
}
|
||||
|
||||
public function getLastRun() {
|
||||
return $this->_lastrun;
|
||||
}
|
||||
|
||||
public function getDisabled() {
|
||||
return $this->_disabled;
|
||||
}
|
||||
|
||||
public function setDisabled($newDisabled) { /* {{{ */
|
||||
$db = $this->db;
|
||||
|
||||
$queryStr = "UPDATE `tblSchedulerTask` SET `disabled` =".intval($newDisabled)." WHERE `id` = " . $this->_id;
|
||||
$res = $db->getResult($queryStr);
|
||||
if (!$res)
|
||||
return false;
|
||||
|
||||
$this->_disabled = $newDisabled;
|
||||
return true;
|
||||
} /* }}} */
|
||||
|
||||
public function setParameter($newParams) { /* {{{ */
|
||||
$db = $this->db;
|
||||
|
||||
$queryStr = "UPDATE `tblSchedulerTask` SET `params` =".$db->qstr(json_encode($newParams))." WHERE `id` = " . $this->_id;
|
||||
$res = $db->getResult($queryStr);
|
||||
if (!$res)
|
||||
return false;
|
||||
|
||||
$this->_params = $newParams;
|
||||
return true;
|
||||
} /* }}} */
|
||||
|
||||
public function getParameter($name = '') {
|
||||
if($name)
|
||||
return isset($this->_params[$name]) ? $this->_params[$name] : null;
|
||||
return $this->_params;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if task is due
|
||||
*
|
||||
* This methods compares the current time with the time in the database
|
||||
* field `nextrun`.
|
||||
* If nextrun is smaller than the current time, the the task is due.
|
||||
* The methode does not rely on the value in the class variable `_nextrun`,
|
||||
* because that value could be 'very old', retrieved at a time
|
||||
* when the task list was fetched for checking due tasks e.g. by the
|
||||
* scheduler client. There is good reason to always take the current
|
||||
* value of nextrun from the database.
|
||||
*
|
||||
* Assuming there are two tasks. Task 1 takes 13 mins and task 2 takes only
|
||||
* 30 sec. Task 1 is run every hour and task 2 starts at 8:06. The cronjob
|
||||
* runs every 5 min. At e.g. 8:00 the list of tasks is read from the database
|
||||
* task 1 is due and starts running and before it runs it sets the database
|
||||
* field nextrun to 9:00. Task 2 isn't due at that time.
|
||||
* At 8:05 the cron job runs again, task 1 has already a new nextrun value
|
||||
* and will not run again. Task 2 isn't due yet and task 1 started at 8:00 is
|
||||
* still running.
|
||||
* At 8:10 task 1 is still running an not due again, but task 2 is due and
|
||||
* will be run. The database field `nextrun` of task 2 will be set to 8:06
|
||||
* on the next day.
|
||||
* At 8:13 task 1 which started at 8:00 is finished and the list of tasks
|
||||
* from that time will be processed further. Task 2 still has the old value
|
||||
* in the class variable `_nextrun` (8:06 the current day),
|
||||
* though the database field `nextrun` has been updated in
|
||||
* between. Taking the value of the class variable would rerun task 2 again,
|
||||
* though it ran at 8:10 already.
|
||||
* That's why this method always takes the current value of nextrun
|
||||
* from the database.
|
||||
*
|
||||
* @return boolean true if task is due, otherwise false
|
||||
*/
|
||||
public function isDue() {
|
||||
$db = $this->db;
|
||||
|
||||
$queryStr = "SELECT * FROM `tblSchedulerTask` WHERE `id` = " . $this->_id;
|
||||
$resArr = $db->getResultArray($queryStr);
|
||||
if (is_bool($resArr) && $resArr == false)
|
||||
return false;
|
||||
if (count($resArr) != 1)
|
||||
return false;
|
||||
$row = $resArr[0];
|
||||
$this->_nextrun = $row['nextrun'];
|
||||
|
||||
return $this->_nextrun < date('Y-m-d H:i:s');
|
||||
}
|
||||
|
||||
public function updateLastNextRun() {
|
||||
$db = $this->db;
|
||||
|
||||
$lastrun = date('Y-m-d H:i:s');
|
||||
try {
|
||||
$cron = Cron\CronExpression::factory($this->_frequency);
|
||||
$nextrun = $cron->getNextRunDate()->format('Y-m-d H:i:s');
|
||||
} catch (Exception $e) {
|
||||
$nextrun = null;
|
||||
}
|
||||
|
||||
$queryStr = "UPDATE `tblSchedulerTask` SET `lastrun`=".$db->qstr($lastrun).", `nextrun`=".($nextrun ? $db->qstr($nextrun) : "NULL")." WHERE `id` = " . $this->_id;
|
||||
$res = $db->getResult($queryStr);
|
||||
if (!$res)
|
||||
return false;
|
||||
|
||||
$this->_lastrun = $lastrun;
|
||||
$this->_nextrun = $nextrun;
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete task
|
||||
*
|
||||
* @return boolean true on success or false in case of an error
|
||||
*/
|
||||
function remove() { /* {{{ */
|
||||
$db = $this->db;
|
||||
|
||||
$queryStr = "DELETE FROM `tblSchedulerTask` WHERE `id` = " . $this->_id;
|
||||
if (!$db->getResult($queryStr)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
} /* }}} */
|
||||
|
||||
}
|
||||
139
inc/inc.ClassSchedulerTaskBase.php
Normal file
139
inc/inc.ClassSchedulerTaskBase.php
Normal file
|
|
@ -0,0 +1,139 @@
|
|||
<?php
|
||||
/***************************************************************
|
||||
* Copyright notice
|
||||
*
|
||||
* (c) 2018 Uwe Steinmann <uwe@steinmann.cx>
|
||||
* All rights reserved
|
||||
*
|
||||
* This script is part of the SeedDMS project. The SeedDMS project is
|
||||
* free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* The GNU General Public License can be found at
|
||||
* http://www.gnu.org/copyleft/gpl.html.
|
||||
*
|
||||
* This script is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* This copyright notice MUST APPEAR in all copies of the script!
|
||||
***************************************************************/
|
||||
|
||||
/**
|
||||
* Base class for scheduler task
|
||||
*
|
||||
* @author Uwe Steinmann <uwe@steinmann.cx>
|
||||
* @package SeedDMS
|
||||
*/
|
||||
class SeedDMS_SchedulerTaskBase {
|
||||
var $dms;
|
||||
|
||||
var $user;
|
||||
|
||||
var $settings;
|
||||
|
||||
var $logger;
|
||||
|
||||
var $fulltextservice;
|
||||
|
||||
var $notifier;
|
||||
|
||||
var $conversionmgr;
|
||||
|
||||
/**
|
||||
* Call a hook with a given name
|
||||
*
|
||||
* Checks if a hook with the given name and for the current task
|
||||
* exists and executes it. The name of the current task is taken
|
||||
* from the current class name by lower casing the first char.
|
||||
* This function will execute all registered hooks in the order
|
||||
* they were registered.
|
||||
*
|
||||
* Attention: as func_get_arg() cannot handle references passed to the hook,
|
||||
* callHook() should not be called if that is required. In that case get
|
||||
* a list of hook objects with getHookObjects() and call the hooks yourself.
|
||||
*
|
||||
* @params string $hook name of hook
|
||||
* @return string concatenated string, merged arrays or whatever the hook
|
||||
* function returns
|
||||
*/
|
||||
public function callHook($hook) { /* {{{ */
|
||||
$tmps = array();
|
||||
$tmp = explode('_', get_class($this));
|
||||
$tmps[] = $tmp[1];
|
||||
$tmp = explode('_', get_parent_class($this));
|
||||
$tmps[] = $tmp[1];
|
||||
/* Run array_unique() in case the parent class has the same suffix */
|
||||
$tmps = array_unique($tmps);
|
||||
$ret = null;
|
||||
foreach($tmps as $tmp)
|
||||
if(isset($GLOBALS['SEEDDMS_HOOKS']['task'][lcfirst($tmp)])) {
|
||||
foreach($GLOBALS['SEEDDMS_HOOKS']['task'][lcfirst($tmp)] as $hookObj) {
|
||||
if (method_exists($hookObj, $hook)) {
|
||||
switch(func_num_args()) {
|
||||
case 1:
|
||||
$tmpret = $hookObj->$hook($this);
|
||||
break;
|
||||
case 2:
|
||||
$tmpret = $hookObj->$hook($this, func_get_arg(1));
|
||||
break;
|
||||
case 3:
|
||||
$tmpret = $hookObj->$hook($this, func_get_arg(1), func_get_arg(2));
|
||||
break;
|
||||
case 4:
|
||||
$tmpret = $hookObj->$hook($this, func_get_arg(1), func_get_arg(2), func_get_arg(3));
|
||||
break;
|
||||
default:
|
||||
case 5:
|
||||
$tmpret = $hookObj->$hook($this, func_get_arg(1), func_get_arg(2), func_get_arg(3), func_get_arg(4));
|
||||
break;
|
||||
}
|
||||
if($tmpret !== null) {
|
||||
if(is_string($tmpret)) {
|
||||
$ret = ($ret === null) ? $tmpret : (is_string($ret) ? $ret.$tmpret : array_merge($ret, array($tmpret)));
|
||||
} elseif(is_array($tmpret) || is_object($tmpret)) {
|
||||
$ret = ($ret === null) ? $tmpret : (is_string($ret) ? array_merge(array($ret), $tmpret) : array_merge($ret, $tmpret));
|
||||
} else
|
||||
$ret = $tmpret;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return $ret;
|
||||
} /* }}} */
|
||||
|
||||
public function __construct($dms=null, $user=null, $settings=null, $logger=null, $fulltextservice=null, $notifier=null, $conversionmgr=null) { /* {{{ */
|
||||
$this->dms = $dms;
|
||||
$this->user = $user;
|
||||
$this->settings = $settings;
|
||||
$this->logger = $logger;
|
||||
$this->fulltextservice = $fulltextservice;
|
||||
$this->notifier = $notifier;
|
||||
$this->conversionmgr = $conversionmgr;
|
||||
} /* }}} */
|
||||
|
||||
public function execute(SeedDMS_SchedulerTask $task) { /* {{{ */
|
||||
return true;
|
||||
} /* }}} */
|
||||
|
||||
public function getDescription() { /* {{{ */
|
||||
return '';
|
||||
} /* }}} */
|
||||
|
||||
public function getAdditionalParams() { /* {{{ */
|
||||
return array();
|
||||
} /* }}} */
|
||||
|
||||
public function getAdditionalParamByName($name) { /* {{{ */
|
||||
foreach($this->getAdditionalParams() as $param) {
|
||||
if($param['name'] == $name)
|
||||
return $param;
|
||||
}
|
||||
return null;
|
||||
} /* }}} */
|
||||
}
|
||||
|
||||
?>
|
||||
|
|
@ -15,8 +15,6 @@
|
|||
* @version Release: @package_version@
|
||||
*/
|
||||
|
||||
namespace Seeddms\Seeddms;
|
||||
|
||||
/**
|
||||
* Class to represent a session
|
||||
*
|
||||
|
|
@ -31,7 +29,7 @@ namespace Seeddms\Seeddms;
|
|||
* @copyright 2011 Uwe Steinmann
|
||||
* @version Release: @package_version@
|
||||
*/
|
||||
class Session {
|
||||
class SeedDMS_Session {
|
||||
/**
|
||||
* @var object $db reference to database object. This must be an instance
|
||||
* of {@link SeedDMS_Core_DatabaseAccess}.
|
||||
|
|
@ -55,7 +53,7 @@ class Session {
|
|||
* Create a new instance of the session handler
|
||||
*
|
||||
* @param object $db object to access the underlying database
|
||||
* @return object instance of Seeddms\Seeddms\Session
|
||||
* @return object instance of SeedDMS_Session
|
||||
*/
|
||||
function __construct($db) { /* {{{ */
|
||||
$this->db = $db;
|
||||
|
|
@ -419,8 +417,6 @@ class Session {
|
|||
|
||||
}
|
||||
|
||||
class_alias('Seeddms\Seeddms\Session', 'SeedDMS_Session');
|
||||
|
||||
/**
|
||||
* Class for managing sessions
|
||||
*
|
||||
|
|
@ -432,7 +428,7 @@ class_alias('Seeddms\Seeddms\Session', 'SeedDMS_Session');
|
|||
* @copyright 2014 Uwe Steinmann
|
||||
* @version Release: @package_version@
|
||||
*/
|
||||
class SessionMgr {
|
||||
class SeedDMS_SessionMgr {
|
||||
/**
|
||||
* @var object $db reference to database object. This must be an instance
|
||||
* of {@link SeedDMS_Core_DatabaseAccess}.
|
||||
|
|
@ -444,7 +440,7 @@ class SessionMgr {
|
|||
* Create a new instance of the session manager
|
||||
*
|
||||
* @param object $db object to access the underlying database
|
||||
* @return object instance of Seeddms\Seeddms\SessionMgr
|
||||
* @return object instance of SeedDMS_SessionMgr
|
||||
*/
|
||||
function __construct($db) { /* {{{ */
|
||||
$this->db = $db;
|
||||
|
|
@ -482,7 +478,7 @@ class SessionMgr {
|
|||
return false;
|
||||
$sessions = array();
|
||||
foreach($resArr as $rec) {
|
||||
$session = new Session($this->db);
|
||||
$session = new SeedDMS_Session($this->db);
|
||||
$session->load($rec['id']);
|
||||
$sessions[] = $session;
|
||||
}
|
||||
|
|
@ -505,7 +501,7 @@ class SessionMgr {
|
|||
return false;
|
||||
$sessions = array();
|
||||
foreach($resArr as $rec) {
|
||||
$session = new Session($this->db);
|
||||
$session = new SeedDMS_Session($this->db);
|
||||
$session->load($rec['id']);
|
||||
$sessions[] = $session;
|
||||
}
|
||||
|
|
@ -527,7 +523,7 @@ class SessionMgr {
|
|||
return false;
|
||||
$sessions = array();
|
||||
foreach($resArr as $rec) {
|
||||
$session = new Session($this->db);
|
||||
$session = new SeedDMS_Session($this->db);
|
||||
$session->load($rec['id']);
|
||||
$sessions[] = $session;
|
||||
}
|
||||
|
|
@ -535,5 +531,3 @@ class SessionMgr {
|
|||
|
||||
} /* }}} */
|
||||
}
|
||||
|
||||
class_alias('Seeddms\Seeddms\SessionMgr', 'SeedDMS_SessionMgr');
|
||||
|
|
|
|||
|
|
@ -11,12 +11,6 @@
|
|||
* @version Release: @package_version@
|
||||
*/
|
||||
|
||||
namespace Seeddms\Seeddms;
|
||||
|
||||
use SeedDMS_Core_File;
|
||||
use SeedDMS_Core_DMS;
|
||||
use SeedDMS_Core_DatabaseAccess;
|
||||
|
||||
/**
|
||||
* Class for reading and writing the configuration file
|
||||
*
|
||||
|
|
@ -51,6 +45,8 @@ class Settings { /* {{{ */
|
|||
var $_enableGuestLogin = false;
|
||||
// If you even want guest to be logged in automatically, set the following to true
|
||||
var $_enableGuestAutoLogin = false;
|
||||
// Set to true for 2-factor Authentication
|
||||
var $_enable2FactorAuthentication = false;
|
||||
// If you want to allow login by email, set the following to true
|
||||
var $_enableLoginByEmail = false;
|
||||
// Allow users to reset their password
|
||||
|
|
@ -122,6 +118,12 @@ class Settings { /* {{{ */
|
|||
var $_dropFolderDir = null;
|
||||
// Where the backup directory is located
|
||||
var $_backupDir = null;
|
||||
// Where the library folder is located
|
||||
var $_libraryFolder = 1;
|
||||
// Where the checked out files are located
|
||||
var $_checkOutDir = null;
|
||||
// Create checkout dir if it doesn't exists
|
||||
var $_createCheckOutDir = false;
|
||||
// Where the repository for extensions is located
|
||||
var $_repositoryUrl = null;
|
||||
// URL of proxy
|
||||
|
|
@ -152,10 +154,6 @@ class Settings { /* {{{ */
|
|||
var $_showSingleSearchHit = true;
|
||||
// enable/disable use of memcached
|
||||
var $_enableMemcached = false;
|
||||
// memcached host
|
||||
var $_memcachedHost = 'localhost';
|
||||
// memcached port
|
||||
var $_memcachedPort = '11211';
|
||||
// contentOffsetDirTo
|
||||
var $_contentOffsetDir = "1048576";
|
||||
// Maximum number of sub-directories per parent directory
|
||||
|
|
@ -198,6 +196,18 @@ class Settings { /* {{{ */
|
|||
var $_enableUpdateRevApp = false;
|
||||
// enable/disable removal of a review/approval by the administrator
|
||||
var $_enableRemoveRevApp = false;
|
||||
// enable/disable listing logged in user as recipient
|
||||
var $_enableSelfReceipt = false;
|
||||
// enable/disable hidden user as recipient
|
||||
var $_enableHiddenReceipt = true;
|
||||
// enable/disable update of a receipt by the recipient
|
||||
var $_enableUpdateReceipt = false;
|
||||
// enable/disable listing administrator as recipient
|
||||
var $_enableAdminReceipt = false;
|
||||
// enable/disable listing owner as recipient
|
||||
var $_enableOwnerReceipt = false;
|
||||
// enable/disable filter for receipt by the recipient
|
||||
var $_enableFilterReceipt = false;
|
||||
// group manager is mandatory reviewer
|
||||
var $_addManagerAsReviewer = false;
|
||||
// group manager is mandatory approver
|
||||
|
|
@ -220,8 +230,12 @@ class Settings { /* {{{ */
|
|||
var $_enableDuplicateDocNames = true;
|
||||
// enable/disable duplicate names of a subfolder in a folder
|
||||
var $_enableDuplicateSubFolderNames = true;
|
||||
// allow/disallow to cancel a checkout
|
||||
var $_enableCancelCheckout = true;
|
||||
// override mimetype set by browser when uploading a file
|
||||
var $_overrideMimeType = false;
|
||||
// advanced access control lists
|
||||
var $_advancedAcl = false;
|
||||
// enable/disable notification when added as a reviewer/approver
|
||||
var $_enableNotificationAppRev = true;
|
||||
// enable/disable notification of users/group who need to take action for
|
||||
|
|
@ -231,12 +245,26 @@ class Settings { /* {{{ */
|
|||
var $_enableNotificationWorkflow = false;
|
||||
// preset expiration date
|
||||
var $_presetExpirationDate = "";
|
||||
// initial document status
|
||||
var $_initialDocumentStatus = 2; //S_RELEASED;
|
||||
// the name of the versioning info file created by the backup tool
|
||||
var $_versioningFileName = "versioning_info.txt";
|
||||
// the mode of workflow
|
||||
var $_workflowMode = "traditional";
|
||||
// enable/disable acknowledge workflow
|
||||
var $_enableReceiptWorkflow = true;
|
||||
// enable/disable reject of reception
|
||||
var $_enableReceiptReject = false;
|
||||
// enable/disable comment of reception
|
||||
var $_disableReceiptComment = false;
|
||||
// enable/disable revision workflow
|
||||
var $_enableRevisionWorkflow = true;
|
||||
// enable/disable revision on vote reject
|
||||
var $_enableRevisionOneVoteReject = true;
|
||||
// Allow to set just a reviewer in tradional workflow
|
||||
var $_allowReviewerOnly = true;
|
||||
// Allow to change reviewer/approver after review/approval has started
|
||||
var $_allowChangeRevAppInProcess = false;
|
||||
// enable/disable log system
|
||||
var $_logFileEnable = true;
|
||||
// max log level
|
||||
|
|
@ -273,8 +301,12 @@ class Settings { /* {{{ */
|
|||
var $_enableClipboard = true;
|
||||
// show always clipboard in main menu, even if empty
|
||||
var $_alwaysShowClipboard = false;
|
||||
// enable/disable list of transmittals in main menu
|
||||
var $_enableMenuTransmittals = false;
|
||||
// enable/disable list of tasks in main menu
|
||||
var $_enableMenuTasks = true;
|
||||
// select which tasks show up in main menu
|
||||
var $_tasksInMenu = array();
|
||||
// show always tasks in main menu, even if none are due
|
||||
var $_alwaysShowMenuTasks = true;
|
||||
// enable/disable list of files in drop folder
|
||||
|
|
@ -330,8 +362,6 @@ class Settings { /* {{{ */
|
|||
var $_previewWidthDetail = 100;
|
||||
// Preview image width in drop folder list
|
||||
var $_previewWidthDropFolderList = 100;
|
||||
// download or view online when clicking on preview image
|
||||
var $_defaultThumbnailClick = 'download';
|
||||
// show full preview on document details page
|
||||
var $_showFullPreview = false;
|
||||
// convert to pdf for preview on document details page
|
||||
|
|
@ -418,10 +448,7 @@ class Settings { /* {{{ */
|
|||
// Load config file
|
||||
if (!defined("SEEDDMS_INSTALL")) {
|
||||
if(!file_exists($configFilePath)) {
|
||||
if(php_sapi_name() === 'cli')
|
||||
echo "You do not seem to have a valid configuration. Set SEEDDMS_CONFIG_FILE to the path of the configuration file.\n";
|
||||
else
|
||||
echo "You do not seem to have a valid configuration. Run the <a href=\"install/install.php\">install tool</a> first.";
|
||||
echo "You do not seem to have a valid configuration. Run the <a href=\"install/install.php\">install tool</a> first.";
|
||||
exit;
|
||||
}
|
||||
}
|
||||
|
|
@ -431,14 +458,17 @@ class Settings { /* {{{ */
|
|||
echo "Your configuration contains errors.";
|
||||
exit;
|
||||
}
|
||||
|
||||
// if (!is_null($this->_maxExecutionTime))
|
||||
// ini_set("max_execution_time", $this->_maxExecutionTime);
|
||||
} /* }}} */
|
||||
|
||||
/**
|
||||
* Check if the passed parameter equals to 'true', 'on', 'yes' or 'y'
|
||||
* and returns true, if it does.
|
||||
* Check if a variable has the string 'true', 'on', 'yes' or 'y'
|
||||
* and returns true.
|
||||
*
|
||||
* @param string $var value
|
||||
* @return boolean true if $var is 'true', 'on', 'yes' or 'y', otherwise false
|
||||
* @return true/false
|
||||
*/
|
||||
protected static function boolVal($var) { /* {{{ */
|
||||
$var = strtolower(strval($var));
|
||||
|
|
@ -456,10 +486,22 @@ class Settings { /* {{{ */
|
|||
} /* }}} */
|
||||
|
||||
/**
|
||||
* Create ';' seperated string from array
|
||||
* Check if a variable is a string and returns an array
|
||||
*
|
||||
* @param array $var value
|
||||
* @return true/false
|
||||
*/
|
||||
function arrayVal($var) { /* {{{ */
|
||||
if((string) $var)
|
||||
return explode(';', $var);
|
||||
return array();
|
||||
} /* }}} */
|
||||
|
||||
/**
|
||||
* Return ';' seperated string from array
|
||||
*
|
||||
* @param array $value
|
||||
* @return string
|
||||
*
|
||||
*/
|
||||
function arrayToString($value) { /* {{{ */
|
||||
return implode(";", $value);
|
||||
|
|
@ -469,14 +511,14 @@ class Settings { /* {{{ */
|
|||
* Return array from ';' seperated string
|
||||
*
|
||||
* @param string $value
|
||||
* @return array
|
||||
*
|
||||
*/
|
||||
function stringToArray($value) { /* {{{ */
|
||||
return explode(";", $value);
|
||||
} /* }}} */
|
||||
|
||||
/**
|
||||
* Set $_viewOnlineFileTypes
|
||||
* set $_viewOnlineFileTypes
|
||||
*
|
||||
* @param string $stringValue string value
|
||||
*
|
||||
|
|
@ -486,7 +528,7 @@ class Settings { /* {{{ */
|
|||
} /* }}} */
|
||||
|
||||
/**
|
||||
* Get $_viewOnlineFileTypes in a string value
|
||||
* get $_viewOnlineFileTypes in a string value
|
||||
*
|
||||
* @return string value
|
||||
*
|
||||
|
|
@ -496,7 +538,7 @@ class Settings { /* {{{ */
|
|||
} /* }}} */
|
||||
|
||||
/**
|
||||
* Set $_editOnlineFileTypes
|
||||
* set $_editOnlineFileTypes
|
||||
*
|
||||
* @param string $stringValue string value
|
||||
*
|
||||
|
|
@ -506,7 +548,7 @@ class Settings { /* {{{ */
|
|||
} /* }}} */
|
||||
|
||||
/**
|
||||
* Get $_editOnlineFileTypes in a string value
|
||||
* get $_editOnlineFileTypes in a string value
|
||||
*
|
||||
* @return string value
|
||||
*
|
||||
|
|
@ -519,7 +561,8 @@ class Settings { /* {{{ */
|
|||
* Load config file
|
||||
*
|
||||
* @param string $configFilePath config file path
|
||||
* @return boolean true, if loading was successful, otherwise false
|
||||
*
|
||||
* @return true/false
|
||||
*/
|
||||
public function load($configFilePath) { /* {{{ */
|
||||
$contents = file_get_contents($configFilePath);
|
||||
|
|
@ -553,7 +596,6 @@ class Settings { /* {{{ */
|
|||
$this->_previewWidthDetail = intval($tab["previewWidthDetail"]);
|
||||
if(isset($tab["previewWidthDropFolderList"]))
|
||||
$this->_previewWidthDropFolderList = intval($tab["previewWidthDropFolderList"]);
|
||||
$this->_defaultThumbnailClick = strval($tab["defaultThumbnailClick"]);
|
||||
$this->_showFullPreview = Settings::boolVal($tab["showFullPreview"]);
|
||||
$this->_convertToPdf = Settings::boolVal($tab["convertToPdf"]);
|
||||
if(isset($tab["maxItemsPerPage"]))
|
||||
|
|
@ -579,8 +621,10 @@ class Settings { /* {{{ */
|
|||
$this->_enableSessionList = Settings::boolVal($tab["enableSessionList"]);
|
||||
$this->_enableClipboard = Settings::boolVal($tab["enableClipboard"]);
|
||||
$this->_alwaysShowClipboard = Settings::boolVal($tab["alwaysShowClipboard"]);
|
||||
$this->_enableMenuTransmittals = Settings::boolVal($tab["enableMenuTransmittals"]);
|
||||
$this->_enableMenuTasks = Settings::boolVal($tab["enableMenuTasks"]);
|
||||
$this->_alwaysShowMenuTasks = Settings::boolVal($tab["alwaysShowMenuTasks"]);
|
||||
$this->_tasksInMenu = Settings::arrayVal($tab["tasksInMenu"]);
|
||||
$this->_enableDropFolderList = Settings::boolVal($tab["enableDropFolderList"]);
|
||||
$this->_enableDropUpload = Settings::boolVal($tab["enableDropUpload"]);
|
||||
$this->_enableMultiUpload = Settings::boolVal($tab["enableMultiUpload"]);
|
||||
|
|
@ -606,6 +650,7 @@ class Settings { /* {{{ */
|
|||
$this->_sortUsersInList = strval($tab["sortUsersInList"]);
|
||||
$this->_sortFoldersDefault = strval($tab["sortFoldersDefault"]);
|
||||
$this->_expandFolderTree = intval($tab["expandFolderTree"]);
|
||||
$this->_libraryFolder = intval($tab["libraryFolder"]);
|
||||
$this->_defaultDocPosition = strval($tab["defaultDocPosition"]);
|
||||
$this->_defaultFolderPosition = strval($tab["defaultFolderPosition"]);
|
||||
|
||||
|
|
@ -649,6 +694,8 @@ class Settings { /* {{{ */
|
|||
$this->_luceneDir = strval($tab["luceneDir"]);
|
||||
$this->_dropFolderDir = strval($tab["dropFolderDir"]);
|
||||
$this->_backupDir = strval($tab["backupDir"]);
|
||||
$this->_checkOutDir = strval($tab["checkOutDir"]);
|
||||
$this->_createCheckOutDir = Settings::boolVal($tab["createCheckOutDir"]);
|
||||
$this->_repositoryUrl = strval($tab["repositoryUrl"]);
|
||||
$this->_proxyUrl = strval($tab["proxyUrl"]);
|
||||
$this->_proxyUser = strval($tab["proxyUser"]);
|
||||
|
|
@ -662,16 +709,13 @@ class Settings { /* {{{ */
|
|||
$this->_maxUploadSize = strval($tab["maxUploadSize"]);
|
||||
$this->_enableXsendfile = Settings::boolVal($tab["enableXsendfile"]);
|
||||
$this->_enableMemcached = Settings::boolVal($tab["enableMemcached"]);
|
||||
$this->_memcachedHost = strval($tab["memcachedHost"]);
|
||||
$this->_memcachedPort = strval($tab["memcachedPort"]);
|
||||
}
|
||||
|
||||
// XML Path: /configuration/system/authentication
|
||||
$node = $xml->xpath('/configuration/system/authentication');
|
||||
if($node) {
|
||||
// XML Path: /configuration/system/authentication
|
||||
$node = $xml->xpath('/configuration/system/authentication');
|
||||
$tab = $node[0]->attributes();
|
||||
$this->_enableGuestLogin = Settings::boolVal($tab["enableGuestLogin"]);
|
||||
$this->_enableGuestAutoLogin = Settings::boolVal($tab["enableGuestAutoLogin"]);
|
||||
$this->_enable2FactorAuthentication = Settings::boolVal($tab["enable2FactorAuthentication"]);
|
||||
$this->_enableLoginByEmail = Settings::boolVal($tab["enableLoginByEmail"]);
|
||||
$this->_enablePasswordForgotten = Settings::boolVal($tab["enablePasswordForgotten"]);
|
||||
$this->_passwordStrength = intval($tab["passwordStrength"]);
|
||||
|
|
@ -809,6 +853,11 @@ class Settings { /* {{{ */
|
|||
$this->_enableHiddenRevApp = Settings::boolval($tab["enableHiddenRevApp"]);
|
||||
$this->_enableUpdateRevApp = Settings::boolval($tab["enableUpdateRevApp"]);
|
||||
$this->_enableRemoveRevApp = Settings::boolval($tab["enableRemoveRevApp"]);
|
||||
$this->_enableSelfReceipt = Settings::boolval($tab["enableSelfReceipt"]);
|
||||
$this->_enableAdminReceipt = Settings::boolval($tab["enableAdminReceipt"]);
|
||||
$this->_enableOwnerReceipt = Settings::boolval($tab["enableOwnerReceipt"]);
|
||||
$this->_enableUpdateReceipt = Settings::boolval($tab["enableUpdateReceipt"]);
|
||||
$this->_enableFilterReceipt = Settings::boolval($tab["enableFilterReceipt"]);
|
||||
$this->_addManagerAsReviewer = Settings::boolval($tab["addManagerAsReviewer"]);
|
||||
$this->_addManagerAsApprover = Settings::boolval($tab["addManagerAsApprover"]);
|
||||
if(trim(strval($tab["globalReviewer"])))
|
||||
|
|
@ -820,14 +869,23 @@ class Settings { /* {{{ */
|
|||
if(trim(strval($tab["globalGroupApprover"])))
|
||||
$this->_globalGroupApprover = explode(',',strval($tab["globalGroupApprover"]));
|
||||
$this->_presetExpirationDate = strval($tab["presetExpirationDate"]);
|
||||
$this->_initialDocumentStatus = intval($tab["initialDocumentStatus"]);
|
||||
$this->_versioningFileName = strval($tab["versioningFileName"]);
|
||||
$this->_workflowMode = strval($tab["workflowMode"]);
|
||||
$this->_enableReceiptWorkflow = Settings::boolval($tab["enableReceiptWorkflow"]);
|
||||
$this->_enableReceiptReject = Settings::boolval($tab["enableReceiptReject"]);
|
||||
$this->_disableReceiptComment = Settings::boolval($tab["disableReceiptComment"]);
|
||||
$this->_enableRevisionWorkflow = Settings::boolval($tab["enableRevisionWorkflow"]);
|
||||
$this->_enableRevisionOneVoteReject = Settings::boolval($tab["enableRevisionOneVoteReject"]);
|
||||
$this->_allowReviewerOnly = Settings::boolval($tab["allowReviewerOnly"]);
|
||||
$this->_allowChangeRevAppInProcess = Settings::boolval($tab["allowChangeRevAppInProcess"]);
|
||||
$this->_enableVersionDeletion = Settings::boolval($tab["enableVersionDeletion"]);
|
||||
$this->_enableVersionModification = Settings::boolval($tab["enableVersionModification"]);
|
||||
$this->_enableDuplicateDocNames = Settings::boolval($tab["enableDuplicateDocNames"]);
|
||||
$this->_enableDuplicateSubFolderNames = Settings::boolval($tab["enableDuplicateSubFolderNames"]);
|
||||
$this->_enableCancelCheckout = Settings::boolval($tab["enableCancelCheckout"]);
|
||||
$this->_overrideMimeType = Settings::boolval($tab["overrideMimeType"]);
|
||||
$this->_advancedAcl = Settings::boolval($tab["advancedAcl"]);
|
||||
$this->_removeFromDropFolder = Settings::boolval($tab["removeFromDropFolder"]);
|
||||
$this->_uploadedAttachmentIsPublic = Settings::boolval($tab["uploadedAttachmentIsPublic"]);
|
||||
}
|
||||
|
|
@ -912,6 +970,8 @@ class Settings { /* {{{ */
|
|||
$attributValue = "true";
|
||||
else
|
||||
$attributValue = "false";
|
||||
} elseif(is_array($attributValue)) {
|
||||
$attributValue = implode(';', $attributValue);
|
||||
}
|
||||
|
||||
if (isset($node[$attributName])) {
|
||||
|
|
@ -977,7 +1037,6 @@ class Settings { /* {{{ */
|
|||
$this->setXMLAttributValue($node, "previewWidthMenuList", $this->_previewWidthMenuList);
|
||||
$this->setXMLAttributValue($node, "previewWidthDetail", $this->_previewWidthDetail);
|
||||
$this->setXMLAttributValue($node, "previewWidthDropFolderList", $this->_previewWidthDropFolderList);
|
||||
$this->setXMLAttributValue($node, "defaultThumbnailClick", $this->_defaultThumbnailClick);
|
||||
$this->setXMLAttributValue($node, "showFullPreview", $this->_showFullPreview);
|
||||
$this->setXMLAttributValue($node, "convertToPdf", $this->_convertToPdf);
|
||||
$this->setXMLAttributValue($node, "maxItemsPerPage", $this->_maxItemsPerPage);
|
||||
|
|
@ -998,8 +1057,10 @@ class Settings { /* {{{ */
|
|||
$this->setXMLAttributValue($node, "enableSessionList", $this->_enableSessionList);
|
||||
$this->setXMLAttributValue($node, "enableClipboard", $this->_enableClipboard);
|
||||
$this->setXMLAttributValue($node, "alwaysShowClipboard", $this->_alwaysShowClipboard);
|
||||
$this->setXMLAttributValue($node, "enableMenuTransmittals", $this->_enableMenuTransmittals);
|
||||
$this->setXMLAttributValue($node, "enableMenuTasks", $this->_enableMenuTasks);
|
||||
$this->setXMLAttributValue($node, "alwaysShowMenuTasks", $this->_alwaysShowMenuTasks);
|
||||
$this->setXMLAttributValue($node, "tasksInMenu", $this->_tasksInMenu);
|
||||
$this->setXMLAttributValue($node, "enableDropFolderList", $this->_enableDropFolderList);
|
||||
$this->setXMLAttributValue($node, "enableDropUpload", $this->_enableDropUpload);
|
||||
$this->setXMLAttributValue($node, "enableMultiUpload", $this->_enableMultiUpload);
|
||||
|
|
@ -1022,6 +1083,7 @@ class Settings { /* {{{ */
|
|||
$this->setXMLAttributValue($node, "stopWordsFile", $this->_stopWordsFile);
|
||||
$this->setXMLAttributValue($node, "sortUsersInList", $this->_sortUsersInList);
|
||||
$this->setXMLAttributValue($node, "sortFoldersDefault", $this->_sortFoldersDefault);
|
||||
$this->setXMLAttributValue($node, "libraryFolder", $this->_libraryFolder);
|
||||
$this->setXMLAttributValue($node, "defaultDocPosition", $this->_defaultDocPosition);
|
||||
$this->setXMLAttributValue($node, "defaultFolderPosition", $this->_defaultFolderPosition);
|
||||
|
||||
|
|
@ -1053,6 +1115,8 @@ class Settings { /* {{{ */
|
|||
$this->setXMLAttributValue($node, "luceneDir", $this->_luceneDir);
|
||||
$this->setXMLAttributValue($node, "dropFolderDir", $this->_dropFolderDir);
|
||||
$this->setXMLAttributValue($node, "backupDir", $this->_backupDir);
|
||||
$this->setXMLAttributValue($node, "checkOutDir", $this->_checkOutDir);
|
||||
$this->setXMLAttributValue($node, "createCheckOutDir", $this->_createCheckOutDir);
|
||||
$this->setXMLAttributValue($node, "repositoryUrl", $this->_repositoryUrl);
|
||||
$this->setXMLAttributValue($node, "proxyUrl", $this->_proxyUrl);
|
||||
$this->setXMLAttributValue($node, "proxyUser", $this->_proxyUser);
|
||||
|
|
@ -1066,13 +1130,12 @@ class Settings { /* {{{ */
|
|||
$this->setXMLAttributValue($node, "maxUploadSize", $this->_maxUploadSize);
|
||||
$this->setXMLAttributValue($node, "enableXsendfile", $this->_enableXsendfile);
|
||||
$this->setXMLAttributValue($node, "enableMemcached", $this->_enableMemcached);
|
||||
$this->setXMLAttributValue($node, "memcachedHost", $this->_memcachedHost);
|
||||
$this->setXMLAttributValue($node, "memcachedPort", $this->_memcachedPort);
|
||||
|
||||
// XML Path: /configuration/system/authentication
|
||||
$node = $this->getXMLNode($xml, '/configuration/system', 'authentication');
|
||||
$this->setXMLAttributValue($node, "enableGuestLogin", $this->_enableGuestLogin);
|
||||
$this->setXMLAttributValue($node, "enableGuestAutoLogin", $this->_enableGuestAutoLogin);
|
||||
$this->setXMLAttributValue($node, "enable2FactorAuthentication", $this->_enable2FactorAuthentication);
|
||||
$this->setXMLAttributValue($node, "enableLoginByEmail", $this->_enableLoginByEmail);
|
||||
$this->setXMLAttributValue($node, "enablePasswordForgotten", $this->_enablePasswordForgotten);
|
||||
$this->setXMLAttributValue($node, "passwordStrength", $this->_passwordStrength);
|
||||
|
|
@ -1184,6 +1247,13 @@ class Settings { /* {{{ */
|
|||
$this->setXMLAttributValue($node, "enableHiddenRevApp", $this->_enableHiddenRevApp);
|
||||
$this->setXMLAttributValue($node, "enableUpdateRevApp", $this->_enableUpdateRevApp);
|
||||
$this->setXMLAttributValue($node, "enableRemoveRevApp", $this->_enableRemoveRevApp);
|
||||
$this->setXMLAttributValue($node, "enableSelfReceipt", $this->_enableSelfReceipt);
|
||||
$this->setXMLAttributValue($node, "enableAdminReceipt", $this->_enableAdminReceipt);
|
||||
$this->setXMLAttributValue($node, "enableOwnerReceipt", $this->_enableOwnerReceipt);
|
||||
$this->setXMLAttributValue($node, "enableUpdateReceipt", $this->_enableUpdateReceipt);
|
||||
$this->setXMLAttributValue($node, "enableFilterReceipt", $this->_enableFilterReceipt);
|
||||
$this->setXMLAttributValue($node, "presetExpirationDate", $this->_presetExpirationDate);
|
||||
$this->setXMLAttributValue($node, "initialDocumentStatus", $this->_initialDocumentStatus);
|
||||
$this->setXMLAttributValue($node, "addManagerAsReviewer", $this->_addManagerAsReviewer);
|
||||
$this->setXMLAttributValue($node, "addManagerAsApprover", $this->_addManagerAsApprover);
|
||||
$this->setXMLAttributValue($node, "globalReviewer", implode(',', $this->_globalReviewer));
|
||||
|
|
@ -1193,14 +1263,21 @@ class Settings { /* {{{ */
|
|||
$this->setXMLAttributValue($node, "presetExpirationDate", $this->_presetExpirationDate);
|
||||
$this->setXMLAttributValue($node, "apiOrigin", $this->_apiOrigin);
|
||||
$this->setXMLAttributValue($node, "versioningFileName", $this->_versioningFileName);
|
||||
$this->setXMLAttributValue($node, "presetExpirationDate", $this->_presetExpirationDate);
|
||||
$this->setXMLAttributValue($node, "workflowMode", $this->_workflowMode);
|
||||
$this->setXMLAttributValue($node, "enableReceiptWorkflow", $this->_enableReceiptWorkflow);
|
||||
$this->setXMLAttributValue($node, "enableReceiptReject", $this->_enableReceiptReject);
|
||||
$this->setXMLAttributValue($node, "disableReceiptComment", $this->_disableReceiptComment);
|
||||
$this->setXMLAttributValue($node, "enableRevisionWorkflow", $this->_enableRevisionWorkflow);
|
||||
$this->setXMLAttributValue($node, "enableRevisionOneVoteReject", $this->_enableRevisionOneVoteReject);
|
||||
$this->setXMLAttributValue($node, "allowReviewerOnly", $this->_allowReviewerOnly);
|
||||
$this->setXMLAttributValue($node, "allowChangeRevAppInProcess", $this->_allowChangeRevAppInProcess);
|
||||
$this->setXMLAttributValue($node, "enableVersionDeletion", $this->_enableVersionDeletion);
|
||||
$this->setXMLAttributValue($node, "enableVersionModification", $this->_enableVersionModification);
|
||||
$this->setXMLAttributValue($node, "enableDuplicateDocNames", $this->_enableDuplicateDocNames);
|
||||
$this->setXMLAttributValue($node, "enableDuplicateSubFolderNames", $this->_enableDuplicateSubFolderNames);
|
||||
$this->setXMLAttributValue($node, "enableCancelCheckout", $this->_enableCancelCheckout);
|
||||
$this->setXMLAttributValue($node, "overrideMimeType", $this->_overrideMimeType);
|
||||
$this->setXMLAttributValue($node, "advancedAcl", $this->_advancedAcl);
|
||||
$this->setXMLAttributValue($node, "removeFromDropFolder", $this->_removeFromDropFolder);
|
||||
$this->setXMLAttributValue($node, "uploadedAttachmentIsPublic", $this->_uploadedAttachmentIsPublic);
|
||||
|
||||
|
|
@ -1300,7 +1377,7 @@ class Settings { /* {{{ */
|
|||
|
||||
// Save
|
||||
return $xml->asXML($configFilePath);
|
||||
} /* }}} */
|
||||
} /* }}} */
|
||||
|
||||
/**
|
||||
* search and return Config File Path
|
||||
|
|
@ -1600,14 +1677,39 @@ class Settings { /* {{{ */
|
|||
}
|
||||
if($dsn) {
|
||||
$connTmp = new PDO($dsn, $this->_dbUser, $this->_dbPass);
|
||||
$db = new SeedDMS_Core_DatabaseAccess($this->_dbDriver, $this->_dbHostname, $this->_dbUser, $this->_dbPass, $this->_dbDatabase);
|
||||
if(!$db->connect()) {
|
||||
$result["dbDatabase"] = array(
|
||||
"status" => "error",
|
||||
"type" => "error",
|
||||
"currentvalue" => '[host, user, database] -> [' . $this->_dbHostname . ',' . $this->_dbUser . ',' . $this->_dbDatabase .']',
|
||||
"systemerror" => $connTmp->ErrorMsg()
|
||||
);
|
||||
/* Check if there wasn't a previous error while searching for
|
||||
* SeedDMS_Core.
|
||||
*/
|
||||
if(!isset($result["coreDir"])) {
|
||||
/* Instanciate SeedDMS_Core to check version */
|
||||
if(!empty($this->_coreDir))
|
||||
require_once($this->_coreDir.'/Core.php');
|
||||
else
|
||||
require_once($this->_rootDir.'../pear/vendor/seeddms/core/Core.php');
|
||||
$tmpcore = new SeedDMS_Core_DMS(null, $this->_contentDir);
|
||||
$db = new SeedDMS_Core_DatabaseAccess($this->_dbDriver, $this->_dbHostname, $this->_dbUser, $this->_dbPass, $this->_dbDatabase);
|
||||
if(!$db->connect()) {
|
||||
$result["dbDatabase"] = array(
|
||||
"status" => "error",
|
||||
"type" => "error",
|
||||
"currentvalue" => '[host, user, database] -> [' . $this->_dbHostname . ',' . $this->_dbUser . ',' . $this->_dbDatabase .']',
|
||||
"systemerror" => $connTmp->ErrorMsg()
|
||||
);
|
||||
} else {
|
||||
/*
|
||||
$dms = new SeedDMS_Core_DMS($db, $this->_contentDir.$this->_contentOffsetDir);
|
||||
|
||||
if(!$dms->checkVersion()) {
|
||||
$result["dbVersion"] = array(
|
||||
"status" => "error",
|
||||
"type" => "error",
|
||||
"currentvalue" => $dms->version,
|
||||
"suggestion" => 'updateDatabase'
|
||||
);
|
||||
}
|
||||
*/
|
||||
}
|
||||
$connTmp = null;
|
||||
}
|
||||
}
|
||||
} catch(Exception $e) {
|
||||
|
|
@ -1769,13 +1871,13 @@ class Settings { /* {{{ */
|
|||
* Check if extension is disabled
|
||||
*
|
||||
* @param string $extname name of extension
|
||||
* @return true if extension is disabled or extension could not be found in configuration
|
||||
* @return true if extension is disabled
|
||||
*/
|
||||
public function extensionIsDisabled($extname) { /* {{{ */
|
||||
if(array_key_exists($extname, $this->_extensions))
|
||||
return $this->_extensions[$extname]['__disable__'];
|
||||
|
||||
return true;
|
||||
return false;
|
||||
} /* }}} */
|
||||
|
||||
/**
|
||||
|
|
@ -1819,66 +1921,5 @@ class Settings { /* {{{ */
|
|||
return min($mus);
|
||||
} /* }}} */
|
||||
|
||||
/**
|
||||
* Get base url
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getBaseUrl() { /* {{{ */
|
||||
global $_SERVER;
|
||||
|
||||
if(!empty($this->_baseUrl))
|
||||
return $this->_baseUrl;
|
||||
|
||||
if(isset($_SERVER['HTTP_X_FORWARDED_HOST']))
|
||||
$host = $_SERVER['HTTP_X_FORWARDED_HOST'];
|
||||
else
|
||||
$host = $_SERVER['HTTP_HOST'];
|
||||
if(isset($_SERVER['HTTP_X_FORWARDED_PROTO']))
|
||||
$ssl = $_SERVER['HTTP_X_FORWARDED_PROTO'] == 'https';
|
||||
else
|
||||
$ssl = (isset($_SERVER['HTTPS']) && (strcmp($_SERVER['HTTPS'],'off')!=0));
|
||||
|
||||
return "http".($ssl ? "s" : "")."://".$host;
|
||||
} /* }}} */
|
||||
|
||||
/**
|
||||
* Get base url with http root folder
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getBaseUrlWithRoot() { /* {{{ */
|
||||
return $this->getBaseUrl().$this->_httpRoot;
|
||||
} /* }}} */
|
||||
|
||||
public function getAvailableLanguages() { /* {{{ */
|
||||
$languages = array();
|
||||
|
||||
$path = $this->_rootDir . "languages/";
|
||||
$handle = opendir($path);
|
||||
|
||||
while ($entry = readdir($handle) )
|
||||
{
|
||||
if ($entry == ".." || $entry == ".") {
|
||||
continue;
|
||||
} elseif (is_dir($path . $entry)) {
|
||||
array_push($languages, $entry);
|
||||
}
|
||||
}
|
||||
closedir($handle);
|
||||
|
||||
asort($languages);
|
||||
return $languages;
|
||||
} /* }}} */
|
||||
|
||||
function getLanguages() { /* {{{ */
|
||||
if($this->_availablelanguages) {
|
||||
return $this->_availablelanguages;
|
||||
}
|
||||
|
||||
return self::getAvailableLanguages();
|
||||
} /* }}} */
|
||||
|
||||
} /* }}} */
|
||||
|
||||
class_alias('Seeddms\Seeddms\Settings', 'SeedDMS_Settings');
|
||||
|
|
|
|||
|
|
@ -1,383 +0,0 @@
|
|||
<?php
|
||||
/**
|
||||
* Translate phrase and do all language handling
|
||||
*
|
||||
* @category DMS
|
||||
* @package SeedDMS
|
||||
* @license GPL 2
|
||||
* @version @version@
|
||||
* @author Uwe Steinmann <uwe@steinmann.cx>
|
||||
* @copyright Copyright (C) 2025 Uwe Steinmann
|
||||
* @version Release: @package_version@
|
||||
*/
|
||||
|
||||
namespace Seeddms\Seeddms;
|
||||
|
||||
use SeedDMS_Core_AttributeDefinition;
|
||||
|
||||
/**
|
||||
* Class for translation and language handling
|
||||
*
|
||||
* @category DMS
|
||||
* @package SeedDMS
|
||||
* @author Uwe Steinmann <uwe@steinmann.cx>
|
||||
* @copyright Copyright (C) 2025 Uwe Steinmann
|
||||
* @version Release: @package_version@
|
||||
*/
|
||||
class Translator { /* {{{ */
|
||||
|
||||
protected $settings;
|
||||
|
||||
protected $defaultlang;
|
||||
|
||||
protected $lang;
|
||||
|
||||
protected $missinglang;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param string $settings SeedDMS configuration
|
||||
*/
|
||||
function __construct($settings=null) { /* {{{ */
|
||||
$this->settings = $settings;
|
||||
$this->defaultlang = '';
|
||||
|
||||
$this->lang = array();
|
||||
$this->missinglang = array();
|
||||
} /* }}} */
|
||||
|
||||
function setDefaultLanguage($lang) { /* {{{ */
|
||||
$this->defaultlang = $lang;
|
||||
} /* }}} */
|
||||
|
||||
public function init() { /* {{{ */
|
||||
$__languages = $this->settings->getLanguages();
|
||||
if(!in_array($this->settings->_language, $__languages))
|
||||
$__languages[] = $this->settings->_language;
|
||||
foreach($__languages as $_lang) {
|
||||
if(file_exists($this->settings->_rootDir . "languages/" . $_lang . "/lang.inc")) {
|
||||
include $this->settings->_rootDir . "languages/" . $_lang . "/lang.inc";
|
||||
$this->lang[$_lang] = $text;
|
||||
}
|
||||
}
|
||||
} /* }}} */
|
||||
|
||||
function addPhrases($lang, &$data) { /* {{{ */
|
||||
if(isset($this->lang[$lang]))
|
||||
$this->lang[$lang] = array_merge($this->lang[$lang], $data);
|
||||
else
|
||||
$this->lang[$lang] = $data;
|
||||
} /* }}} */
|
||||
|
||||
/**
|
||||
* Get translation
|
||||
*
|
||||
* Returns the translation for a given key. It will replace markers
|
||||
* in the form [xxx] with those elements from the array $replace.
|
||||
* A default text can be gіven for the case, that there is no translation
|
||||
* available. The fourth parameter can override the currently set language
|
||||
* in the session or the default language from the configuration.
|
||||
*
|
||||
* @param string $key key of translation text
|
||||
* @param array $replace list of values that replace markers in the text
|
||||
* @param string $defaulttext text used if no translation can be found
|
||||
* @param string $lang use this language instead of the currently set lang
|
||||
*/
|
||||
function translate($key, $replace = array(), $defaulttext = null, $lang="") { /* {{{ */
|
||||
$trantext = '';
|
||||
if(!$lang) {
|
||||
if($this->defaultlang)
|
||||
$lang = $this->defaultlang;
|
||||
else
|
||||
$lang = $this->settings->_language;
|
||||
}
|
||||
|
||||
if(!isset($this->lang[$lang][$key]) || !$this->lang[$lang][$key]) {
|
||||
if ($defaulttext === null) {
|
||||
$this->missinglang[$key] = $lang; //$_SERVER['SCRIPT_NAME'];
|
||||
if(!empty($this->lang[$this->settings->_language][$key])) {
|
||||
$tmpText = $this->lang[$this->settings->_language][$key];
|
||||
} else {
|
||||
$tmpText = '**'.$key.'**';
|
||||
}
|
||||
} else
|
||||
$tmpText = $defaulttext;
|
||||
} else
|
||||
$tmpText = $this->lang[$lang][$key];
|
||||
|
||||
if (count($replace) == 0)
|
||||
return $tmpText.$trantext;
|
||||
|
||||
$keys = array_keys($replace);
|
||||
foreach ($keys as $key)
|
||||
$tmpText = str_replace("[".$key."]", $replace[$key], $tmpText);
|
||||
|
||||
return $tmpText;
|
||||
} /* }}} */
|
||||
|
||||
function print($key, $replace = array(), $defaulttext = null, $lang="") { /* {{{ */
|
||||
print $this->translate($key, $replace, $defaulttext, $lang);
|
||||
} /* }}} */
|
||||
|
||||
function printReviewStatusText($status, $date=0) { /* {{{ */
|
||||
if (is_null($status)) {
|
||||
print $this->translate("status_unknown");
|
||||
}
|
||||
else {
|
||||
switch ($status) {
|
||||
case -2:
|
||||
print $this->translate("status_reviewer_removed");
|
||||
break;
|
||||
case -1:
|
||||
print $this->translate("status_reviewer_rejected").($date !=0 ? " ".$date : "");
|
||||
break;
|
||||
case 0:
|
||||
print $this->translate("status_not_reviewed");
|
||||
break;
|
||||
case 1:
|
||||
print $this->translate("status_reviewed").($date !=0 ? " ".$date : "");
|
||||
break;
|
||||
default:
|
||||
print $this->translate("status_unknown");
|
||||
break;
|
||||
}
|
||||
}
|
||||
} /* }}} */
|
||||
|
||||
function getReviewStatusText($status, $date=0) { /* {{{ */
|
||||
if (is_null($status)) {
|
||||
return $this->translate("status_unknown");
|
||||
}
|
||||
else {
|
||||
switch ($status) {
|
||||
case -2:
|
||||
return $this->translate("status_reviewer_removed");
|
||||
break;
|
||||
case -1:
|
||||
return $this->translate("status_reviewer_rejected").($date !=0 ? " ".$date : "");
|
||||
break;
|
||||
case 0:
|
||||
return $this->translate("status_not_reviewed");
|
||||
break;
|
||||
case 1:
|
||||
return $this->translate("status_reviewed").($date !=0 ? " ".$date : "");
|
||||
break;
|
||||
default:
|
||||
return $this->translate("status_unknown");
|
||||
break;
|
||||
}
|
||||
}
|
||||
} /* }}} */
|
||||
|
||||
function printApprovalStatusText($status, $date=0) { /* {{{ */
|
||||
if (is_null($status)) {
|
||||
print $this->translate("status_unknown");
|
||||
}
|
||||
else {
|
||||
switch ($status) {
|
||||
case -2:
|
||||
print $this->translate("status_approver_removed");
|
||||
break;
|
||||
case -1:
|
||||
print $this->translate("status_approval_rejected").($date !=0 ? " ".$date : "");
|
||||
break;
|
||||
case 0:
|
||||
print $this->translate("status_not_approved");
|
||||
break;
|
||||
case 1:
|
||||
print $this->translate("status_approved").($date !=0 ? " ".$date : "");
|
||||
break;
|
||||
default:
|
||||
print $this->translate("status_unknown");
|
||||
break;
|
||||
}
|
||||
}
|
||||
} /* }}} */
|
||||
|
||||
function getApprovalStatusText($status, $date=0) { /* {{{ */
|
||||
if (is_null($status)) {
|
||||
return $this->translate("status_unknown");
|
||||
}
|
||||
else {
|
||||
switch ($status) {
|
||||
case -2:
|
||||
return $this->translate("status_approver_removed");
|
||||
break;
|
||||
case -1:
|
||||
return $this->translate("status_approval_rejected").($date !=0 ? " ".$date : "");
|
||||
break;
|
||||
case 0:
|
||||
return $this->translate("status_not_approved");
|
||||
break;
|
||||
case 1:
|
||||
return $this->translate("status_approved").($date !=0 ? " ".$date : "");
|
||||
break;
|
||||
default:
|
||||
return $this->translate("status_unknown");
|
||||
break;
|
||||
}
|
||||
}
|
||||
} /* }}} */
|
||||
|
||||
function printOverallStatusText($status) { /* {{{ */
|
||||
print getOverallStatusText($status);
|
||||
} /* }}} */
|
||||
|
||||
function getOverallStatusText($status) { /* {{{ */
|
||||
if (is_null($status)) {
|
||||
return $this->translate("assumed_released");
|
||||
}
|
||||
else {
|
||||
switch($status) {
|
||||
case S_IN_WORKFLOW:
|
||||
return $this->translate("in_workflow");
|
||||
break;
|
||||
case S_DRAFT_REV:
|
||||
return $this->translate("draft_pending_review");
|
||||
break;
|
||||
case S_DRAFT_APP:
|
||||
return $this->translate("draft_pending_approval");
|
||||
break;
|
||||
case S_RELEASED:
|
||||
return $this->translate("released");
|
||||
break;
|
||||
case S_REJECTED:
|
||||
return $this->translate("rejected");
|
||||
break;
|
||||
case S_OBSOLETE:
|
||||
return $this->translate("obsolete");
|
||||
break;
|
||||
case S_EXPIRED:
|
||||
return $this->translate("expired");
|
||||
break;
|
||||
default:
|
||||
return $this->translate("status_unknown");
|
||||
break;
|
||||
}
|
||||
}
|
||||
} /* }}} */
|
||||
|
||||
function getAttributeTypeText($attrdef) { /* {{{ */
|
||||
$t = '';
|
||||
switch($attrdef->getType()) {
|
||||
case SeedDMS_Core_AttributeDefinition::type_int:
|
||||
$t = $this->translate("attrdef_type_int");
|
||||
break;
|
||||
case SeedDMS_Core_AttributeDefinition::type_float:
|
||||
$t = $this->translate("attrdef_type_float");
|
||||
break;
|
||||
case SeedDMS_Core_AttributeDefinition::type_string:
|
||||
$t = $this->translate("attrdef_type_string");
|
||||
break;
|
||||
case SeedDMS_Core_AttributeDefinition::type_boolean:
|
||||
$t = $this->translate("attrdef_type_boolean");
|
||||
break;
|
||||
case SeedDMS_Core_AttributeDefinition::type_date:
|
||||
$t = $this->translate("attrdef_type_date");
|
||||
break;
|
||||
case SeedDMS_Core_AttributeDefinition::type_email:
|
||||
$t = $this->translate("attrdef_type_email");
|
||||
break;
|
||||
case SeedDMS_Core_AttributeDefinition::type_url:
|
||||
$t = $this->translate("attrdef_type_url");
|
||||
break;
|
||||
case SeedDMS_Core_AttributeDefinition::type_boolean:
|
||||
$t = $this->translate("attrdef_type_boolean");
|
||||
break;
|
||||
case SeedDMS_Core_AttributeDefinition::type_folder:
|
||||
$t = $this->translate("attrdef_type_folder");
|
||||
break;
|
||||
case SeedDMS_Core_AttributeDefinition::type_document:
|
||||
$t = $this->translate("attrdef_type_document");
|
||||
break;
|
||||
case SeedDMS_Core_AttributeDefinition::type_user:
|
||||
$t = $this->translate("attrdef_type_user");
|
||||
break;
|
||||
case SeedDMS_Core_AttributeDefinition::type_group:
|
||||
$t = $this->translate("attrdef_type_group");
|
||||
break;
|
||||
}
|
||||
return $t;
|
||||
} /* }}} */
|
||||
|
||||
function getAttributeObjectTypeText($attrdef) { /* {{{ */
|
||||
$ot = '';
|
||||
switch($attrdef->getObjType()) {
|
||||
case SeedDMS_Core_AttributeDefinition::objtype_all:
|
||||
$ot = $this->translate("all");
|
||||
break;
|
||||
case SeedDMS_Core_AttributeDefinition::objtype_folder:
|
||||
$ot = $this->translate("folder");
|
||||
break;
|
||||
case SeedDMS_Core_AttributeDefinition::objtype_document:
|
||||
$ot = $this->translate("document");
|
||||
break;
|
||||
case SeedDMS_Core_AttributeDefinition::objtype_documentcontent:
|
||||
$ot = $this->translate("documentcontent");
|
||||
break;
|
||||
default:
|
||||
$ot = $this->translate('objtype_unknown');
|
||||
}
|
||||
return $ot;
|
||||
} /* }}} */
|
||||
|
||||
function getAttributeValidationText($error, $attrname='', $attrvalue='', $regex='') { /* {{{ */
|
||||
$arr = getAttributeValidationError($error, $attrname, $attrvalue, $regex);
|
||||
|
||||
return $this->translate($arr[0], $arr[1]);
|
||||
} /* }}} */
|
||||
|
||||
function getAttributeValidationError($error, $attrname='', $attrvalue='', $regex='') { /* {{{ */
|
||||
if(is_object($attrvalue))
|
||||
$attrvalue = $attrvalue->getId();
|
||||
switch($error) {
|
||||
case 14:
|
||||
return array("attr_not_in_valueset", array('attrname'=>$attrname, 'value'=>$attrvalue));
|
||||
break;
|
||||
case 13:
|
||||
return array("attr_not_a_group", array('attrname'=>$attrname, 'value'=>$attrvalue));
|
||||
break;
|
||||
case 12:
|
||||
return array("attr_not_a_user", array('attrname'=>$attrname, 'value'=>$attrvalue));
|
||||
break;
|
||||
case 11:
|
||||
return array("attr_not_a_folder", array('attrname'=>$attrname, 'value'=>$attrvalue));
|
||||
break;
|
||||
case 10:
|
||||
return array("attr_not_a_document", array('attrname'=>$attrname, 'value'=>$attrvalue));
|
||||
break;
|
||||
case 9:
|
||||
return array("attr_malformed_date", array('attrname'=>$attrname, 'value'=>$attrvalue));
|
||||
break;
|
||||
case 8:
|
||||
return array("attr_malformed_boolean", array('attrname'=>$attrname, 'value'=>$attrvalue));
|
||||
break;
|
||||
case 7:
|
||||
return array("attr_malformed_float", array('attrname'=>$attrname, 'value'=>$attrvalue));
|
||||
break;
|
||||
case 6:
|
||||
return array("attr_malformed_int", array('attrname'=>$attrname, 'value'=>$attrvalue));
|
||||
break;
|
||||
case 5:
|
||||
return array("attr_malformed_email", array('attrname'=>$attrname, 'value'=>$attrvalue));
|
||||
break;
|
||||
case 4:
|
||||
return array("attr_malformed_url", array('attrname'=>$attrname, 'value'=>$attrvalue));
|
||||
break;
|
||||
case 3:
|
||||
return array("attr_no_regex_match", array('attrname'=>$attrname, 'value'=>$attrvalue, 'regex'=>$regex));
|
||||
break;
|
||||
case 2:
|
||||
return array("attr_max_values", array('attrname'=>$attrname, 'value'=>$attrvalue));
|
||||
break;
|
||||
case 1:
|
||||
return array("attr_min_values", array('attrname'=>$attrname, 'value'=>$attrvalue));
|
||||
break;
|
||||
default:
|
||||
return array("attr_validation_error", array('attrname'=>$attrname, 'value'=>$attrvalue));
|
||||
break;
|
||||
}
|
||||
} /* }}} */
|
||||
|
||||
} /* }}} */
|
||||
|
|
@ -20,6 +20,7 @@
|
|||
|
||||
require_once('inc.ClassUI_Default.php');
|
||||
require_once('inc.ClassViewCommon.php');
|
||||
require_once('inc.ClassAccessOperation.php');
|
||||
|
||||
/* $theme was possibly set in inc.Authentication.php */
|
||||
if (!isset($theme) || strlen($theme)==0) {
|
||||
|
|
@ -45,12 +46,7 @@ class UI extends UI_Default {
|
|||
* @return object an object of a class implementing the view
|
||||
*/
|
||||
static public function factory($theme, $class='', $params=array()) { /* {{{ */
|
||||
foreach(['settings', 'dms', 'user', 'session', 'extmgr', 'request', 'logger', 'notifier', 'fulltextservice', 'translator'] as $vn) {
|
||||
if(isset($params[$vn]))
|
||||
${$vn} = $params[$vn];
|
||||
else
|
||||
${$vn} = $GLOBALS[$vn] ?? null;
|
||||
}
|
||||
global $settings, $dms, $user, $session, $extMgr, $request, $logger, $notifier, $fulltextservice;
|
||||
if(!$class) {
|
||||
$class = 'Bootstrap';
|
||||
$class = 'Style';
|
||||
|
|
@ -60,9 +56,9 @@ class UI extends UI_Default {
|
|||
}
|
||||
/* Collect all decorators */
|
||||
$decorators = array();
|
||||
foreach($extmgr->getExtensionConfiguration() as $extname=>$extconf) {
|
||||
foreach($extMgr->getExtensionConfiguration() as $extname=>$extconf) {
|
||||
if(!$settings->extensionIsDisabled($extname)) {
|
||||
if($extmgr->checkExtensionByName($extname, $extconf)) {
|
||||
if($extMgr->checkExtensionByName($extname, $extconf)) {
|
||||
if(isset($extconf['decorators'][$class])) {
|
||||
$filename = $settings->_rootDir.'ext/'.$extname.'/decorators/'.$theme."/".$extconf['decorators'][$class]['file'];
|
||||
if(file_exists($filename)) {
|
||||
|
|
@ -77,9 +73,9 @@ class UI extends UI_Default {
|
|||
*/
|
||||
$filename = '';
|
||||
$httpbasedir = '';
|
||||
foreach($extmgr->getExtensionConfiguration() as $extname=>$extconf) {
|
||||
foreach($extMgr->getExtensionConfiguration() as $extname=>$extconf) {
|
||||
if(!$settings->extensionIsDisabled($extname)) {
|
||||
if($extmgr->checkExtensionByName($extname, $extconf)) {
|
||||
if($extMgr->checkExtensionByName($extname, $extconf)) {
|
||||
/* Setting the 'views' element in the configuration can be used to
|
||||
* replace an existing view in views/bootstrap/, e.g. class.ViewFolder.php
|
||||
* without providing an out/out.ViewFolder.php. In that case $httpbasedir
|
||||
|
|
@ -132,6 +128,7 @@ class UI extends UI_Default {
|
|||
$params['settings'] = $settings;
|
||||
$view = new $classname($params, $theme);
|
||||
/* Set some configuration parameters */
|
||||
$view->setParam('accessobject', new SeedDMS_AccessOperation($dms, $user, $settings));
|
||||
$view->setParam('referer', isset($_SERVER['HTTP_REFERER']) ? $_SERVER['HTTP_REFERER'] : '');
|
||||
$view->setParam('requesturi', $_SERVER['REQUEST_URI']);
|
||||
$view->setParam('absbaseprefix', $settings->_httpRoot.$httpbasedir);
|
||||
|
|
@ -142,7 +139,6 @@ class UI extends UI_Default {
|
|||
$view->setParam('logger', $logger);
|
||||
$view->setParam('notifier', $notifier);
|
||||
$view->setParam('fulltextservice', $fulltextservice);
|
||||
$view->setParam('translator', $translator);
|
||||
// $view->setParam('settings', $settings);
|
||||
$view->setParam('sitename', $settings->_siteName);
|
||||
$view->setParam('rootfolderid', $settings->_rootFolderID);
|
||||
|
|
@ -160,11 +156,14 @@ class UI extends UI_Default {
|
|||
$view->setParam('enablefoldertree', $settings->_enableFolderTree);
|
||||
$view->setParam('enablelanguageselector', $settings->_enableLanguageSelector);
|
||||
$view->setParam('enableclipboard', $settings->_enableClipboard);
|
||||
$view->setParam('enablemenutransmittals', $settings->_enableMenuTransmittals);
|
||||
$view->setParam('enablemenutasks', $settings->_enableMenuTasks);
|
||||
$view->setParam('tasksinmenu', $settings->_tasksInMenu);
|
||||
$view->setParam('enabledropfolderlist', $settings->_enableDropFolderList);
|
||||
$view->setParam('dropfolderdir', $settings->_dropFolderDir);
|
||||
$view->setParam('enablesessionlist', $settings->_enableSessionList);
|
||||
$view->setParam('workflowmode', $settings->_workflowMode);
|
||||
$view->setParam('checkoutdir', $settings->_checkOutDir);
|
||||
$view->setParam('partitionsize', SeedDMS_Core_File::parse_filesize( $settings->_partitionSize));
|
||||
$view->setParam('maxuploadsize', $settings->getMaximumUploadSize());
|
||||
$view->setParam('showmissingtranslations', $settings->_showMissingTranslations);
|
||||
|
|
@ -200,7 +199,6 @@ class UI extends UI_Default {
|
|||
|
||||
static public function exitError($pagetitle, $error, $noexit=false, $plain=false) {
|
||||
global $theme, $dms, $user, $settings;
|
||||
$accessop = new SeedDMS_AccessOperation($dms, null, $user, $settings);
|
||||
$view = UI::factory($theme, 'ErrorDlg');
|
||||
$request = $view->getParam('request');
|
||||
if($request) {
|
||||
|
|
@ -208,7 +206,6 @@ class UI extends UI_Default {
|
|||
}
|
||||
$view->setParam('dms', $dms);
|
||||
$view->setParam('user', $user);
|
||||
$view->setParam('accessobject', $accessop);
|
||||
$view->setParam('pagetitle', $pagetitle);
|
||||
$view->setParam('errormsg', $error);
|
||||
$view->setParam('plain', $plain);
|
||||
|
|
|
|||
|
|
@ -1,95 +0,0 @@
|
|||
<?php
|
||||
/**
|
||||
* Various utility functions
|
||||
*
|
||||
* @category DMS
|
||||
* @package SeedDMS
|
||||
* @license GPL 2
|
||||
* @version @version@
|
||||
* @author Uwe Steinmann <uwe@steinmann.cx>
|
||||
* @copyright Copyright (C) 2025 Uwe Steinmann
|
||||
* @version Release: @package_version@
|
||||
*/
|
||||
|
||||
namespace Seeddms\Seeddms;
|
||||
|
||||
/**
|
||||
* Class with various methods
|
||||
*
|
||||
* @category DMS
|
||||
* @package SeedDMS
|
||||
* @author Uwe Steinmann <uwe@steinmann.cx>
|
||||
* @copyright Copyright (C) 2025 Uwe Steinmann
|
||||
* @version Release: @package_version@
|
||||
*/
|
||||
class Utilities { /* {{{ */
|
||||
|
||||
/**
|
||||
* Recursively remove a directory on disc
|
||||
*
|
||||
* @param string $dir name of directory
|
||||
*/
|
||||
static public function rrmdir($dir) { /* {{{ */
|
||||
if (is_dir($dir)) {
|
||||
$objects = scandir($dir);
|
||||
foreach ($objects as $object) {
|
||||
if ($object != "." && $object != "..") {
|
||||
if (filetype($dir."/".$object) == "dir") self::rrmdir($dir."/".$object); else unlink($dir."/".$object);
|
||||
}
|
||||
}
|
||||
reset($objects);
|
||||
rmdir($dir);
|
||||
}
|
||||
} /* }}} */
|
||||
|
||||
/**
|
||||
* Create a random string
|
||||
*
|
||||
* @param integer $n number of chars
|
||||
* @param string $alph alphabet used as source for chars
|
||||
* @return string random string
|
||||
*/
|
||||
static public function makeRandomString($n, $alph = "0123456789abcdefghijklmnopqrstuvwxyz") { /* {{{ */
|
||||
$len = strlen($alph)-1;
|
||||
$s = "";
|
||||
for ($i = 0; $i != $n; ++$i)
|
||||
$s .= $alph[mt_rand(0, $len)];
|
||||
return $s;
|
||||
} /* }}} */
|
||||
|
||||
/**
|
||||
* Create a real uniqid for cryptographic purposes
|
||||
*
|
||||
* @ return string
|
||||
*/
|
||||
static public function uniqidReal($lenght = 13) { /* {{{ */
|
||||
// uniqid gives 13 chars, but you could adjust it to your needs.
|
||||
if (function_exists("random_bytes")) {
|
||||
$bytes = random_bytes(ceil($lenght / 2));
|
||||
} elseif (function_exists("openssl_random_pseudo_bytes")) {
|
||||
$bytes = openssl_random_pseudo_bytes(ceil($lenght / 2));
|
||||
} else {
|
||||
throw new Exception("no cryptographically secure random function available");
|
||||
}
|
||||
return substr(bin2hex($bytes), 0, $lenght);
|
||||
} /* }}} */
|
||||
|
||||
/**
|
||||
* Return nonce for CSP
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
static public function createNonce() { /* {{{ */
|
||||
$length = 16;
|
||||
$usable = true;
|
||||
$bytes = openssl_random_pseudo_bytes($length, $usable);
|
||||
if ($usable === false) {
|
||||
// weak
|
||||
// @TODO do something?
|
||||
}
|
||||
return base64_encode($bytes);
|
||||
} /* }}} */
|
||||
|
||||
} /* }}} */
|
||||
|
||||
class_alias('Seeddms\Seeddms\Utilities', 'SeedDMS_Utils');
|
||||
|
|
@ -213,7 +213,7 @@ class SeedDMS_View_Common {
|
|||
if(is_string($tmpret)) {
|
||||
$ret = ($ret === null) ? $tmpret : (is_string($ret) ? $ret.$tmpret : array_merge($ret, array($tmpret)));
|
||||
} elseif(is_array($tmpret) || is_object($tmpret)) {
|
||||
$ret = ($ret === null) ? $tmpret : (is_string($ret) ? (array($ret) + $tmpret) : ($ret + $tmpret));
|
||||
$ret = ($ret === null) ? $tmpret : (is_string($ret) ? array_merge(array($ret), $tmpret) : array_merge($ret, $tmpret));
|
||||
} else
|
||||
$ret = $tmpret;
|
||||
}
|
||||
|
|
@ -322,8 +322,10 @@ class SeedDMS_View_Common {
|
|||
*/
|
||||
protected function html_url($view, $urlparams=array()) { /* {{{ */
|
||||
$url = $this->params['settings']->_httpRoot."out/out.".$view.".php";
|
||||
if($urlparams)
|
||||
if(is_array($urlparams))
|
||||
$url .= "?".http_build_query($urlparams);
|
||||
elseif(is_string($urlparams))
|
||||
$url .= "?".$urlparams;
|
||||
return $url;
|
||||
} /* }}} */
|
||||
|
||||
|
|
|
|||
|
|
@ -56,14 +56,12 @@ if(isset($GLOBALS['SEEDDMS_HOOKS']['initStorage'])) {
|
|||
|
||||
$dms = new SeedDMS_Core_DMS($db, $storage ? $storage : $settings->_contentDir.$settings->_contentOffsetDir);
|
||||
|
||||
$memcache = null;
|
||||
if($settings->_enableMemcached && extension_loaded('memcached')) {
|
||||
$mc = new Memcached('seeddms');
|
||||
$mc->addServers(array(
|
||||
array($settings->_memcachedHost ?? 'localhost', $settings->_memcachedPort ?? 11211),
|
||||
$memcache = new Memcached('seeddms');
|
||||
$memcache->addServers(array(
|
||||
array('localhost',11211),
|
||||
));
|
||||
$memcache = new \Cache\Adapter\Memcached\MemcachedCachePool($mc);
|
||||
$dms->setCache($memcache);
|
||||
$dms->setMemcache($memcache);
|
||||
}
|
||||
|
||||
if(!$settings->_doNotCheckDBVersion && !$dms->checkVersion()) {
|
||||
|
|
@ -89,8 +87,11 @@ if(isset($GLOBALS['SEEDDMS_HOOKS']['initDMS'])) {
|
|||
}
|
||||
}
|
||||
|
||||
require_once('inc/inc.Tasks.php');
|
||||
require_once("inc.ConversionInit.php");
|
||||
require_once('inc.FulltextInit.php');
|
||||
require_once('inc.AuthenticationInit.php');
|
||||
require_once("inc.ClassNotificationService.php");
|
||||
require_once("inc.ClassEmailNotify.php");
|
||||
require_once('inc.Notification.php');
|
||||
|
||||
|
|
|
|||
|
|
@ -11,36 +11,35 @@
|
|||
* @version Release: @package_version@
|
||||
*/
|
||||
|
||||
require_once "inc.ClassExtensionMgr.php";
|
||||
global $logger;
|
||||
|
||||
require "inc.ClassExtensionMgr.php";
|
||||
require_once "inc.ClassSchedulerTaskBase.php";
|
||||
require_once "inc.ClassExtBase.php";
|
||||
|
||||
// Do not set a namespace until all extensions use that namespace
|
||||
// or set the class name in the conf file to '\xxxx'
|
||||
//namespace Seeddms\Seeddms;
|
||||
$extMgr = new SeedDMS_Extension_Mgr($settings->_rootDir."/ext", $settings->_cacheDir, $settings->_repositoryUrl, $settings->_proxyUrl, $settings->_proxyUser, $settings->_proxyPassword);
|
||||
|
||||
use Seeddms\Seeddms\ExtensionMgr;
|
||||
$version = new SeedDMS_Version;
|
||||
|
||||
class_alias('Seeddms\Seeddms\ExtensionMgr', 'SeedDMS_Extension_Mgr');
|
||||
/* Declare an alias as long as it used by extensions */
|
||||
class_alias('Seeddms\Seeddms\ExtensionBase', 'SeedDMS_ExtBase');
|
||||
|
||||
$extmgr = new ExtensionMgr($settings->_rootDir."/ext", $settings->_cacheDir, $settings->_repositoryUrl, $settings->_proxyUrl, $settings->_proxyUser, $settings->_proxyPassword);
|
||||
|
||||
foreach($extmgr->getExtensionConfiguration() as $extname=>$extconf) {
|
||||
if($extconf['disable']) {
|
||||
$settings->disableExtension($extname);
|
||||
continue;
|
||||
}
|
||||
foreach($extMgr->getExtensionConfiguration() as $extname=>$extconf) {
|
||||
if(!$settings->extensionIsDisabled($extname)) {
|
||||
$disabled = false;
|
||||
if($extmgr->checkExtensionByName($extname, $extconf)) {
|
||||
$disabled = true;
|
||||
if($extMgr->checkExtensionByName($extname, $extconf)) {
|
||||
$disabled = false;
|
||||
$settings->enableExtension($extname);
|
||||
} else {
|
||||
$disabled = true;
|
||||
$settings->disableExtension($extname);
|
||||
// echo $extmgr->getErrorMsg();
|
||||
// echo $extMgr->getErrorMsg();
|
||||
}
|
||||
/* check for requirements */
|
||||
/*
|
||||
if(!empty($extconf['constraints']['depends']['seeddms'])) {
|
||||
$t = explode('-', $extconf['constraints']['depends']['seeddms'], 2);
|
||||
if(SeedDMS_Extension_Mgr::cmpVersion($t[0], $version->version()) > 0 || ($t[1] && SeedDMS_Extension_Mgr::cmpVersion($t[1], $version->version()) < 0))
|
||||
$disabled = true;
|
||||
else
|
||||
$disabled = false;
|
||||
}
|
||||
*/
|
||||
if(!$disabled) {
|
||||
if(isset($extconf['class']) && isset($extconf['class']['file']) && isset($extconf['class']['name'])) {
|
||||
$classfile = $settings->_rootDir."/ext/".$extname."/".$extconf['class']['file'];
|
||||
|
|
@ -48,7 +47,7 @@ foreach($extmgr->getExtensionConfiguration() as $extname=>$extconf) {
|
|||
include($classfile);
|
||||
$obj = new $extconf['class']['name']($settings, null, $logger);
|
||||
if(method_exists($obj, 'init'))
|
||||
$obj->init($extmgr);
|
||||
$obj->init($extMgr);
|
||||
}
|
||||
}
|
||||
if(isset($extconf['language']['file'])) {
|
||||
|
|
@ -58,15 +57,14 @@ foreach($extmgr->getExtensionConfiguration() as $extname=>$extconf) {
|
|||
include($langfile);
|
||||
if(isset($__lang) && $__lang) {
|
||||
foreach($__lang as $lang=>&$data) {
|
||||
$translator->addPhrases($lang, $data);
|
||||
if(isset($GLOBALS['LANG'][$lang]))
|
||||
$GLOBALS['LANG'][$lang] = array_merge($GLOBALS['LANG'][$lang], $data);
|
||||
else
|
||||
$GLOBALS['LANG'][$lang] = $data;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Ensure $settings->_extensions has an entry for the extension, even if
|
||||
// the extension is disabled already.
|
||||
$settings->disableExtension($extname);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -26,6 +26,7 @@ $fulltextservice = null;
|
|||
if($settings->_enableFullSearch) {
|
||||
require_once("inc.ClassFulltextService.php");
|
||||
$fulltextservice = new SeedDMS_FulltextService();
|
||||
$fulltextservice->setLogger($logger);
|
||||
|
||||
if($settings->_fullSearchEngine == 'sqlitefts') {
|
||||
$indexconf = array(
|
||||
|
|
|
|||
|
|
@ -18,31 +18,48 @@
|
|||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
use Seeddms\Seeddms\Translator;
|
||||
|
||||
$translator = new Translator($settings);
|
||||
$translator->init();
|
||||
|
||||
/* All remaining functions in this file are deprecated and should
|
||||
* not be used anymore. Use instead the equivalent methods in class
|
||||
* Translator;
|
||||
*/
|
||||
function getAvailableLanguages() { /* {{{ */
|
||||
trigger_error("getAvailableLanguages() is deprecated.", E_USER_DEPRECATED);
|
||||
foreach(debug_backtrace() as $n) {
|
||||
trigger_error($n['file'].": Line ".$n['line'], E_USER_DEPRECATED);
|
||||
$LANG = array();
|
||||
$MISSING_LANG = array();
|
||||
$__languages = getLanguages();
|
||||
if(!in_array($settings->_language, $__languages))
|
||||
$__languages[] = $settings->_language;
|
||||
foreach($__languages as $_lang) {
|
||||
if(file_exists($settings->_rootDir . "languages/" . $_lang . "/lang.inc")) {
|
||||
include $settings->_rootDir . "languages/" . $_lang . "/lang.inc";
|
||||
$LANG[$_lang] = $text;
|
||||
}
|
||||
}
|
||||
unset($text);
|
||||
|
||||
return $GLOBALS['settings']->getAvailableLanguages();
|
||||
function getAvailableLanguages() { /* {{{ */
|
||||
global $settings;
|
||||
|
||||
$languages = array();
|
||||
|
||||
$path = $settings->_rootDir . "languages/";
|
||||
$handle = opendir($path);
|
||||
|
||||
while ($entry = readdir($handle) )
|
||||
{
|
||||
if ($entry == ".." || $entry == ".")
|
||||
continue;
|
||||
else if (is_dir($path . $entry))
|
||||
array_push($languages, $entry);
|
||||
}
|
||||
closedir($handle);
|
||||
|
||||
asort($languages);
|
||||
return $languages;
|
||||
} /* }}} */
|
||||
|
||||
function getLanguages() { /* {{{ */
|
||||
trigger_error("getLanguages() is deprecated.", E_USER_DEPRECATED);
|
||||
foreach(debug_backtrace() as $n) {
|
||||
trigger_error($n['file'].": Line ".$n['line'], E_USER_DEPRECATED);
|
||||
global $settings;
|
||||
|
||||
if($settings->_availablelanguages) {
|
||||
return $settings->_availablelanguages;
|
||||
}
|
||||
|
||||
return $GLOBALS['settings']->getLanguages();
|
||||
return getAvailableLanguages();
|
||||
} /* }}} */
|
||||
|
||||
/**
|
||||
|
|
@ -60,56 +77,381 @@ function getLanguages() { /* {{{ */
|
|||
* @param string $lang use this language instead of the currently set lang
|
||||
*/
|
||||
function getMLText($key, $replace = array(), $defaulttext = null, $lang="") { /* {{{ */
|
||||
// trigger_error("getMLText() is deprecated.", E_USER_DEPRECATED);
|
||||
// foreach(debug_backtrace() as $n) {
|
||||
// trigger_error($n['file'].": Line ".$n['line'], E_USER_DEPRECATED);
|
||||
// }
|
||||
GLOBAL $settings, $LANG, $session, $MISSING_LANG;
|
||||
|
||||
return $GLOBALS['translator']->translate($key, $replace, $defaulttext, $lang);
|
||||
$trantext = '';
|
||||
if(0 && $settings->_otrance) {
|
||||
$trantext = '<form style="display: inline-block;" accept-charset="UTF-8" action="http://translate.seeddms.org/connector/index" target="_blank" method="post"><input type="hidden" value="" name="oTranceKeys['.$key.']"><input type="submit" value="submit" class="btn btn-mini"/></form>';
|
||||
}
|
||||
|
||||
if(!$lang) {
|
||||
if($session)
|
||||
$lang = $session->getLanguage();
|
||||
else
|
||||
$lang = $settings->_language;
|
||||
}
|
||||
|
||||
if(!isset($LANG[$lang][$key]) || !$LANG[$lang][$key]) {
|
||||
if ($defaulttext === null) {
|
||||
$MISSING_LANG[$key] = $lang; //$_SERVER['SCRIPT_NAME'];
|
||||
if(!empty($LANG[$settings->_language][$key])) {
|
||||
$tmpText = $LANG[$settings->_language][$key];
|
||||
} else {
|
||||
$tmpText = '**'.$key.'**';
|
||||
}
|
||||
} else
|
||||
$tmpText = $defaulttext;
|
||||
} else
|
||||
$tmpText = $LANG[$lang][$key];
|
||||
|
||||
if(0 && $settings->_otrance) {
|
||||
$_GLOBALS['used_langs'][$key] = $tmpText;
|
||||
}
|
||||
|
||||
if (count($replace) == 0)
|
||||
return $tmpText.$trantext;
|
||||
|
||||
$keys = array_keys($replace);
|
||||
foreach ($keys as $key)
|
||||
$tmpText = str_replace("[".$key."]", $replace[$key], $tmpText);
|
||||
|
||||
return $tmpText;
|
||||
} /* }}} */
|
||||
|
||||
function printMLText($key, $replace = array(), $defaulttext = null, $lang="") { /* {{{ */
|
||||
$GLOBALS['translator']->print($key, $replace, $defaulttext, $lang);
|
||||
function printMLText($key, $replace = array(), $defaulttext = null, $lang="") /* {{{ */
|
||||
{
|
||||
print getMLText($key, $replace, $defaulttext, $lang);
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
function printReviewStatusText($status, $date=0) { /* {{{ */
|
||||
$GLOBALS['translator']->printReviewStatusText($status, $date);
|
||||
if (is_null($status)) {
|
||||
print getMLText("status_unknown");
|
||||
}
|
||||
else {
|
||||
switch ($status) {
|
||||
case -2:
|
||||
print getMLText("status_reviewer_removed");
|
||||
break;
|
||||
case -1:
|
||||
print getMLText("status_reviewer_rejected").($date !=0 ? " ".$date : "");
|
||||
break;
|
||||
case 0:
|
||||
print getMLText("status_not_reviewed");
|
||||
break;
|
||||
case 1:
|
||||
print getMLText("status_reviewed").($date !=0 ? " ".$date : "");
|
||||
break;
|
||||
default:
|
||||
print getMLText("status_unknown");
|
||||
break;
|
||||
}
|
||||
}
|
||||
} /* }}} */
|
||||
|
||||
function getReviewStatusText($status, $date=0) { /* {{{ */
|
||||
return $GLOBALS['translator']->getReviewStatusText($status, $date);
|
||||
if (is_null($status)) {
|
||||
return getMLText("status_unknown");
|
||||
}
|
||||
else {
|
||||
switch ($status) {
|
||||
case -2:
|
||||
return getMLText("status_reviewer_removed");
|
||||
break;
|
||||
case -1:
|
||||
return getMLText("status_reviewer_rejected").($date !=0 ? " ".$date : "");
|
||||
break;
|
||||
case 0:
|
||||
return getMLText("status_not_reviewed");
|
||||
break;
|
||||
case 1:
|
||||
return getMLText("status_reviewed").($date !=0 ? " ".$date : "");
|
||||
break;
|
||||
default:
|
||||
return getMLText("status_unknown");
|
||||
break;
|
||||
}
|
||||
}
|
||||
} /* }}} */
|
||||
|
||||
function printReceiptStatusText($status, $date=0) { /* {{{ */
|
||||
print getReceiptStatusText($status, $date);
|
||||
} /* }}} */
|
||||
|
||||
function getReceiptStatusText($status, $date=0) { /* {{{ */
|
||||
if (is_null($status)) {
|
||||
return getMLText("status_unknown");
|
||||
}
|
||||
else {
|
||||
switch ($status) {
|
||||
case -2:
|
||||
return getMLText("status_recipient_removed");
|
||||
break;
|
||||
case -1:
|
||||
return getMLText("status_receipt_rejected").($date !=0 ? " ".$date : "");
|
||||
break;
|
||||
case 0:
|
||||
return getMLText("status_not_receipted");
|
||||
break;
|
||||
case 1:
|
||||
return getMLText("status_receipted").($date !=0 ? " ".$date : "");
|
||||
break;
|
||||
default:
|
||||
return getMLText("status_unknown");
|
||||
break;
|
||||
}
|
||||
}
|
||||
} /* }}} */
|
||||
|
||||
function printRevisionStatusText($status, $date=0) { /* {{{ */
|
||||
print getRevisionStatusText($status, $date);
|
||||
} /* }}} */
|
||||
|
||||
function getRevisionStatusText($status, $date=0) { /* {{{ */
|
||||
if (is_null($status)) {
|
||||
return getMLText("status_unknown");
|
||||
}
|
||||
else {
|
||||
switch ($status) {
|
||||
case -3:
|
||||
return getMLText("status_revision_sleeping");
|
||||
break;
|
||||
case -2:
|
||||
return getMLText("status_revisor_removed");
|
||||
break;
|
||||
case -1:
|
||||
return getMLText("status_needs_correction").($date !=0 ? " ".$date : "");
|
||||
return getMLText("status_revision_rejected").($date !=0 ? " ".$date : "");
|
||||
break;
|
||||
case 0:
|
||||
return getMLText("status_not_revised");
|
||||
break;
|
||||
case 1:
|
||||
return getMLText("status_revised").($date !=0 ? " ".$date : "");
|
||||
break;
|
||||
default:
|
||||
return getMLText("status_unknown");
|
||||
break;
|
||||
}
|
||||
}
|
||||
} /* }}} */
|
||||
|
||||
function printApprovalStatusText($status, $date=0) { /* {{{ */
|
||||
$GLOBALS['translator']->printApprovalStatusText($status, $date);
|
||||
if (is_null($status)) {
|
||||
print getMLText("status_unknown");
|
||||
}
|
||||
else {
|
||||
switch ($status) {
|
||||
case -2:
|
||||
print getMLText("status_approver_removed");
|
||||
break;
|
||||
case -1:
|
||||
print getMLText("status_approval_rejected").($date !=0 ? " ".$date : "");
|
||||
break;
|
||||
case 0:
|
||||
print getMLText("status_not_approved");
|
||||
break;
|
||||
case 1:
|
||||
print getMLText("status_approved").($date !=0 ? " ".$date : "");
|
||||
break;
|
||||
default:
|
||||
print getMLText("status_unknown");
|
||||
break;
|
||||
}
|
||||
}
|
||||
} /* }}} */
|
||||
|
||||
function getApprovalStatusText($status, $date=0) { /* {{{ */
|
||||
return $GLOBALS['translator']->getApprovalStatusText($status, $date);
|
||||
if (is_null($status)) {
|
||||
return getMLText("status_unknown");
|
||||
}
|
||||
else {
|
||||
switch ($status) {
|
||||
case -2:
|
||||
return getMLText("status_approver_removed");
|
||||
break;
|
||||
case -1:
|
||||
return getMLText("status_approval_rejected").($date !=0 ? " ".$date : "");
|
||||
break;
|
||||
case 0:
|
||||
return getMLText("status_not_approved");
|
||||
break;
|
||||
case 1:
|
||||
return getMLText("status_approved").($date !=0 ? " ".$date : "");
|
||||
break;
|
||||
default:
|
||||
return getMLText("status_unknown");
|
||||
break;
|
||||
}
|
||||
}
|
||||
} /* }}} */
|
||||
|
||||
function printOverallStatusText($status) { /* {{{ */
|
||||
$GLOBALS['translator']->printOverallStatusText($status);
|
||||
print getOverallStatusText($status);
|
||||
} /* }}} */
|
||||
|
||||
function getOverallStatusText($status) { /* {{{ */
|
||||
return $GLOBALS['translator']->getOverallStatusText($status);
|
||||
if (is_null($status)) {
|
||||
return getMLText("assumed_released");
|
||||
}
|
||||
else {
|
||||
switch($status) {
|
||||
case S_IN_WORKFLOW:
|
||||
return getMLText("in_workflow");
|
||||
break;
|
||||
case S_DRAFT_REV:
|
||||
return getMLText("draft_pending_review");
|
||||
break;
|
||||
case S_DRAFT_APP:
|
||||
return getMLText("draft_pending_approval");
|
||||
break;
|
||||
case S_RELEASED:
|
||||
return getMLText("released");
|
||||
break;
|
||||
case S_REJECTED:
|
||||
return getMLText("rejected");
|
||||
break;
|
||||
case S_OBSOLETE:
|
||||
return getMLText("obsolete");
|
||||
break;
|
||||
case S_EXPIRED:
|
||||
return getMLText("expired");
|
||||
break;
|
||||
case S_IN_REVISION:
|
||||
return getMLText("in_revision");
|
||||
break;
|
||||
case S_DRAFT:
|
||||
return getMLText("draft");
|
||||
break;
|
||||
case S_NEEDS_CORRECTION:
|
||||
return getMLText("needs_correction");
|
||||
break;
|
||||
default:
|
||||
return getMLText("status_unknown");
|
||||
break;
|
||||
}
|
||||
}
|
||||
} /* }}} */
|
||||
|
||||
function getAttributeTypeText($attrdef) { /* {{{ */
|
||||
return $GLOBALS['translator']->getAttributeTypeText($attrdef);
|
||||
$t = '';
|
||||
switch($attrdef->getType()) {
|
||||
case SeedDMS_Core_AttributeDefinition::type_int:
|
||||
$t = getMLText("attrdef_type_int");
|
||||
break;
|
||||
case SeedDMS_Core_AttributeDefinition::type_float:
|
||||
$t = getMLText("attrdef_type_float");
|
||||
break;
|
||||
case SeedDMS_Core_AttributeDefinition::type_string:
|
||||
$t = getMLText("attrdef_type_string");
|
||||
break;
|
||||
case SeedDMS_Core_AttributeDefinition::type_boolean:
|
||||
$t = getMLText("attrdef_type_boolean");
|
||||
break;
|
||||
case SeedDMS_Core_AttributeDefinition::type_date:
|
||||
$t = getMLText("attrdef_type_date");
|
||||
break;
|
||||
case SeedDMS_Core_AttributeDefinition::type_email:
|
||||
$t = getMLText("attrdef_type_email");
|
||||
break;
|
||||
case SeedDMS_Core_AttributeDefinition::type_url:
|
||||
$t = getMLText("attrdef_type_url");
|
||||
break;
|
||||
case SeedDMS_Core_AttributeDefinition::type_boolean:
|
||||
$t = getMLText("attrdef_type_boolean");
|
||||
break;
|
||||
case SeedDMS_Core_AttributeDefinition::type_folder:
|
||||
$t = getMLText("attrdef_type_folder");
|
||||
break;
|
||||
case SeedDMS_Core_AttributeDefinition::type_document:
|
||||
$t = getMLText("attrdef_type_document");
|
||||
break;
|
||||
case SeedDMS_Core_AttributeDefinition::type_user:
|
||||
$t = getMLText("attrdef_type_user");
|
||||
break;
|
||||
case SeedDMS_Core_AttributeDefinition::type_group:
|
||||
$t = getMLText("attrdef_type_group");
|
||||
break;
|
||||
}
|
||||
return $t;
|
||||
} /* }}} */
|
||||
|
||||
function getAttributeObjectTypeText($attrdef) { /* {{{ */
|
||||
return $GLOBALS['translator']->getAttributeObjectTypeText($attrdef);
|
||||
$ot = '';
|
||||
switch($attrdef->getObjType()) {
|
||||
case SeedDMS_Core_AttributeDefinition::objtype_all:
|
||||
$ot = getMLText("all");
|
||||
break;
|
||||
case SeedDMS_Core_AttributeDefinition::objtype_folder:
|
||||
$ot = getMLText("folder");
|
||||
break;
|
||||
case SeedDMS_Core_AttributeDefinition::objtype_document:
|
||||
$ot = getMLText("document");
|
||||
break;
|
||||
case SeedDMS_Core_AttributeDefinition::objtype_documentcontent:
|
||||
$ot = getMLText("documentcontent");
|
||||
break;
|
||||
default:
|
||||
$ot = getMLText('objtype_unknown');
|
||||
}
|
||||
return $ot;
|
||||
} /* }}} */
|
||||
|
||||
function getAttributeValidationText($error, $attrname='', $attrvalue='', $regex='') { /* {{{ */
|
||||
return $GLOBALS['translator']->getAttributeValidationText($error, $attrname, $attrvalue, $regex);
|
||||
$arr = getAttributeValidationError($error, $attrname, $attrvalue, $regex);
|
||||
|
||||
return getMLText($arr[0], $arr[1]);
|
||||
} /* }}} */
|
||||
|
||||
function getAttributeValidationError($error, $attrname='', $attrvalue='', $regex='') { /* {{{ */
|
||||
return $GLOBALS['translator']->getAttributeValidationError($error, $attrname, $attrvalue, $regex);
|
||||
if(is_object($attrvalue))
|
||||
$attrvalue = $attrvalue->getId();
|
||||
switch($error) {
|
||||
case 14:
|
||||
return array("attr_not_in_valueset", array('attrname'=>$attrname, 'value'=>$attrvalue));
|
||||
break;
|
||||
case 13:
|
||||
return array("attr_not_a_group", array('attrname'=>$attrname, 'value'=>$attrvalue));
|
||||
break;
|
||||
case 12:
|
||||
return array("attr_not_a_user", array('attrname'=>$attrname, 'value'=>$attrvalue));
|
||||
break;
|
||||
case 11:
|
||||
return array("attr_not_a_folder", array('attrname'=>$attrname, 'value'=>$attrvalue));
|
||||
break;
|
||||
case 10:
|
||||
return array("attr_not_a_document", array('attrname'=>$attrname, 'value'=>$attrvalue));
|
||||
break;
|
||||
case 9:
|
||||
return array("attr_malformed_date", array('attrname'=>$attrname, 'value'=>$attrvalue));
|
||||
break;
|
||||
case 8:
|
||||
return array("attr_malformed_boolean", array('attrname'=>$attrname, 'value'=>$attrvalue));
|
||||
break;
|
||||
case 7:
|
||||
return array("attr_malformed_float", array('attrname'=>$attrname, 'value'=>$attrvalue));
|
||||
break;
|
||||
case 6:
|
||||
return array("attr_malformed_int", array('attrname'=>$attrname, 'value'=>$attrvalue));
|
||||
break;
|
||||
case 5:
|
||||
return array("attr_malformed_email", array('attrname'=>$attrname, 'value'=>$attrvalue));
|
||||
break;
|
||||
case 4:
|
||||
return array("attr_malformed_url", array('attrname'=>$attrname, 'value'=>$attrvalue));
|
||||
break;
|
||||
case 3:
|
||||
return array("attr_no_regex_match", array('attrname'=>$attrname, 'value'=>$attrvalue, 'regex'=>$regex));
|
||||
break;
|
||||
case 2:
|
||||
return array("attr_max_values", array('attrname'=>$attrname, 'value'=>$attrvalue));
|
||||
break;
|
||||
case 1:
|
||||
return array("attr_min_values", array('attrname'=>$attrname, 'value'=>$attrvalue));
|
||||
break;
|
||||
default:
|
||||
return array("attr_validation_error", array('attrname'=>$attrname, 'value'=>$attrvalue));
|
||||
break;
|
||||
}
|
||||
} /* }}} */
|
||||
|
||||
|
|
|
|||
|
|
@ -21,5 +21,5 @@
|
|||
require_once("Log.php");
|
||||
require_once("inc/inc.Utils.php");
|
||||
|
||||
$logger = getLogger($settings, '', (int) $settings->_logFileMaxLevel);
|
||||
$logger = getLogger('', (int) $settings->_logFileMaxLevel);
|
||||
|
||||
|
|
|
|||
|
|
@ -12,10 +12,8 @@
|
|||
* @version Release: @package_version@
|
||||
*/
|
||||
|
||||
require_once("inc.ClassEmailNotify.php");
|
||||
require_once("inc.ClassNotificationService.php");
|
||||
|
||||
$notifier = new SeedDMS_NotificationService($logger, $settings, $translator);
|
||||
global $logger;
|
||||
$notifier = new SeedDMS_NotificationService($logger, $settings);
|
||||
|
||||
if(isset($GLOBALS['SEEDDMS_HOOKS']['notification'])) {
|
||||
foreach($GLOBALS['SEEDDMS_HOOKS']['notification'] as $notificationObj) {
|
||||
|
|
@ -26,7 +24,7 @@ if(isset($GLOBALS['SEEDDMS_HOOKS']['notification'])) {
|
|||
}
|
||||
|
||||
if($settings->_enableEmail) {
|
||||
$notifier->addService(new SeedDMS_EmailNotify($dms, $translator, $settings->_smtpSendFrom, $settings->_smtpServer, $settings->_smtpPort, $settings->_smtpUser, $settings->_smtpPassword, $settings->_smtpLazySSL, $settings->_smtpForceFrom), 'email');
|
||||
$notifier->addService(new SeedDMS_EmailNotify($dms, $settings->_smtpSendFrom, $settings->_smtpServer, $settings->_smtpPort, $settings->_smtpUser, $settings->_smtpPassword, $settings->_smtpLazySSL, $settings->_smtpForceFrom), 'email');
|
||||
}
|
||||
|
||||
if(isset($GLOBALS['SEEDDMS_HOOKS']['notification'])) {
|
||||
|
|
|
|||
17
inc/inc.Scheduler.php
Normal file
17
inc/inc.Scheduler.php
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
<?php
|
||||
/**
|
||||
* Initialize scheduler
|
||||
*
|
||||
* @category DMS
|
||||
* @package SeedDMS
|
||||
* @license GPL 2
|
||||
* @version @version@
|
||||
* @author Uwe Steinmann <uwe@steinmann.cx>
|
||||
* @copyright Copyright (C) 2018 Uwe Steinmann
|
||||
* @version Release: @package_version@
|
||||
*/
|
||||
|
||||
require_once "inc.ClassSchedulerTaskBase.php";
|
||||
require_once "inc.ClassScheduler.php";
|
||||
require_once "inc.ClassSchedulerTask.php";
|
||||
|
||||
|
|
@ -18,8 +18,6 @@
|
|||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
use Seeddms\Seeddms\Settings;
|
||||
|
||||
require_once('inc.ClassSettings.php');
|
||||
if(defined("SEEDDMS_CONFIG_FILE"))
|
||||
$settings = new Settings(SEEDDMS_CONFIG_FILE);
|
||||
|
|
@ -62,7 +60,7 @@ if($settings->_dbDriver == 'sqlite' && empty($settings->_dbDatabase)) {
|
|||
$settings->_dbDatabase = $__datadir."/content.db";
|
||||
}
|
||||
|
||||
ini_set('include_path', $settings->_rootDir.'..'. PATH_SEPARATOR .ini_get('include_path'));
|
||||
ini_set('include_path', $settings->_rootDir.'pear'. PATH_SEPARATOR .ini_get('include_path'));
|
||||
if(!empty($settings->_extraPath)) {
|
||||
ini_set('include_path', $settings->_extraPath. PATH_SEPARATOR .ini_get('include_path'));
|
||||
}
|
||||
|
|
@ -77,7 +75,13 @@ if(isset($settings->_maxExecutionTime)) {
|
|||
* relative to it.
|
||||
*/
|
||||
ini_set('include_path', $settings->_rootDir. PATH_SEPARATOR .ini_get('include_path'));
|
||||
/* Add root Dir.'../pear'. Needed because the SeedDMS_Core, etc. are included
|
||||
* relative to it.
|
||||
*/
|
||||
ini_set('include_path', $settings->_rootDir.'../pear'. PATH_SEPARATOR .ini_get('include_path'));
|
||||
|
||||
require_once 'vendor/autoload.php';
|
||||
/* composer is installed in pear directory, but install tool does not need it */
|
||||
if(!defined("SEEDDMS_INSTALL"))
|
||||
require_once 'vendor/autoload.php';
|
||||
|
||||
require_once "inc.Version.php";
|
||||
|
|
|
|||
1052
inc/inc.Tasks.php
Normal file
1052
inc/inc.Tasks.php
Normal file
File diff suppressed because it is too large
Load Diff
|
|
@ -86,29 +86,21 @@ function getPeriodOfTime($timestamp) { /* {{{ */
|
|||
$timestamp = strtotime($timestamp);
|
||||
|
||||
$time = time() - $timestamp; // to get the time since that moment
|
||||
$rel = 'ago';
|
||||
if ($time < 0) {
|
||||
$time = -$time;
|
||||
$rel = 'from_now';
|
||||
}
|
||||
$time = ($time < 0) ? -$time : $time;
|
||||
$time = ($time<1)? 1 : $time;
|
||||
$tokens = array (
|
||||
31536000 => 'year',
|
||||
2592000 => 'month',
|
||||
604800 => 'week',
|
||||
86400 => 'day',
|
||||
3600 => 'hour',
|
||||
60 => 'minute',
|
||||
1 => 'second'
|
||||
31536000 => 'abbr_year',
|
||||
2592000 => 'abbr_month',
|
||||
604800 => 'abbr_week',
|
||||
86400 => 'abbr_day',
|
||||
3600 => 'abbr_hour',
|
||||
60 => 'abbr_minute',
|
||||
1 => 'abbr_second'
|
||||
);
|
||||
|
||||
if($time == 0)
|
||||
return getMLText('now');
|
||||
|
||||
foreach ($tokens as $unit => $text) {
|
||||
if ($time < $unit) continue;
|
||||
$numberOfUnits = floor($time / $unit);
|
||||
return getMLText($text.($numberOfUnits > 1 ? 's' : '').'_'.$rel, ['num'=>$numberOfUnits]);
|
||||
return $numberOfUnits.' '.(($numberOfUnits>1) ? getMLText($text):getMLText($text));
|
||||
}
|
||||
} /* }}} */
|
||||
|
||||
|
|
@ -119,7 +111,7 @@ function getPeriodOfTime($timestamp) { /* {{{ */
|
|||
* @return integer/boolean unix timestamp or false in case of an error
|
||||
*/
|
||||
function makeTsFromDate($date) { /* {{{ */
|
||||
return $date ? strtotime($date) : false;
|
||||
return strtotime($date);
|
||||
} /* }}} */
|
||||
|
||||
/*
|
||||
|
|
@ -455,7 +447,7 @@ function utf8_basename($path, $suffix='') { /* {{{ */
|
|||
* @return string valid file name
|
||||
*/
|
||||
function getFilenameByDocname($content) { /* {{{ */
|
||||
if(is_string) {
|
||||
if(is_string($content)) {
|
||||
$filename = $content;
|
||||
} else {
|
||||
$document = $content->getDocument();
|
||||
|
|
@ -470,31 +462,10 @@ function getFilenameByDocname($content) { /* {{{ */
|
|||
return mb_ereg_replace("([^\w\s\d\-_~,;\[\]\(\).])", '', $filename);
|
||||
} /* }}} */
|
||||
|
||||
function getStreamContext($proxyurl, $proxyuser, $proxypass) { /* {{{ */
|
||||
if(!$proxyurl)
|
||||
return null;
|
||||
$url = parse_url($proxyurl);
|
||||
$opts = [
|
||||
$url['scheme'] => [
|
||||
'proxy' => 'tcp://'.$url['host'].($url['port'] ? ':'.$url['port'] : ''),
|
||||
'request_fulluri' => true,
|
||||
]
|
||||
];
|
||||
if($proxyuser && $proxypass) {
|
||||
$auth = base64_encode($proxyurl.':'.$this->proxypass);
|
||||
$opts[$url['scheme']] = [
|
||||
'header' => [
|
||||
'Proxy-Authorization: Basic '.$auth
|
||||
]
|
||||
];
|
||||
}
|
||||
function getLogger($prefix='', $mask=PEAR_LOG_INFO) { /* {{{ */
|
||||
global $settings;
|
||||
|
||||
$context = stream_context_create($opts);
|
||||
return $context;
|
||||
} /* }}} */
|
||||
|
||||
function getLogger($settings, $prefix='', $mask=PEAR_LOG_INFO) { /* {{{ */
|
||||
if(!empty($settings->_logFileEnable)) {
|
||||
if($settings->_logFileEnable) {
|
||||
if ($settings->_logFileRotation=="h") $logname=date("YmdH", time());
|
||||
else if ($settings->_logFileRotation=="d") $logname=date("Ymd", time());
|
||||
else $logname=date("Ym", time());
|
||||
|
|
@ -650,7 +621,7 @@ function checkFormKey($formid='', $method='POST') { /* {{{ */
|
|||
* quota is reached. Negative values indicate a disk usage above quota.
|
||||
*/
|
||||
function checkQuota($user) { /* {{{ */
|
||||
global $settings;
|
||||
global $settings, $dms;
|
||||
|
||||
/* check if quota is turn off system wide */
|
||||
if($settings->_quota == 0)
|
||||
|
|
@ -772,7 +743,6 @@ function get_extension($mimetype) { /* {{{ */
|
|||
case 'video/webm': return '.webm';
|
||||
case 'application/zip': return '.zip';
|
||||
case 'application/x-gzip': return '.gz';
|
||||
case 'application/x-xz': return '.xz';
|
||||
case 'application/x-rar': return '.rar';
|
||||
case 'application/x-7z-compressed': return '.7z';
|
||||
case 'application/x-compressed-tar': return '.tgz';
|
||||
|
|
@ -825,6 +795,18 @@ function addDirSep($str, $chr=DIRECTORY_SEPARATOR) { /* {{{ */
|
|||
} /* }}} */
|
||||
|
||||
/**
|
||||
* Formats comments for aknowledge of reception.
|
||||
*
|
||||
* Only use in documentListRow()
|
||||
*/
|
||||
function formatComment($an) { /* {{{ */
|
||||
$t = array();
|
||||
foreach($an as $a)
|
||||
$t[] = $a['n']." × ".$a['c'];
|
||||
return $t;
|
||||
} /* }}} */
|
||||
|
||||
/*
|
||||
* Determines if a command exists on the current environment
|
||||
*
|
||||
* @param string $command The command to check
|
||||
|
|
@ -1000,6 +982,52 @@ function seed_pass_verify($password, $hash) { /* {{{ */
|
|||
return $hash === md5($password);
|
||||
} /* }}} */
|
||||
|
||||
function resolveTask($task) { /* {{{ */
|
||||
global $dms, $user, $settings, $logger, $fulltextservice, $notifier, $conversionmgr;
|
||||
|
||||
if(is_object($task))
|
||||
return $task;
|
||||
if(is_string($task)) {
|
||||
if(class_exists($task)) {
|
||||
$task = new $task($dms, $user, $settings, $logger, $fulltextservice, $notifier, $conversionmgr);
|
||||
}
|
||||
}
|
||||
return $task;
|
||||
} /* }}} */
|
||||
|
||||
/**
|
||||
* Return nonce for CSP
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
function createNonce() { /* {{{ */
|
||||
$length = 16;
|
||||
$usable = true;
|
||||
$bytes = openssl_random_pseudo_bytes($length, $usable);
|
||||
if ($usable === false) {
|
||||
// weak
|
||||
// @TODO do something?
|
||||
}
|
||||
return base64_encode($bytes);
|
||||
} /* }}} */
|
||||
|
||||
/**
|
||||
* Create a real uniqid for cryptographic purposes
|
||||
*
|
||||
* @ return string
|
||||
*/
|
||||
function uniqidReal($lenght = 13) {
|
||||
// uniqid gives 13 chars, but you could adjust it to your needs.
|
||||
if (function_exists("random_bytes")) {
|
||||
$bytes = random_bytes(ceil($lenght / 2));
|
||||
} elseif (function_exists("openssl_random_pseudo_bytes")) {
|
||||
$bytes = openssl_random_pseudo_bytes(ceil($lenght / 2));
|
||||
} else {
|
||||
throw new Exception("no cryptographically secure random function available");
|
||||
}
|
||||
return substr(bin2hex($bytes), 0, $lenght);
|
||||
}
|
||||
|
||||
/**
|
||||
* Compare function for sorting users by login
|
||||
*
|
||||
|
|
@ -1122,9 +1150,9 @@ function getMandatoryReviewers($folder, $document, $user) { /* {{{ */
|
|||
foreach($revg as $gid) {
|
||||
if($g = $dms->getGroup($gid)) {
|
||||
if($document)
|
||||
$accessmode = $document->getGroupAccessMode($g);
|
||||
$accessmode = $document->getGroupAccessMode($u);
|
||||
else
|
||||
$accessmode = $folder->getGroupAccessMode($g);
|
||||
$accessmode = $folder->getGroupAccessMode($u);
|
||||
if($accessmode < M_READ || !$g->getUsers())
|
||||
$reviewers["ng"][] = $g->getId();
|
||||
else
|
||||
|
|
@ -1219,9 +1247,9 @@ function getMandatoryApprovers($folder, $document, $user) { /* {{{ */
|
|||
foreach($appg as $gid) {
|
||||
if($g = $dms->getGroup($gid)) {
|
||||
if($document)
|
||||
$accessmode = $document->getGroupAccessMode($g);
|
||||
$accessmode = $document->getGroupAccessMode($u);
|
||||
else
|
||||
$accessmode = $folder->getGroupAccessMode($g);
|
||||
$accessmode = $folder->getGroupAccessMode($u);
|
||||
if($accessmode < M_READ || !$g->getUsers())
|
||||
$approvers["ng"][] = $g->getId();
|
||||
else
|
||||
|
|
@ -1232,7 +1260,33 @@ function getMandatoryApprovers($folder, $document, $user) { /* {{{ */
|
|||
return $approvers;
|
||||
} /* }}} */
|
||||
|
||||
require_once "inc/inc.ClassUtilities.php";
|
||||
/**
|
||||
* Class with various utility methods
|
||||
*
|
||||
* This class will sooner or later comprise the functions above
|
||||
*
|
||||
*/
|
||||
class SeedDMS_Utils { /* {{{ */
|
||||
|
||||
/**
|
||||
* Recursively remove a directory on disc
|
||||
*
|
||||
* @param string $dir name of directory
|
||||
*/
|
||||
static public function rrmdir($dir) { /* {{{ */
|
||||
if (is_dir($dir)) {
|
||||
$objects = scandir($dir);
|
||||
foreach ($objects as $object) {
|
||||
if ($object != "." && $object != "..") {
|
||||
if (filetype($dir."/".$object) == "dir") self::rrmdir($dir."/".$object); else unlink($dir."/".$object);
|
||||
}
|
||||
}
|
||||
reset($objects);
|
||||
rmdir($dir);
|
||||
}
|
||||
} /* }}} */
|
||||
|
||||
} /* }}} */
|
||||
|
||||
/**
|
||||
* Class for creating encrypted api keys
|
||||
|
|
@ -1378,8 +1432,6 @@ class SeedDMS_Search { /* {{{ */
|
|||
|
||||
public $searchparams;
|
||||
|
||||
protected $total;
|
||||
|
||||
protected $dcount;
|
||||
|
||||
protected $fcount;
|
||||
|
|
@ -1392,10 +1444,6 @@ class SeedDMS_Search { /* {{{ */
|
|||
|
||||
protected $searchTime;
|
||||
|
||||
protected $facets;
|
||||
|
||||
protected $stats;
|
||||
|
||||
public function __construct($dms, $user, $fulltextservice, $settings) {
|
||||
$this->dms = $dms;
|
||||
$this->user = $user;
|
||||
|
|
@ -1404,7 +1452,6 @@ class SeedDMS_Search { /* {{{ */
|
|||
$this->searchparams = [];
|
||||
$this->dcount = 0;
|
||||
$this->fcount = 0;
|
||||
$this->total = 0;
|
||||
$this->totalPages = 0;
|
||||
$this->entries = array();
|
||||
$this->terms = array();
|
||||
|
|
@ -1740,6 +1787,33 @@ class SeedDMS_Search { /* {{{ */
|
|||
}
|
||||
$this->searchparams['startFolder'] = $startFolder;
|
||||
|
||||
/* Revision date {{{ */
|
||||
$revisionstartts = null;
|
||||
$revisionstartdate = array();
|
||||
$revisionendts = null;
|
||||
$revisionenddate = array();
|
||||
$revised['from'] = null;
|
||||
$revised['to'] = null;
|
||||
if(!empty($get["revisiondatestart"])) {
|
||||
$revisionstartts = makeTsFromDate($get["revisiondatestart"]);
|
||||
$revisionstartdate = array('year'=>(int)date('Y', $revisionstartts), 'month'=>(int)date('m', $revisionstartts), 'day'=>(int)date('d', $revisionstartts), 'hour'=>0, 'minute'=>0, 'second'=>0);
|
||||
if (!checkdate($revisionstartdate['month'], $revisionstartdate['day'], $revisionstartdate['year'])) {
|
||||
UI::exitError(getMLText("search"),getMLText("invalid_revision_date_start"));
|
||||
}
|
||||
$revised['from'] = $revisionstartts;
|
||||
}
|
||||
$this->searchparams['revisionstartdate'] = $revisionstartdate;
|
||||
if(!empty($get["revisiondateend"])) {
|
||||
$revisionendts = makeTsFromDate($get["revisiondateend"]);
|
||||
$revisionenddate = array('year'=>(int)date('Y', $revisionendts), 'month'=>(int)date('m', $revisionendts), 'day'=>(int)date('d', $revisionendts), 'hour'=>23, 'minute'=>59, 'second'=>59);
|
||||
if (!checkdate($revisionenddate['month'], $revisionenddate['day'], $revisionenddate['year'])) {
|
||||
UI::exitError(getMLText("search"),getMLText("invalid_revision_date_end"));
|
||||
}
|
||||
$revised['to'] = $revisionendts;
|
||||
}
|
||||
$this->searchparams['revisionenddate'] = $revisionenddate;
|
||||
/* }}} */
|
||||
|
||||
/* Status date {{{ */
|
||||
$statusstartdate = array();
|
||||
$statusenddate = array();
|
||||
|
|
@ -1784,6 +1858,12 @@ class SeedDMS_Search { /* {{{ */
|
|||
$this->searchparams['expenddate'] = $expenddate;
|
||||
/* }}} */
|
||||
|
||||
$reception = array();
|
||||
if (isset($get["reception"])){
|
||||
$reception = $get["reception"];
|
||||
}
|
||||
$this->searchparams['reception'] = $reception;
|
||||
|
||||
/* Do not search for folders if result shall be filtered by status.
|
||||
* If this is not done, unexplainable results will be delivered.
|
||||
* e.g. a search for expired documents of a given user will list
|
||||
|
|
@ -1799,17 +1879,16 @@ class SeedDMS_Search { /* {{{ */
|
|||
$attributes = array();
|
||||
|
||||
foreach($attributes as $attrdefid=>$attribute) {
|
||||
$attrdef = $this->dms->getAttributeDefinition($attrdefid);
|
||||
if($attribute) {
|
||||
if($attrdef = $this->dms->getAttributeDefinition($attrdefid)) {
|
||||
if($attrdef->getType() == SeedDMS_Core_AttributeDefinition::type_date) {
|
||||
if(is_array($attribute)) {
|
||||
if(!empty($attributes[$attrdefid]['from']))
|
||||
$attributes[$attrdefid]['from'] = date('Y-m-d', makeTsFromDate($attribute['from']));
|
||||
if(!empty($attributes[$attrdefid]['to']))
|
||||
$attributes[$attrdefid]['to'] = date('Y-m-d', makeTsFromDate($attribute['to']));
|
||||
} else {
|
||||
$attributes[$attrdefid] = date('Y-m-d', makeTsFromDate($attribute));
|
||||
}
|
||||
if($attrdef->getType() == SeedDMS_Core_AttributeDefinition::type_date) {
|
||||
if(is_array($attribute)) {
|
||||
if(!empty($attributes[$attrdefid]['from']))
|
||||
$attributes[$attrdefid]['from'] = date('Y-m-d', makeTsFromDate($attribute['from']));
|
||||
if(!empty($attributes[$attrdefid]['to']))
|
||||
$attributes[$attrdefid]['to'] = date('Y-m-d', makeTsFromDate($attribute['to']));
|
||||
} else {
|
||||
$attributes[$attrdefid] = date('Y-m-d', makeTsFromDate($attribute));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1935,6 +2014,9 @@ class SeedDMS_Search { /* {{{ */
|
|||
'mode'=>$this->searchparams['resultmode'],
|
||||
'expirationstartdate'=>$this->searchparams['expstartdate'],
|
||||
'expirationenddate'=>$this->searchparams['expenddate'],
|
||||
'revisionstartdate'=>$this->searchparams['revisionstartdate'],
|
||||
'revisionenddate'=>$this->searchparams['revisionenddate'],
|
||||
'reception'=>$this->searchparams['reception'],
|
||||
'statusstartdate'=>$this->searchparams['statusstartdate'],
|
||||
'statusenddate'=>$this->searchparams['statusenddate'],
|
||||
'orderby'=>$this->searchparams['orderby']
|
||||
|
|
|
|||
|
|
@ -18,11 +18,9 @@
|
|||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
namespace Seeddms\Seeddms;
|
||||
class SeedDMS_Version { /* {{{ */
|
||||
|
||||
class Version { /* {{{ */
|
||||
|
||||
const _number = "5.1.44";
|
||||
const _number = "6.0.33";
|
||||
const _string = "SeedDMS";
|
||||
|
||||
function __construct() {
|
||||
|
|
@ -49,7 +47,7 @@ class Version { /* {{{ */
|
|||
|
||||
function banner() { /* {{{ */
|
||||
return self::_string .", ". self::_number;
|
||||
} /* }}} */
|
||||
}
|
||||
|
||||
/**
|
||||
* Compare two version
|
||||
|
|
@ -86,4 +84,3 @@ class Version { /* {{{ */
|
|||
|
||||
} /* }}} */
|
||||
|
||||
class_alias('Seeddms\Seeddms\Version', 'SeedDMS_Version');
|
||||
|
|
|
|||
|
|
@ -34,7 +34,7 @@ require "inc/inc.Settings.php";
|
|||
use DI\ContainerBuilder;
|
||||
use Slim\Factory\AppFactory;
|
||||
|
||||
if (true) {
|
||||
if(true) {
|
||||
require_once("inc/inc.Utils.php");
|
||||
require_once("inc/inc.LogInit.php");
|
||||
require_once("inc/inc.Language.php");
|
||||
|
|
@ -59,37 +59,38 @@ if (true) {
|
|||
$container->set('fulltextservice', $fulltextservice);
|
||||
$container->set('notifier', $notifier);
|
||||
$container->set('authenticator', $authenticator);
|
||||
$container->set('translator', $translator);
|
||||
|
||||
if (isset($GLOBALS['SEEDDMS_HOOKS']['initDMS'])) {
|
||||
foreach ($GLOBALS['SEEDDMS_HOOKS']['initDMS'] as $hookObj) {
|
||||
if (method_exists($hookObj, 'addMiddleware')) {
|
||||
$hookObj->addMiddleware($app);
|
||||
if(isset($GLOBALS['SEEDDMS_HOOKS']['initDMS'])) {
|
||||
foreach($GLOBALS['SEEDDMS_HOOKS']['initDMS'] as $hookObj) {
|
||||
if (method_exists($hookObj, 'addMiddleware')) {
|
||||
$hookObj->addMiddleware($app);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$app->addErrorMiddleware(false, true, true);
|
||||
|
||||
if (isset($GLOBALS['SEEDDMS_HOOKS']['initDMS'])) {
|
||||
foreach ($GLOBALS['SEEDDMS_HOOKS']['initDMS'] as $hookObj) {
|
||||
if(isset($GLOBALS['SEEDDMS_HOOKS']['initDMS'])) {
|
||||
foreach($GLOBALS['SEEDDMS_HOOKS']['initDMS'] as $hookObj) {
|
||||
if (method_exists($hookObj, 'addRoute')) {
|
||||
// FIXME: pass $app only just like initRestAPI. $app has a container
|
||||
// which contains all other objects
|
||||
$hookObj->addRoute(array('dms'=>$dms, 'app'=>$app, 'settings'=>$settings, 'conversionmgr'=>$conversionmgr, 'authenticator'=>$authenticator, 'fulltextservice'=>$fulltextservice, 'logger'=>$logger, 'notifier'=>$notifier, 'translator'=>$translator));
|
||||
$hookObj->addRoute(array('dms'=>$dms, 'app'=>$app, 'settings'=>$settings, 'conversionmgr'=>$conversionmgr, 'authenticator'=>$authenticator, 'fulltextservice'=>$fulltextservice, 'logger'=>$logger));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Catch all route */
|
||||
$app->get('/{path:.*}', function ($request, $response) use ($settings) {
|
||||
$app->get('/{path:.*}', function($request, $response) use ($settings) {
|
||||
return $response
|
||||
->withHeader('Location', $settings->_httpRoot.'out/out.ViewFolder.php')
|
||||
->withStatus(302);
|
||||
|
||||
});
|
||||
|
||||
$app->run();
|
||||
} else {
|
||||
|
||||
header("Location: ". (isset($settings->_siteDefaultPage) && strlen($settings->_siteDefaultPage)>0 ? $settings->_siteDefaultPage : "out/out.ViewFolder.php"));
|
||||
?>
|
||||
<html>
|
||||
|
|
@ -47,19 +47,35 @@ CREATE TABLE `tblAttributeDefinitions` (
|
|||
-- --------------------------------------------------------
|
||||
|
||||
--
|
||||
-- Table structure for table `tblUsers`
|
||||
-- Table structure for table `tblRoles`
|
||||
--
|
||||
|
||||
CREATE TABLE `tblRoles` (
|
||||
`id` int(11) NOT NULL AUTO_INCREMENT,
|
||||
`name` varchar(50) DEFAULT NULL,
|
||||
`role` smallint(1) NOT NULL DEFAULT '0',
|
||||
`noaccess` varchar(30) NOT NULL DEFAULT '',
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE (`name`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
||||
|
||||
-- --------------------------------------------------------
|
||||
|
||||
--
|
||||
-- Table structure for table `tblUsers`
|
||||
--
|
||||
|
||||
CREATE TABLE `tblUsers` (
|
||||
`id` int(11) NOT NULL AUTO_INCREMENT,
|
||||
`login` varchar(50) DEFAULT NULL,
|
||||
`pwd` varchar(50) DEFAULT NULL,
|
||||
`secret` varchar(50) DEFAULT NULL,
|
||||
`fullName` varchar(100) DEFAULT NULL,
|
||||
`email` varchar(70) DEFAULT NULL,
|
||||
`language` varchar(32) NOT NULL,
|
||||
`theme` varchar(32) NOT NULL,
|
||||
`comment` text NOT NULL,
|
||||
`role` smallint(1) NOT NULL DEFAULT '0',
|
||||
`role` int(11) NOT NULL,
|
||||
`hidden` smallint(1) NOT NULL DEFAULT '0',
|
||||
`pwdExpiration` datetime DEFAULT NULL,
|
||||
`loginfailures` tinyint(4) NOT NULL DEFAULT '0',
|
||||
|
|
@ -67,11 +83,28 @@ CREATE TABLE `tblUsers` (
|
|||
`quota` bigint(20) DEFAULT NULL,
|
||||
`homefolder` int(11) DEFAULT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY `login` (`login`)
|
||||
UNIQUE KEY `login` (`login`),
|
||||
CONSTRAINT `tblUsers_role` FOREIGN KEY (`role`) REFERENCES `tblRoles` (`id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
||||
|
||||
-- --------------------------------------------------------
|
||||
|
||||
--
|
||||
-- Table structure for table `tblUserSubstitutes`
|
||||
--
|
||||
|
||||
CREATE TABLE `tblUserSubstitutes` (
|
||||
`id` int(11) NOT NULL AUTO_INCREMENT,
|
||||
`user` int(11) DEFAULT null,
|
||||
`substitute` int(11) DEFAULT null,
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY `user` (`user`,`substitute`),
|
||||
CONSTRAINT `tblUserSubstitutes_user` FOREIGN KEY (`user`) REFERENCES `tblUsers` (`id`) ON DELETE CASCADE,
|
||||
CONSTRAINT `tblUserSubstitutes_substitute` FOREIGN KEY (`substitute`) REFERENCES `tblUsers` (`id`) ON DELETE CASCADE
|
||||
);
|
||||
|
||||
-- --------------------------------------------------------
|
||||
|
||||
--
|
||||
-- Table structure for table `tblUserPasswordRequest`
|
||||
--
|
||||
|
|
@ -222,6 +255,7 @@ CREATE TABLE `tblDocumentApprovers` (
|
|||
UNIQUE KEY `documentID` (`documentID`,`version`,`type`,`required`),
|
||||
CONSTRAINT `tblDocumentApprovers_document` FOREIGN KEY (`documentID`) REFERENCES `tblDocuments` (`id`) ON DELETE CASCADE
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
||||
CREATE INDEX `indDocumentApproversRequired` ON `tblDocumentApprovers` (`required`);
|
||||
|
||||
-- --------------------------------------------------------
|
||||
|
||||
|
|
@ -262,6 +296,7 @@ CREATE TABLE `tblDocumentContent` (
|
|||
`mimeType` varchar(100) NOT NULL DEFAULT '',
|
||||
`fileSize` bigint(20) DEFAULT NULL,
|
||||
`checksum` char(32) DEFAULT NULL,
|
||||
`revisiondate` datetime DEFAULT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY `document` (`document`,`version`),
|
||||
CONSTRAINT `tblDocumentContent_document` FOREIGN KEY (`document`) REFERENCES `tblDocuments` (`id`)
|
||||
|
|
@ -350,6 +385,23 @@ CREATE TABLE `tblDocumentLocks` (
|
|||
-- --------------------------------------------------------
|
||||
|
||||
--
|
||||
-- Table structure for table `tblDocumentCheckOuts`
|
||||
--
|
||||
|
||||
CREATE TABLE `tblDocumentCheckOuts` (
|
||||
`document` int(11) NOT NULL DEFAULT '0',
|
||||
`version` smallint(5) unsigned NOT NULL DEFAULT '0',
|
||||
`userID` int(11) NOT NULL DEFAULT '0',
|
||||
`date` datetime NOT NULL,
|
||||
`filename` varchar(255) NOT NULL DEFAULT '',
|
||||
PRIMARY KEY (`document`),
|
||||
CONSTRAINT `tblDocumentCheckOuts_document` FOREIGN KEY (`document`) REFERENCES `tblDocuments` (`id`) ON DELETE CASCADE,
|
||||
CONSTRAINT `tblDocumentCheckOuts_user` FOREIGN KEY (`userID`) REFERENCES `tblUsers` (`id`) ON DELETE CASCADE
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
||||
|
||||
-- --------------------------------------------------------
|
||||
|
||||
--
|
||||
-- Table structure for table `tblDocumentReviewers`
|
||||
--
|
||||
|
||||
|
|
@ -363,6 +415,7 @@ CREATE TABLE `tblDocumentReviewers` (
|
|||
UNIQUE KEY `documentID` (`documentID`,`version`,`type`,`required`),
|
||||
CONSTRAINT `tblDocumentReviewers_document` FOREIGN KEY (`documentID`) REFERENCES `tblDocuments` (`id`) ON DELETE CASCADE
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
||||
CREATE INDEX `indDocumentReviewersRequired` ON `tblDocumentReviewers` (`required`);
|
||||
|
||||
-- --------------------------------------------------------
|
||||
|
||||
|
|
@ -386,6 +439,83 @@ CREATE TABLE `tblDocumentReviewLog` (
|
|||
|
||||
-- --------------------------------------------------------
|
||||
|
||||
--
|
||||
-- Table structure for table `tblDocumentRecipients`
|
||||
--
|
||||
|
||||
CREATE TABLE `tblDocumentRecipients` (
|
||||
`receiptID` int(11) NOT NULL AUTO_INCREMENT,
|
||||
`documentID` int(11) NOT NULL DEFAULT '0',
|
||||
`version` smallint(5) unsigned NOT NULL DEFAULT '0',
|
||||
`type` tinyint(4) NOT NULL DEFAULT '0',
|
||||
`required` int(11) NOT NULL DEFAULT '0',
|
||||
PRIMARY KEY (`receiptID`),
|
||||
UNIQUE KEY `documentID` (`documentID`,`version`,`type`,`required`),
|
||||
CONSTRAINT `tblDocumentRecipients_document` FOREIGN KEY (`documentID`) REFERENCES `tblDocuments` (`id`) ON DELETE CASCADE
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
||||
CREATE INDEX `indDocumentRecipientsRequired` ON `tblDocumentRecipients` (`required`);
|
||||
|
||||
-- --------------------------------------------------------
|
||||
|
||||
--
|
||||
-- Table structure for table `tblDocumentReceiptLog`
|
||||
--
|
||||
|
||||
CREATE TABLE `tblDocumentReceiptLog` (
|
||||
`receiptLogID` int(11) NOT NULL AUTO_INCREMENT,
|
||||
`receiptID` int(11) NOT NULL DEFAULT '0',
|
||||
`status` tinyint(4) NOT NULL DEFAULT '0',
|
||||
`comment` text NOT NULL,
|
||||
`date` datetime NOT NULL,
|
||||
`userID` int(11) NOT NULL DEFAULT '0',
|
||||
PRIMARY KEY (`receiptLogID`),
|
||||
KEY `tblDocumentReceiptLog_receipt` (`receiptID`),
|
||||
KEY `tblDocumentReceiptLog_user` (`userID`),
|
||||
CONSTRAINT `tblDocumentReceiptLog_recipient` FOREIGN KEY (`receiptID`) REFERENCES `tblDocumentRecipients` (`receiptID`) ON DELETE CASCADE,
|
||||
CONSTRAINT `tblDocumentReceiptLog_user` FOREIGN KEY (`userID`) REFERENCES `tblUsers` (`id`) ON DELETE CASCADE
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
||||
|
||||
-- --------------------------------------------------------
|
||||
|
||||
--
|
||||
-- Table structure for table `tblDocumentRevisors`
|
||||
--
|
||||
|
||||
CREATE TABLE `tblDocumentRevisors` (
|
||||
`revisionID` int(11) NOT NULL AUTO_INCREMENT,
|
||||
`documentID` int(11) NOT NULL DEFAULT '0',
|
||||
`version` smallint(5) unsigned NOT NULL DEFAULT '0',
|
||||
`type` tinyint(4) NOT NULL DEFAULT '0',
|
||||
`required` int(11) NOT NULL DEFAULT '0',
|
||||
`startdate` datetime DEFAULT NULL,
|
||||
PRIMARY KEY (`revisionID`),
|
||||
UNIQUE KEY `documentID` (`documentID`,`version`,`type`,`required`),
|
||||
CONSTRAINT `tblDocumentRevisors_document` FOREIGN KEY (`documentID`) REFERENCES `tblDocuments` (`id`) ON DELETE CASCADE
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
||||
CREATE INDEX `indDocumentRevisorsRequired` ON `tblDocumentRevisors` (`required`);
|
||||
|
||||
-- --------------------------------------------------------
|
||||
|
||||
--
|
||||
-- Table structure for table `tblDocumentRevisionLog`
|
||||
--
|
||||
|
||||
CREATE TABLE `tblDocumentRevisionLog` (
|
||||
`revisionLogID` int(11) NOT NULL AUTO_INCREMENT,
|
||||
`revisionID` int(11) NOT NULL DEFAULT '0',
|
||||
`status` tinyint(4) NOT NULL DEFAULT '0',
|
||||
`comment` text NOT NULL,
|
||||
`date` datetime NOT NULL,
|
||||
`userID` int(11) NOT NULL DEFAULT '0',
|
||||
PRIMARY KEY (`revisionLogID`),
|
||||
KEY `tblDocumentRevisionLog_revision` (`revisionID`),
|
||||
KEY `tblDocumentRevisionLog_user` (`userID`),
|
||||
CONSTRAINT `tblDocumentRevisionLog_revision` FOREIGN KEY (`revisionID`) REFERENCES `tblDocumentRevisors` (`revisionID`) ON DELETE CASCADE,
|
||||
CONSTRAINT `tblDocumentRevisionLog_user` FOREIGN KEY (`userID`) REFERENCES `tblUsers` (`id`) ON DELETE CASCADE
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
||||
|
||||
-- --------------------------------------------------------
|
||||
|
||||
--
|
||||
-- Table structure for table `tblDocumentStatus`
|
||||
--
|
||||
|
|
@ -608,6 +738,7 @@ CREATE TABLE `tblWorkflows` (
|
|||
`id` int(11) NOT NULL AUTO_INCREMENT,
|
||||
`name` text NOT NULL,
|
||||
`initstate` int(11) NOT NULL,
|
||||
`layoutdata` text DEFAULT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `tblWorkflow_initstate` (`initstate`),
|
||||
CONSTRAINT `tblWorkflow_initstate` FOREIGN KEY (`initstate`) REFERENCES `tblWorkflowStates` (`id`) ON DELETE CASCADE
|
||||
|
|
@ -674,53 +805,52 @@ CREATE TABLE `tblWorkflowTransitionGroups` (
|
|||
|
||||
-- --------------------------------------------------------
|
||||
|
||||
--
|
||||
-- Table structure for table `tblWorkflowLog`
|
||||
--
|
||||
|
||||
CREATE TABLE `tblWorkflowLog` (
|
||||
`id` int(11) NOT NULL AUTO_INCREMENT,
|
||||
`document` int(11) DEFAULT NULL,
|
||||
`version` smallint(5) DEFAULT NULL,
|
||||
`workflow` int(11) DEFAULT NULL,
|
||||
`userid` int(11) DEFAULT NULL,
|
||||
`transition` int(11) DEFAULT NULL,
|
||||
`date` datetime NOT NULL,
|
||||
`comment` text,
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `tblWorkflowLog_document` (`document`),
|
||||
KEY `tblWorkflowLog_workflow` (`workflow`),
|
||||
KEY `tblWorkflowLog_userid` (`userid`),
|
||||
KEY `tblWorkflowLog_transition` (`transition`),
|
||||
CONSTRAINT `tblWorkflowLog_document` FOREIGN KEY (`document`) REFERENCES `tblDocuments` (`id`) ON DELETE CASCADE,
|
||||
CONSTRAINT `tblWorkflowLog_transition` FOREIGN KEY (`transition`) REFERENCES `tblWorkflowTransitions` (`id`) ON DELETE CASCADE,
|
||||
CONSTRAINT `tblWorkflowLog_userid` FOREIGN KEY (`userid`) REFERENCES `tblUsers` (`id`) ON DELETE CASCADE,
|
||||
CONSTRAINT `tblWorkflowLog_workflow` FOREIGN KEY (`workflow`) REFERENCES `tblWorkflows` (`id`) ON DELETE CASCADE
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
||||
|
||||
-- --------------------------------------------------------
|
||||
|
||||
--
|
||||
-- Table structure for table `tblWorkflowDocumentContent`
|
||||
--
|
||||
|
||||
CREATE TABLE `tblWorkflowDocumentContent` (
|
||||
`parentworkflow` int(11) DEFAULT '0',
|
||||
`id` int(11) NOT NULL AUTO_INCREMENT,
|
||||
`parent` int(11) DEFAULT NULL,
|
||||
`workflow` int(11) DEFAULT NULL,
|
||||
`document` int(11) DEFAULT NULL,
|
||||
`version` smallint(5) DEFAULT NULL,
|
||||
`state` int(11) DEFAULT NULL,
|
||||
`date` datetime NOT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `tblWorkflowDocument_document` (`document`),
|
||||
KEY `tblWorkflowDocument_workflow` (`workflow`),
|
||||
KEY `tblWorkflowDocument_state` (`state`),
|
||||
CONSTRAINT `tblWorkflowDocument_document` FOREIGN KEY (`document`) REFERENCES `tblDocuments` (`id`) ON DELETE CASCADE,
|
||||
CONSTRAINT `tblWorkflowDocument_state` FOREIGN KEY (`state`) REFERENCES `tblWorkflowStates` (`id`) ON DELETE CASCADE,
|
||||
CONSTRAINT `tblWorkflowDocumentContent_parent` FOREIGN KEY (`parent`) REFERENCES `tblWorkflowDocumentContent` (`id`) ON DELETE CASCADE,
|
||||
CONSTRAINT `tblWorkflowDocument_workflow` FOREIGN KEY (`workflow`) REFERENCES `tblWorkflows` (`id`) ON DELETE CASCADE
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
||||
|
||||
-- --------------------------------------------------------
|
||||
|
||||
--
|
||||
-- Table structure for table `tblWorkflowLog`
|
||||
--
|
||||
|
||||
CREATE TABLE `tblWorkflowLog` (
|
||||
`id` int(11) NOT NULL AUTO_INCREMENT,
|
||||
`workflowdocumentcontent` int(11) NOT NULL DEFAULT '0',
|
||||
`userid` int(11) DEFAULT NULL,
|
||||
`transition` int(11) DEFAULT NULL,
|
||||
`date` datetime NOT NULL,
|
||||
`comment` text,
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `tblWorkflowLog_userid` (`userid`),
|
||||
KEY `tblWorkflowLog_transition` (`transition`),
|
||||
KEY `tblWorkflowLog_workflowdocumentcontent` (`workflowdocumentcontent`),
|
||||
CONSTRAINT `tblWorkflowLog_workflowdocumentcontent` FOREIGN KEY (`workflowdocumentcontent`) REFERENCES `tblWorkflowDocumentContent` (`id`) ON DELETE CASCADE,
|
||||
CONSTRAINT `tblWorkflowLog_transition` FOREIGN KEY (`transition`) REFERENCES `tblWorkflowTransitions` (`id`) ON DELETE CASCADE,
|
||||
CONSTRAINT `tblWorkflowLog_userid` FOREIGN KEY (`userid`) REFERENCES `tblUsers` (`id`) ON DELETE CASCADE
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
||||
|
||||
-- --------------------------------------------------------
|
||||
|
||||
--
|
||||
-- Table structure for table `tblWorkflowMandatoryWorkflow`
|
||||
--
|
||||
|
|
@ -736,6 +866,127 @@ CREATE TABLE `tblWorkflowMandatoryWorkflow` (
|
|||
|
||||
-- --------------------------------------------------------
|
||||
|
||||
--
|
||||
-- Table structure for transmittal
|
||||
--
|
||||
|
||||
CREATE TABLE `tblTransmittals` (
|
||||
`id` int(11) NOT NULL AUTO_INCREMENT,
|
||||
`name` text NOT NULL,
|
||||
`comment` text NOT NULL,
|
||||
`userID` int(11) NOT NULL DEFAULT '0',
|
||||
`date` datetime DEFAULT NULL,
|
||||
`public` tinyint(1) NOT NULL DEFAULT '0',
|
||||
PRIMARY KEY (`id`),
|
||||
CONSTRAINT `tblTransmittals_user` FOREIGN KEY (`userID`) REFERENCES `tblUsers` (`id`) ON DELETE CASCADE
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
||||
|
||||
-- --------------------------------------------------------
|
||||
|
||||
--
|
||||
-- Table structure for transmittal item
|
||||
--
|
||||
|
||||
CREATE TABLE `tblTransmittalItems` (
|
||||
`id` int(11) NOT NULL AUTO_INCREMENT,
|
||||
`transmittal` int(11) NOT NULL DEFAULT '0',
|
||||
`document` int(11) DEFAULT NULL,
|
||||
`version` smallint(5) unsigned NOT NULL DEFAULT '0',
|
||||
`date` datetime DEFAULT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE (transmittal, document, version),
|
||||
CONSTRAINT `tblTransmittalItems_document` FOREIGN KEY (`document`) REFERENCES `tblDocuments` (`id`) ON DELETE CASCADE,
|
||||
CONSTRAINT `tblTransmittalItem_transmittal` FOREIGN KEY (`transmittal`) REFERENCES `tblTransmittals` (`id`) ON DELETE CASCADE
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
||||
|
||||
-- --------------------------------------------------------
|
||||
|
||||
--
|
||||
-- Table structure for cached read access
|
||||
--
|
||||
|
||||
CREATE TABLE `tblCachedAccess` (
|
||||
`id` int(11) NOT NULL AUTO_INCREMENT,
|
||||
`document` int(11) DEFAULT NULL,
|
||||
`user` int(11) DEFAULT null,
|
||||
`mode` tinyint(4) NOT NULL DEFAULT '0',
|
||||
PRIMARY KEY (`id`),
|
||||
CONSTRAINT `tblCachedAccess_document` FOREIGN KEY (`document`) REFERENCES `tblDocuments` (`id`) ON DELETE CASCADE,
|
||||
CONSTRAINT `tblCachedAccess_user` FOREIGN KEY (`user`) REFERENCES `tblUsers` (`id`) ON DELETE CASCADE
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
||||
|
||||
-- --------------------------------------------------------
|
||||
|
||||
--
|
||||
-- Table structure for access request objects
|
||||
--
|
||||
|
||||
CREATE TABLE `tblAros` (
|
||||
`id` int(11) NOT NULL AUTO_INCREMENT,
|
||||
`parent` int(11),
|
||||
`model` text NOT NULL,
|
||||
`foreignid` int(11) NOT NULL DEFAULT '0',
|
||||
`alias` varchar(255),
|
||||
PRIMARY KEY (`id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
||||
|
||||
-- --------------------------------------------------------
|
||||
|
||||
--
|
||||
-- Table structure for access control objects
|
||||
--
|
||||
|
||||
CREATE TABLE `tblAcos` (
|
||||
`id` int(11) NOT NULL AUTO_INCREMENT,
|
||||
`parent` int(11),
|
||||
`model` text NOT NULL,
|
||||
`foreignid` int(11) NOT NULL DEFAULT '0',
|
||||
`alias` varchar(255),
|
||||
PRIMARY KEY (`id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
||||
|
||||
-- --------------------------------------------------------
|
||||
|
||||
--
|
||||
-- Table structure for acos/aros relation
|
||||
--
|
||||
|
||||
CREATE TABLE `tblArosAcos` (
|
||||
`id` int(11) NOT NULL AUTO_INCREMENT,
|
||||
`aro` int(11) NOT NULL DEFAULT '0',
|
||||
`aco` int(11) NOT NULL DEFAULT '0',
|
||||
`create` tinyint(4) NOT NULL DEFAULT '-1',
|
||||
`read` tinyint(4) NOT NULL DEFAULT '-1',
|
||||
`update` tinyint(4) NOT NULL DEFAULT '-1',
|
||||
`delete` tinyint(4) NOT NULL DEFAULT '-1',
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE (aco, aro),
|
||||
CONSTRAINT `tblArosAcos_acos` FOREIGN KEY (`aco`) REFERENCES `tblAcos` (`id`) ON DELETE CASCADE,
|
||||
CONSTRAINT `tblArosAcos_aros` FOREIGN KEY (`aro`) REFERENCES `tblAros` (`id`) ON DELETE CASCADE
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
||||
|
||||
-- --------------------------------------------------------
|
||||
|
||||
--
|
||||
-- Table structure for table `tblSchedulerTask`
|
||||
--
|
||||
|
||||
CREATE TABLE `tblSchedulerTask` (
|
||||
`id` int(11) NOT NULL AUTO_INCREMENT,
|
||||
`name` varchar(100) DEFAULT NULL,
|
||||
`description` text DEFAULT NULL,
|
||||
`disabled` smallint(1) NOT NULL DEFAULT '0',
|
||||
`extension` varchar(100) DEFAULT NULL,
|
||||
`task` varchar(100) DEFAULT NULL,
|
||||
`frequency` varchar(100) DEFAULT NULL,
|
||||
`params` text DEFAULT NULL,
|
||||
`nextrun` datetime DEFAULT NULL,
|
||||
`lastrun` datetime DEFAULT NULL,
|
||||
PRIMARY KEY (`id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
||||
|
||||
-- --------------------------------------------------------
|
||||
|
||||
--
|
||||
-- Table structure for table `tblVersion`
|
||||
--
|
||||
|
|
@ -753,7 +1004,10 @@ CREATE TABLE `tblVersion` (
|
|||
-- Initial content for database
|
||||
--
|
||||
|
||||
INSERT INTO tblUsers VALUES (1, 'admin', '21232f297a57a5a743894a0e4a801fc3', 'Administrator', 'info@seeddms.org', '', '', '', 1, 0, NULL, 0, 0, 0, NULL);
|
||||
INSERT INTO tblUsers VALUES (2, 'guest', NULL, 'Guest User', NULL, '', '', '', 2, 0, NULL, 0, 0, 0, NULL);
|
||||
INSERT INTO `tblRoles` (`id`, `name`, `role`) VALUES (1, 'Admin', 1);
|
||||
INSERT INTO `tblRoles` (`id`, `name`, `role`) VALUES (2, 'Guest', 2);
|
||||
INSERT INTO `tblRoles` (`id`, `name`, `role`) VALUES (3, 'User', 0);
|
||||
INSERT INTO tblUsers VALUES (1, 'admin', '21232f297a57a5a743894a0e4a801fc3', '', 'Administrator', 'info@seeddms.org', '', '', '', 1, 0, NULL, 0, 0, 0, NULL);
|
||||
INSERT INTO tblUsers VALUES (2, 'guest', NULL, '', 'Guest User', NULL, '', '', '', 2, 0, NULL, 0, 0, 0, NULL);
|
||||
INSERT INTO tblFolders VALUES (1, 'DMS', 0, '', 'DMS root', UNIX_TIMESTAMP(), 1, 0, 2, 0);
|
||||
INSERT INTO tblVersion VALUES (NOW(), 5, 1, 0);
|
||||
INSERT INTO tblVersion VALUES (NOW(), 6, 0, 0);
|
||||
|
|
|
|||
|
|
@ -43,6 +43,19 @@ CREATE TABLE "tblAttributeDefinitions" (
|
|||
|
||||
-- --------------------------------------------------------
|
||||
|
||||
--
|
||||
-- Table structure for table `tblRoles`
|
||||
--
|
||||
|
||||
CREATE TABLE "tblRoles" (
|
||||
"id" SERIAL UNIQUE,
|
||||
"name" varchar(50) default NULL,
|
||||
"role" INTEGER NOT NULL default '0',
|
||||
"noaccess" varchar(30) NOT NULL default ''
|
||||
) ;
|
||||
|
||||
-- --------------------------------------------------------
|
||||
|
||||
--
|
||||
-- Table structure for table "tblUsers"
|
||||
--
|
||||
|
|
@ -51,6 +64,7 @@ CREATE TABLE "tblUsers" (
|
|||
"id" SERIAL UNIQUE,
|
||||
"login" varchar(50) default NULL,
|
||||
"pwd" varchar(50) default NULL,
|
||||
"secret" varchar(50) default NULL,
|
||||
"fullName" varchar(100) default NULL,
|
||||
"email" varchar(70) default NULL,
|
||||
"language" varchar(32) NOT NULL,
|
||||
|
|
@ -68,6 +82,18 @@ CREATE TABLE "tblUsers" (
|
|||
|
||||
-- --------------------------------------------------------
|
||||
|
||||
--
|
||||
-- Table structure for table `tblUserSubstitutes`
|
||||
--
|
||||
|
||||
CREATE TABLE "tblUserSubstitutes" (
|
||||
"id" SERIAL UNIQUE,
|
||||
"user" INTEGER NOT NULL default '0' REFERENCES "tblUsers" ("id") ON DELETE CASCADE,
|
||||
"substitute" INTEGER NOT NULL default '0' REFERENCES "tblUsers" ("id") ON DELETE CASCADE
|
||||
);
|
||||
|
||||
-- --------------------------------------------------------
|
||||
|
||||
--
|
||||
-- Table structure for table "tblUserPasswordRequest"
|
||||
--
|
||||
|
|
@ -225,6 +251,7 @@ CREATE TABLE "tblDocumentContent" (
|
|||
"mimeType" varchar(100) NOT NULL default '',
|
||||
"fileSize" BIGINT,
|
||||
"checksum" char(32),
|
||||
"revisiondate" TIMESTAMP default NULL,
|
||||
UNIQUE ("document","version")
|
||||
) ;
|
||||
|
||||
|
|
@ -290,6 +317,21 @@ CREATE TABLE "tblDocumentLocks" (
|
|||
|
||||
-- --------------------------------------------------------
|
||||
|
||||
--
|
||||
-- Table structure for table `tblDocumentCheckOuts`
|
||||
--
|
||||
|
||||
CREATE TABLE "tblDocumentCheckOuts" (
|
||||
"document" INTEGER REFERENCES "tblDocuments" ("id") ON DELETE CASCADE,
|
||||
"version" INTEGER NOT NULL default '0',
|
||||
"userID" INTEGER NOT NULL default '0' REFERENCES "tblUsers" ("id"),
|
||||
"date" TEXT NOT NULL,
|
||||
"filename" varchar(255) NOT NULL default '',
|
||||
UNIQUE ("document")
|
||||
) ;
|
||||
|
||||
-- --------------------------------------------------------
|
||||
|
||||
--
|
||||
-- Table structure for table "tblDocumentReviewers"
|
||||
--
|
||||
|
|
@ -320,6 +362,67 @@ CREATE TABLE "tblDocumentReviewLog" (
|
|||
|
||||
-- --------------------------------------------------------
|
||||
|
||||
--
|
||||
-- Table structure for table `tblDocumentRecipients`
|
||||
--
|
||||
|
||||
CREATE TABLE "tblDocumentRecipients" (
|
||||
"receiptID" SERIAL UNIQUE,
|
||||
"documentID" INTEGER NOT NULL default '0' REFERENCES "tblDocuments" ("id") ON DELETE CASCADE,
|
||||
"version" INTEGER NOT NULL default '0',
|
||||
"type" INTEGER NOT NULL default '0',
|
||||
"required" INTEGER NOT NULL default '0',
|
||||
UNIQUE ("documentID","version","type","required")
|
||||
) ;
|
||||
|
||||
-- --------------------------------------------------------
|
||||
|
||||
--
|
||||
-- Table structure for table "tblDocumentReceiptLog"
|
||||
--
|
||||
|
||||
CREATE TABLE "tblDocumentReceiptLog" (
|
||||
"receiptLogID" SERIAL UNIQUE,
|
||||
"receiptID" INTEGER NOT NULL default 0 REFERENCES "tblDocumentRecipients" ("receiptID") ON DELETE CASCADE,
|
||||
"status" INTEGER NOT NULL default 0,
|
||||
"comment" TEXT NOT NULL,
|
||||
"date" TEXT NOT NULL,
|
||||
"userID" INTEGER NOT NULL default 0 REFERENCES "tblUsers" ("id") ON DELETE CASCADE
|
||||
) ;
|
||||
|
||||
-- --------------------------------------------------------
|
||||
|
||||
--
|
||||
-- Table structure for table `tblDocumentRevisors`
|
||||
--
|
||||
|
||||
CREATE TABLE "tblDocumentRevisors" (
|
||||
"revisionID" SERIAL UNIQUE,
|
||||
"documentID" INTEGER NOT NULL default '0' REFERENCES "tblDocuments" ("id") ON DELETE CASCADE,
|
||||
"version" INTEGER NOT NULL default '0',
|
||||
"type" INTEGER NOT NULL default '0',
|
||||
"required" INTEGER NOT NULL default '0',
|
||||
"startdate" TIMESTAMP default NULL,
|
||||
UNIQUE ("documentID","version","type","required")
|
||||
) ;
|
||||
|
||||
-- --------------------------------------------------------
|
||||
|
||||
--
|
||||
-- Table structure for table "tblDocumentRevisionLog"
|
||||
--
|
||||
|
||||
CREATE TABLE "tblDocumentRevisionLog" (
|
||||
"revisionLogID" SERIAL UNIQUE,
|
||||
"revisionID" INTEGER NOT NULL default 0 REFERENCES "tblDocumentRevisors" ("revisionID") ON DELETE CASCADE,
|
||||
"status" INTEGER NOT NULL default 0,
|
||||
"comment" TEXT NOT NULL,
|
||||
"date" TIMESTAMP default NULL,
|
||||
"userID" INTEGER NOT NULL default 0 REFERENCES "tblUsers" ("id") ON DELETE CASCADE
|
||||
) ;
|
||||
|
||||
-- --------------------------------------------------------
|
||||
|
||||
--
|
||||
-- Table structure for table "tblDocumentStatus"
|
||||
--
|
||||
|
|
@ -433,7 +536,7 @@ CREATE TABLE "tblSessions" (
|
|||
"theme" varchar(30) NOT NULL default '',
|
||||
"language" varchar(30) NOT NULL default '',
|
||||
"clipboard" text default NULL,
|
||||
"su" INTEGER DEFAULT NULL,
|
||||
"su" INTEGER DEFAULT NULL,
|
||||
"splashmsg" text default NULL
|
||||
) ;
|
||||
|
||||
|
|
@ -514,7 +617,8 @@ CREATE TABLE "tblWorkflowActions" (
|
|||
CREATE TABLE "tblWorkflows" (
|
||||
"id" SERIAL UNIQUE,
|
||||
"name" text NOT NULL,
|
||||
"initstate" INTEGER NOT NULL REFERENCES "tblWorkflowStates" ("id") ON DELETE CASCADE
|
||||
"initstate" INTEGER NOT NULL REFERENCES "tblWorkflowStates" ("id") ON DELETE CASCADE,
|
||||
"layoutdata" text default NULL
|
||||
) ;
|
||||
|
||||
-- --------------------------------------------------------
|
||||
|
|
@ -559,29 +663,13 @@ CREATE TABLE "tblWorkflowTransitionGroups" (
|
|||
|
||||
-- --------------------------------------------------------
|
||||
|
||||
--
|
||||
-- Table structure for workflow log
|
||||
--
|
||||
|
||||
CREATE TABLE "tblWorkflowLog" (
|
||||
"id" SERIAL UNIQUE,
|
||||
"document" INTEGER default NULL REFERENCES "tblDocuments" ("id") ON DELETE CASCADE,
|
||||
"version" INTEGER default NULL,
|
||||
"workflow" INTEGER default NULL REFERENCES "tblWorkflows" ("id") ON DELETE CASCADE,
|
||||
"userid" INTEGER default NULL REFERENCES "tblUsers" ("id") ON DELETE CASCADE,
|
||||
"transition" INTEGER default NULL REFERENCES "tblWorkflowTransitions" ("id") ON DELETE CASCADE,
|
||||
"date" TIMESTAMP default NULL,
|
||||
"comment" text
|
||||
) ;
|
||||
|
||||
-- --------------------------------------------------------
|
||||
|
||||
--
|
||||
-- Table structure for workflow document relation
|
||||
--
|
||||
|
||||
CREATE TABLE "tblWorkflowDocumentContent" (
|
||||
"parentworkflow" INTEGER DEFAULT 0,
|
||||
"id" SERIAL UNIQUE,
|
||||
"parent" INTEGER DEFAULT NULL REFERENCES "tblWorkflowDocumentContent" ("id") ON DELETE CASCADE,
|
||||
"workflow" INTEGER DEFAULT NULL REFERENCES "tblWorkflows" ("id") ON DELETE CASCADE,
|
||||
"document" INTEGER DEFAULT NULL REFERENCES "tblDocuments" ("id") ON DELETE CASCADE,
|
||||
"version" INTEGER DEFAULT NULL,
|
||||
|
|
@ -591,6 +679,21 @@ CREATE TABLE "tblWorkflowDocumentContent" (
|
|||
|
||||
-- --------------------------------------------------------
|
||||
|
||||
--
|
||||
-- Table structure for workflow log
|
||||
--
|
||||
|
||||
CREATE TABLE "tblWorkflowLog" (
|
||||
"id" SERIAL UNIQUE,
|
||||
"workflowdocumentcontent" INTEGER DEFAULT NULL REFERENCES "tblWorkflowDocumentContent" ("id") ON DELETE CASCADE,
|
||||
"userid" INTEGER default NULL REFERENCES "tblUsers" ("id") ON DELETE CASCADE,
|
||||
"transition" INTEGER default NULL REFERENCES "tblWorkflowTransitions" ("id") ON DELETE CASCADE,
|
||||
"date" TIMESTAMP default NULL,
|
||||
"comment" text
|
||||
) ;
|
||||
|
||||
-- --------------------------------------------------------
|
||||
|
||||
--
|
||||
-- Table structure for mandatory workflows
|
||||
--
|
||||
|
|
@ -603,6 +706,101 @@ CREATE TABLE "tblWorkflowMandatoryWorkflow" (
|
|||
|
||||
-- --------------------------------------------------------
|
||||
|
||||
--
|
||||
-- Table structure for transmittal
|
||||
--
|
||||
|
||||
CREATE TABLE "tblTransmittals" (
|
||||
"id" SERIAL UNIQUE,
|
||||
"name" text NOT NULL,
|
||||
"comment" text NOT NULL,
|
||||
"userID" INTEGER NOT NULL default '0' REFERENCES "tblUsers" ("id") ON DELETE CASCADE,
|
||||
"date" TIMESTAMP default NULL,
|
||||
"public" INTEGER NOT NULL default '0'
|
||||
);
|
||||
|
||||
-- --------------------------------------------------------
|
||||
|
||||
--
|
||||
-- Table structure for transmittal item
|
||||
--
|
||||
|
||||
CREATE TABLE "tblTransmittalItems" (
|
||||
"id" SERIAL UNIQUE,
|
||||
"transmittal" INTEGER NOT NULL DEFAULT '0' REFERENCES "tblTransmittals" ("id") ON DELETE CASCADE,
|
||||
"document" INTEGER default NULL REFERENCES "tblDocuments" ("id") ON DELETE CASCADE,
|
||||
"version" INTEGER NOT NULL default '0',
|
||||
"date" TIMESTAMP default NULL,
|
||||
UNIQUE (transmittal, document, version)
|
||||
);
|
||||
|
||||
-- --------------------------------------------------------
|
||||
|
||||
--
|
||||
-- Table structure for access request objects
|
||||
--
|
||||
|
||||
CREATE TABLE "tblAros" (
|
||||
"id" SERIAL UNIQUE,
|
||||
"parent" INTEGER,
|
||||
"model" TEXT NOT NULL,
|
||||
"foreignid" INTEGER NOT NULL DEFAULT '0',
|
||||
"alias" TEXT
|
||||
) ;
|
||||
|
||||
|
||||
-- --------------------------------------------------------
|
||||
|
||||
--
|
||||
-- Table structure for access control objects
|
||||
--
|
||||
|
||||
CREATE TABLE "tblAcos" (
|
||||
"id" SERIAL UNIQUE,
|
||||
"parent" INTEGER,
|
||||
"model" TEXT NOT NULL,
|
||||
"foreignid" INTEGER NOT NULL DEFAULT '0',
|
||||
"alias" TEXT
|
||||
) ;
|
||||
|
||||
-- --------------------------------------------------------
|
||||
|
||||
--
|
||||
-- Table structure for acos/aros relation
|
||||
--
|
||||
|
||||
CREATE TABLE "tblArosAcos" (
|
||||
"id" SERIAL UNIQUE,
|
||||
"aro" INTEGER NOT NULL DEFAULT '0' REFERENCES "tblAros" ("id") ON DELETE CASCADE,
|
||||
"aco" INTEGER NOT NULL DEFAULT '0' REFERENCES "tblAcos" ("id") ON DELETE CASCADE,
|
||||
"create" INTEGER NOT NULL DEFAULT '-1',
|
||||
"read" INTEGER NOT NULL DEFAULT '-1',
|
||||
"update" INTEGER NOT NULL DEFAULT '-1',
|
||||
"delete" INTEGER NOT NULL DEFAULT '-1',
|
||||
UNIQUE (aco, aro)
|
||||
) ;
|
||||
|
||||
-- --------------------------------------------------------
|
||||
|
||||
--
|
||||
-- Table structure for tblSchedulerTask
|
||||
--
|
||||
|
||||
CREATE TABLE "tblSchedulerTask" (
|
||||
"id" SERIAL UNIQUE,
|
||||
"name" varchar(100) DEFAULT NULL,
|
||||
"description" TEXT DEFAULT NULL,
|
||||
"disabled" INTEGER NOT NULL DEFAULT '0',
|
||||
"extension" varchar(100) DEFAULT NULL,
|
||||
"task" varchar(100) DEFAULT NULL,
|
||||
"frequency" varchar(100) DEFAULT NULL,
|
||||
"params" TEXT DEFAULT NULL,
|
||||
"nextrun" TIMESTAMP DEFAULT NULL,
|
||||
"lastrun" TIMESTAMP DEFAULT NULL
|
||||
) ;
|
||||
|
||||
-- --------------------------------------------------------
|
||||
|
||||
--
|
||||
-- Table structure for version
|
||||
--
|
||||
|
|
@ -620,10 +818,16 @@ CREATE TABLE "tblVersion" (
|
|||
-- Initial content for database
|
||||
--
|
||||
|
||||
INSERT INTO "tblUsers" VALUES (1, 'admin', '21232f297a57a5a743894a0e4a801fc3', 'Administrator', 'info@seeddms.org', '', '', '', 1, 0, NULL, 0, 0, 0, NULL);
|
||||
INSERT INTO "tblRoles" ("id", "name", "role") VALUES (1, 'Admin', 1);
|
||||
SELECT nextval('"tblRoles_id_seq"');
|
||||
INSERT INTO "tblRoles" ("id", "name", "role") VALUES (2, 'Guest', 2);
|
||||
SELECT nextval('"tblRoles_id_seq"');
|
||||
INSERT INTO "tblRoles" ("id", "name", "role") VALUES (3, 'User', 0);
|
||||
SELECT nextval('"tblRoles_id_seq"');
|
||||
INSERT INTO "tblUsers" VALUES (1, 'admin', '21232f297a57a5a743894a0e4a801fc3', '', 'Administrator', 'info@seeddms.org', '', '', '', 1, 0, NULL, 0, 0, 0, NULL);
|
||||
SELECT nextval('"tblUsers_id_seq"');
|
||||
INSERT INTO "tblUsers" VALUES (2, 'guest', NULL, 'Guest User', NULL, '', '', '', 2, 0, NULL, 0, 0, 0, NULL);
|
||||
INSERT INTO "tblUsers" VALUES (2, 'guest', NULL, '', 'Guest User', NULL, '', '', '', 2, 0, NULL, 0, 0, 0, NULL);
|
||||
SELECT nextval('"tblUsers_id_seq"');
|
||||
INSERT INTO "tblFolders" VALUES (1, 'DMS', 0, '', 'DMS root', extract(epoch from now()), 1, 0, 2, 0);
|
||||
SELECT nextval('"tblFolders_id_seq"');
|
||||
INSERT INTO "tblVersion" VALUES (CURRENT_TIMESTAMP, 5, 1, 0);
|
||||
INSERT INTO "tblVersion" VALUES (CURRENT_TIMESTAMP, 6, 0, 0);
|
||||
|
|
|
|||
|
|
@ -43,6 +43,20 @@ CREATE TABLE `tblAttributeDefinitions` (
|
|||
|
||||
-- --------------------------------------------------------
|
||||
|
||||
--
|
||||
-- Table structure for table `tblRoles`
|
||||
--
|
||||
|
||||
CREATE TABLE `tblRoles` (
|
||||
`id` INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
`name` varchar(50) default NULL,
|
||||
`role` INTEGER NOT NULL default '0',
|
||||
`noaccess` varchar(30) NOT NULL default '',
|
||||
UNIQUE (`name`)
|
||||
) ;
|
||||
|
||||
-- --------------------------------------------------------
|
||||
|
||||
--
|
||||
-- Table structure for table `tblUsers`
|
||||
--
|
||||
|
|
@ -51,12 +65,13 @@ CREATE TABLE `tblUsers` (
|
|||
`id` INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
`login` varchar(50) default NULL,
|
||||
`pwd` varchar(50) default NULL,
|
||||
`secret` varchar(50) default NULL,
|
||||
`fullName` varchar(100) default NULL,
|
||||
`email` varchar(70) default NULL,
|
||||
`language` varchar(32) NOT NULL,
|
||||
`theme` varchar(32) NOT NULL,
|
||||
`comment` text NOT NULL,
|
||||
`role` INTEGER NOT NULL default '0',
|
||||
`role` INTEGER NOT NULL REFERENCES `tblRoles` (`id`),
|
||||
`hidden` INTEGER NOT NULL default '0',
|
||||
`pwdExpiration` TEXT default NULL,
|
||||
`loginfailures` INTEGER NOT NULL default '0',
|
||||
|
|
@ -68,6 +83,19 @@ CREATE TABLE `tblUsers` (
|
|||
|
||||
-- --------------------------------------------------------
|
||||
|
||||
--
|
||||
-- Table structure for table `tblUserSubstitutes`
|
||||
--
|
||||
|
||||
CREATE TABLE `tblUserSubstitutes` (
|
||||
`id` INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
`user` INTEGER NOT NULL default '0' REFERENCES `tblUsers` (`id`) ON DELETE CASCADE,
|
||||
`substitute` INTEGER NOT NULL default '0' REFERENCES `tblUsers` (`id`) ON DELETE CASCADE,
|
||||
UNIQUE (`user`, `substitute`)
|
||||
);
|
||||
|
||||
-- --------------------------------------------------------
|
||||
|
||||
--
|
||||
-- Table structure for table `tblUserPasswordRequest`
|
||||
--
|
||||
|
|
@ -135,7 +163,7 @@ CREATE TABLE `tblFolderAttributes` (
|
|||
`folder` INTEGER default NULL REFERENCES `tblFolders` (`id`) ON DELETE CASCADE,
|
||||
`attrdef` INTEGER default NULL REFERENCES `tblAttributeDefinitions` (`id`),
|
||||
`value` text default NULL,
|
||||
UNIQUE (folder, attrdef)
|
||||
UNIQUE (`folder`, `attrdef`)
|
||||
) ;
|
||||
|
||||
-- --------------------------------------------------------
|
||||
|
|
@ -171,7 +199,7 @@ CREATE TABLE `tblDocumentAttributes` (
|
|||
`document` INTEGER default NULL REFERENCES `tblDocuments` (`id`) ON DELETE CASCADE,
|
||||
`attrdef` INTEGER default NULL REFERENCES `tblAttributeDefinitions` (`id`),
|
||||
`value` text default NULL,
|
||||
UNIQUE (document, attrdef)
|
||||
UNIQUE (`document`, `attrdef`)
|
||||
) ;
|
||||
|
||||
-- --------------------------------------------------------
|
||||
|
|
@ -188,6 +216,7 @@ CREATE TABLE `tblDocumentApprovers` (
|
|||
`required` INTEGER NOT NULL default '0',
|
||||
UNIQUE (`documentID`,`version`,`type`,`required`)
|
||||
) ;
|
||||
CREATE INDEX `indDocumentApproversRequired` ON `tblDocumentApprovers` (`required`);
|
||||
|
||||
-- --------------------------------------------------------
|
||||
|
||||
|
|
@ -203,6 +232,7 @@ CREATE TABLE `tblDocumentApproveLog` (
|
|||
`date` TEXT NOT NULL,
|
||||
`userID` INTEGER NOT NULL default '0' REFERENCES `tblUsers` (`id`) ON DELETE CASCADE
|
||||
) ;
|
||||
CREATE INDEX `indDocumentApproveLogApproveID` ON `tblDocumentApproveLog` (`approveID`);
|
||||
|
||||
-- --------------------------------------------------------
|
||||
|
||||
|
|
@ -223,6 +253,7 @@ CREATE TABLE `tblDocumentContent` (
|
|||
`mimeType` varchar(100) NOT NULL default '',
|
||||
`fileSize` INTEGER,
|
||||
`checksum` char(32),
|
||||
`revisiondate` TEXT default NULL,
|
||||
UNIQUE (`document`,`version`)
|
||||
) ;
|
||||
|
||||
|
|
@ -237,7 +268,7 @@ CREATE TABLE `tblDocumentContentAttributes` (
|
|||
`content` INTEGER default NULL REFERENCES `tblDocumentContent` (`id`) ON DELETE CASCADE,
|
||||
`attrdef` INTEGER default NULL REFERENCES `tblAttributeDefinitions` (`id`),
|
||||
`value` text default NULL,
|
||||
UNIQUE (content, attrdef)
|
||||
UNIQUE (`content`, `attrdef`)
|
||||
) ;
|
||||
|
||||
-- --------------------------------------------------------
|
||||
|
|
@ -288,6 +319,21 @@ CREATE TABLE `tblDocumentLocks` (
|
|||
|
||||
-- --------------------------------------------------------
|
||||
|
||||
--
|
||||
-- Table structure for table `tblDocumentCheckOuts`
|
||||
--
|
||||
|
||||
CREATE TABLE `tblDocumentCheckOuts` (
|
||||
`document` INTEGER REFERENCES `tblDocuments` (`id`) ON DELETE CASCADE,
|
||||
`version` INTEGER unsigned NOT NULL default '0',
|
||||
`userID` INTEGER NOT NULL default '0' REFERENCES `tblUsers` (`id`),
|
||||
`date` TEXT NOT NULL,
|
||||
`filename` varchar(255) NOT NULL default '',
|
||||
UNIQUE (`document`)
|
||||
) ;
|
||||
|
||||
-- --------------------------------------------------------
|
||||
|
||||
--
|
||||
-- Table structure for table `tblDocumentReviewers`
|
||||
--
|
||||
|
|
@ -300,6 +346,7 @@ CREATE TABLE `tblDocumentReviewers` (
|
|||
`required` INTEGER NOT NULL default '0',
|
||||
UNIQUE (`documentID`,`version`,`type`,`required`)
|
||||
) ;
|
||||
CREATE INDEX `indDocumentReviewersRequired` ON `tblDocumentReviewers` (`required`);
|
||||
|
||||
-- --------------------------------------------------------
|
||||
|
||||
|
|
@ -315,6 +362,72 @@ CREATE TABLE `tblDocumentReviewLog` (
|
|||
`date` TEXT NOT NULL,
|
||||
`userID` INTEGER NOT NULL default 0 REFERENCES `tblUsers` (`id`) ON DELETE CASCADE
|
||||
) ;
|
||||
CREATE INDEX `indDocumentReviewLogReviewID` ON `tblDocumentReviewLog` (`reviewID`);
|
||||
|
||||
-- --------------------------------------------------------
|
||||
|
||||
--
|
||||
-- Table structure for table `tblDocumentRecipients`
|
||||
--
|
||||
|
||||
CREATE TABLE `tblDocumentRecipients` (
|
||||
`receiptID` INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
`documentID` INTEGER NOT NULL default '0' REFERENCES `tblDocuments` (`id`) ON DELETE CASCADE,
|
||||
`version` INTEGER unsigned NOT NULL default '0',
|
||||
`type` INTEGER NOT NULL default '0',
|
||||
`required` INTEGER NOT NULL default '0',
|
||||
UNIQUE (`documentID`,`version`,`type`,`required`)
|
||||
) ;
|
||||
CREATE INDEX `indDocumentRecipientsRequired` ON `tblDocumentRecipients` (`required`);
|
||||
|
||||
-- --------------------------------------------------------
|
||||
|
||||
--
|
||||
-- Table structure for table `tblDocumentReceiptLog`
|
||||
--
|
||||
|
||||
CREATE TABLE `tblDocumentReceiptLog` (
|
||||
`receiptLogID` INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
`receiptID` INTEGER NOT NULL default 0 REFERENCES `tblDocumentRecipients` (`receiptID`) ON DELETE CASCADE,
|
||||
`status` INTEGER NOT NULL default 0,
|
||||
`comment` TEXT NOT NULL,
|
||||
`date` TEXT NOT NULL,
|
||||
`userID` INTEGER NOT NULL default 0 REFERENCES `tblUsers` (`id`) ON DELETE CASCADE
|
||||
) ;
|
||||
CREATE INDEX `indDocumentReceiptLogReceiptID` ON `tblDocumentReceiptLog` (`receiptID`);
|
||||
|
||||
-- --------------------------------------------------------
|
||||
|
||||
--
|
||||
-- Table structure for table `tblDocumentRevisors`
|
||||
--
|
||||
|
||||
CREATE TABLE `tblDocumentRevisors` (
|
||||
`revisionID` INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
`documentID` INTEGER NOT NULL default '0' REFERENCES `tblDocuments` (`id`) ON DELETE CASCADE,
|
||||
`version` INTEGER unsigned NOT NULL default '0',
|
||||
`type` INTEGER NOT NULL default '0',
|
||||
`required` INTEGER NOT NULL default '0',
|
||||
`startdate` TEXT default NULL,
|
||||
UNIQUE (`documentID`,`version`,`type`,`required`)
|
||||
) ;
|
||||
CREATE INDEX `indDocumentRevisorsRequired` ON `tblDocumentRevisors` (`required`);
|
||||
|
||||
-- --------------------------------------------------------
|
||||
|
||||
--
|
||||
-- Table structure for table `tblDocumentRevisionLog`
|
||||
--
|
||||
|
||||
CREATE TABLE `tblDocumentRevisionLog` (
|
||||
`revisionLogID` INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
`revisionID` INTEGER NOT NULL default 0 REFERENCES `tblDocumentRevisors` (`revisionID`) ON DELETE CASCADE,
|
||||
`status` INTEGER NOT NULL default 0,
|
||||
`comment` TEXT NOT NULL,
|
||||
`date` TEXT NOT NULL,
|
||||
`userID` INTEGER NOT NULL default 0 REFERENCES `tblUsers` (`id`) ON DELETE CASCADE
|
||||
) ;
|
||||
CREATE INDEX `indDocumentRevisionLogRevisionID` ON `tblDocumentRevisionLog` (`revisionID`);
|
||||
|
||||
-- --------------------------------------------------------
|
||||
|
||||
|
|
@ -343,6 +456,7 @@ CREATE TABLE `tblDocumentStatusLog` (
|
|||
`date` TEXT NOT NULL,
|
||||
`userID` INTEGER NOT NULL default '0' REFERENCES `tblUsers` (`id`) ON DELETE CASCADE
|
||||
) ;
|
||||
CREATE INDEX `indDocumentStatusLogStatusID` ON `tblDocumentStatusLog` (`StatusID`);
|
||||
|
||||
-- --------------------------------------------------------
|
||||
|
||||
|
|
@ -512,7 +626,8 @@ CREATE TABLE `tblWorkflowActions` (
|
|||
CREATE TABLE `tblWorkflows` (
|
||||
`id` INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
`name` text NOT NULL,
|
||||
`initstate` INTEGER NOT NULL REFERENCES `tblWorkflowStates` (`id`) ON DELETE CASCADE
|
||||
`initstate` INTEGER NOT NULL REFERENCES `tblWorkflowStates` (`id`) ON DELETE CASCADE,
|
||||
`layoutdata` text default NULL
|
||||
) ;
|
||||
|
||||
-- --------------------------------------------------------
|
||||
|
|
@ -557,29 +672,13 @@ CREATE TABLE `tblWorkflowTransitionGroups` (
|
|||
|
||||
-- --------------------------------------------------------
|
||||
|
||||
--
|
||||
-- Table structure for table `tblWorkflowLog`
|
||||
--
|
||||
|
||||
CREATE TABLE `tblWorkflowLog` (
|
||||
`id` INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
`document` INTEGER default NULL REFERENCES `tblDocuments` (`id`) ON DELETE CASCADE,
|
||||
`version` INTEGER default NULL,
|
||||
`workflow` INTEGER default NULL REFERENCES `tblWorkflows` (`id`) ON DELETE CASCADE,
|
||||
`userid` INTEGER default NULL REFERENCES `tblUsers` (`id`) ON DELETE CASCADE,
|
||||
`transition` INTEGER default NULL REFERENCES `tblWorkflowTransitions` (`id`) ON DELETE CASCADE,
|
||||
`date` datetime NOT NULL,
|
||||
`comment` text
|
||||
) ;
|
||||
|
||||
-- --------------------------------------------------------
|
||||
|
||||
--
|
||||
-- Table structure for table `tblWorkflowDocumentContent`
|
||||
--
|
||||
|
||||
CREATE TABLE `tblWorkflowDocumentContent` (
|
||||
`parentworkflow` INTEGER DEFAULT 0,
|
||||
`id` INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
`parent` INTEGER DEFAULT NULL REFERENCES `tblWorkflowDocumentContent` (`id`) ON DELETE CASCADE,
|
||||
`workflow` INTEGER DEFAULT NULL REFERENCES `tblWorkflows` (`id`) ON DELETE CASCADE,
|
||||
`document` INTEGER DEFAULT NULL REFERENCES `tblDocuments` (`id`) ON DELETE CASCADE,
|
||||
`version` INTEGER DEFAULT NULL,
|
||||
|
|
@ -589,6 +688,21 @@ CREATE TABLE `tblWorkflowDocumentContent` (
|
|||
|
||||
-- --------------------------------------------------------
|
||||
|
||||
--
|
||||
-- Table structure for table `tblWorkflowLog`
|
||||
--
|
||||
|
||||
CREATE TABLE `tblWorkflowLog` (
|
||||
`id` INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
`workflowdocumentcontent` INTEGER DEFAULT NULL REFERENCES `tblWorkflowDocumentContent` (`id`) ON DELETE CASCADE,
|
||||
`userid` INTEGER default NULL REFERENCES `tblUsers` (`id`) ON DELETE CASCADE,
|
||||
`transition` INTEGER default NULL REFERENCES `tblWorkflowTransitions` (`id`) ON DELETE CASCADE,
|
||||
`date` datetime NOT NULL,
|
||||
`comment` text
|
||||
) ;
|
||||
|
||||
-- --------------------------------------------------------
|
||||
|
||||
--
|
||||
-- Table structure for table `tblWorkflowMandatoryWorkflow`
|
||||
--
|
||||
|
|
@ -596,7 +710,102 @@ CREATE TABLE `tblWorkflowDocumentContent` (
|
|||
CREATE TABLE `tblWorkflowMandatoryWorkflow` (
|
||||
`userid` INTEGER default NULL REFERENCES `tblUsers` (`id`) ON DELETE CASCADE,
|
||||
`workflow` INTEGER default NULL REFERENCES `tblWorkflows` (`id`) ON DELETE CASCADE,
|
||||
UNIQUE(userid, workflow)
|
||||
UNIQUE(`userid`, `workflow`)
|
||||
) ;
|
||||
|
||||
-- --------------------------------------------------------
|
||||
|
||||
--
|
||||
-- Table structure for transmittal
|
||||
--
|
||||
|
||||
CREATE TABLE `tblTransmittals` (
|
||||
`id` INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
`name` text NOT NULL,
|
||||
`comment` text NOT NULL,
|
||||
`userID` INTEGER NOT NULL default '0' REFERENCES `tblUsers` (`id`) ON DELETE CASCADE,
|
||||
`date` TEXT default NULL,
|
||||
`public` INTEGER NOT NULL default '0'
|
||||
);
|
||||
|
||||
-- --------------------------------------------------------
|
||||
|
||||
--
|
||||
-- Table structure for transmittal item
|
||||
--
|
||||
|
||||
CREATE TABLE `tblTransmittalItems` (
|
||||
`id` INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
`transmittal` INTEGER NOT NULL DEFAULT '0' REFERENCES `tblTransmittals` (`id`) ON DELETE CASCADE,
|
||||
`document` INTEGER default NULL REFERENCES `tblDocuments` (`id`) ON DELETE CASCADE,
|
||||
`version` INTEGER unsigned NOT NULL default '0',
|
||||
`date` TEXT default NULL,
|
||||
UNIQUE (`transmittal`, `document`, `version`)
|
||||
);
|
||||
|
||||
-- --------------------------------------------------------
|
||||
|
||||
--
|
||||
-- Table structure for access request objects
|
||||
--
|
||||
|
||||
CREATE TABLE `tblAros` (
|
||||
`id` INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
`parent` INTEGER,
|
||||
`model` TEXT NOT NULL,
|
||||
`foreignid` INTEGER NOT NULL DEFAULT '0',
|
||||
`alias` TEXT
|
||||
) ;
|
||||
|
||||
|
||||
-- --------------------------------------------------------
|
||||
|
||||
--
|
||||
-- Table structure for access control objects
|
||||
--
|
||||
|
||||
CREATE TABLE `tblAcos` (
|
||||
`id` INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
`parent` INTEGER,
|
||||
`model` TEXT NOT NULL,
|
||||
`foreignid` INTEGER NOT NULL DEFAULT '0',
|
||||
`alias` TEXT
|
||||
) ;
|
||||
|
||||
-- --------------------------------------------------------
|
||||
|
||||
--
|
||||
-- Table structure for acos/aros relation
|
||||
--
|
||||
|
||||
CREATE TABLE `tblArosAcos` (
|
||||
`id` INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
`aro` INTEGER NOT NULL DEFAULT '0' REFERENCES `tblAros` (`id`) ON DELETE CASCADE,
|
||||
`aco` INTEGER NOT NULL DEFAULT '0' REFERENCES `tblAcos` (`id`) ON DELETE CASCADE,
|
||||
`create` INTEGER NOT NULL DEFAULT '-1',
|
||||
`read` INTEGER NOT NULL DEFAULT '-1',
|
||||
`update` INTEGER NOT NULL DEFAULT '-1',
|
||||
`delete` INTEGER NOT NULL DEFAULT '-1',
|
||||
UNIQUE (`aco`, `aro`)
|
||||
) ;
|
||||
|
||||
-- --------------------------------------------------------
|
||||
|
||||
--
|
||||
-- Table structure for table `tblSchedulerTask`
|
||||
--
|
||||
|
||||
CREATE TABLE `tblSchedulerTask` (
|
||||
`id` INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
`name` varchar(100) DEFAULT NULL,
|
||||
`description` TEXT DEFAULT NULL,
|
||||
`disabled` INTEGER NOT NULL DEFAULT '0',
|
||||
`extension` varchar(100) DEFAULT NULL,
|
||||
`task` varchar(100) DEFAULT NULL,
|
||||
`frequency` varchar(100) DEFAULT NULL,
|
||||
`params` TEXT DEFAULT NULL,
|
||||
`nextrun` TEXT DEFAULT NULL,
|
||||
`lastrun` TEXT DEFAULT NULL
|
||||
) ;
|
||||
|
||||
-- --------------------------------------------------------
|
||||
|
|
@ -618,7 +827,10 @@ CREATE TABLE `tblVersion` (
|
|||
-- Initial content for database
|
||||
--
|
||||
|
||||
INSERT INTO `tblRoles` (`id`, `name`, `role`) VALUES (1, 'Admin', 1);
|
||||
INSERT INTO `tblRoles` (`id`, `name`, `role`) VALUES (2, 'Guest', 2);
|
||||
INSERT INTO `tblRoles` (`id`, `name`, `role`) VALUES (3, 'User', 0);
|
||||
INSERT INTO `tblUsers` (`id`, `login`, `pwd`, `fullName`, `email`, `language`, `theme`, `comment`, `role`, `hidden`, `pwdExpiration`, `loginfailures`, `disabled`, `quota`, `homefolder`) VALUES (1, 'admin', '21232f297a57a5a743894a0e4a801fc3', 'Administrator', 'info@seeddms.org', '', '', '', 1, 0, '', 0, 0, 0, NULL);
|
||||
INSERT INTO `tblUsers` (`id`, `login`, `pwd`, `fullName`, `email`, `language`, `theme`, `comment`, `role`, `hidden`, `pwdExpiration`, `loginfailures`, `disabled`, `quota`, `homefolder`) VALUES (2, 'guest', NULL, 'Guest User', NULL, '', '', '', 2, 0, '', 0, 0, 0, NULL);
|
||||
INSERT INTO `tblFolders` (`id`, `name`, `parent`, `folderList`, `comment`, `date`, `owner`, `inheritAccess`, `defaultAccess`, `sequence`) VALUES (1, 'DMS', NULL, '', 'DMS root', strftime('%s','now'), 1, 0, 2, 0);
|
||||
INSERT INTO `tblVersion` VALUES (DATETIME(), 5, 1, 0);
|
||||
INSERT INTO `tblVersion` VALUES (DATETIME(), 6, 0, 0);
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ define("SEEDDMS_INSTALL", "on");
|
|||
define("SEEDDMS_VERSION", $ver->version());
|
||||
|
||||
include("../inc/inc.Settings.php");
|
||||
$settings = new Seeddms\Seeddms\Settings();
|
||||
$settings = new Settings();
|
||||
$rootDir = realpath ("..");
|
||||
if(file_exists($rootDir.'/../www'))
|
||||
$rootDir = realpath($rootDir.'/..').'/www';
|
||||
|
|
|
|||
|
|
@ -62,7 +62,6 @@ function fileExistsInIncludePath($file) { /* {{{ */
|
|||
/**
|
||||
* Load default settings + set
|
||||
*/
|
||||
require_once '../vendor/autoload.php';
|
||||
require_once('../inc/inc.Version.php');
|
||||
$ver = new SeedDMS_Version();
|
||||
define("SEEDDMS_INSTALL", "on");
|
||||
|
|
@ -70,7 +69,7 @@ define("SEEDDMS_VERSION", $ver->version());
|
|||
|
||||
require_once('../inc/inc.ClassSettings.php');
|
||||
|
||||
$configDir = Seeddms\Seeddms\Settings::getConfigDir();
|
||||
$configDir = Settings::getConfigDir();
|
||||
|
||||
/**
|
||||
* Check if ENABLE_INSTALL_TOOL exists in config dir
|
||||
|
|
@ -93,7 +92,8 @@ if (!file_exists($configDir."/settings.xml")) {
|
|||
}
|
||||
|
||||
// Set folders settings
|
||||
$settings = new Seeddms\Seeddms\Settings($configDir."/settings.xml");
|
||||
$settings = new Settings();
|
||||
$settings->load($configDir."/settings.xml");
|
||||
|
||||
$rootDir = realpath ("..");
|
||||
$installPath = realpath ("install.php");
|
||||
|
|
|
|||
181
install/update-6.0.0/update-postgres.sql
Normal file
181
install/update-6.0.0/update-postgres.sql
Normal file
|
|
@ -0,0 +1,181 @@
|
|||
START TRANSACTION;
|
||||
|
||||
ALTER TABLE "tblDocumentContent" ADD COLUMN "revisiondate" TIMESTAMP default NULL;
|
||||
|
||||
ALTER TABLE "tblUsers" ADD COLUMN "secret" varchar(50) default NULL;
|
||||
|
||||
ALTER TABLE "tblWorkflows" ADD COLUMN "layoutdata" text default NULL;
|
||||
|
||||
ALTER TABLE "tblWorkflowDocumentContent" ADD COLUMN "id" SERIAL UNIQUE;
|
||||
|
||||
ALTER TABLE "tblWorkflowLog" ADD COLUMN "workflowdocumentcontent" INTEGER NOT NULL DEFAULT '0';
|
||||
|
||||
UPDATE "tblWorkflowLog" SET "workflowdocumentcontent" = "tblWorkflowDocumentContent"."id" FROM "tblWorkflowDocumentContent" WHERE "tblWorkflowLog"."document" = "tblWorkflowDocumentContent"."document" AND "tblWorkflowLog"."version" = "tblWorkflowDocumentContent"."version" AND "tblWorkflowLog"."workflow" = "tblWorkflowDocumentContent"."workflow";
|
||||
|
||||
INSERT INTO "tblWorkflowDocumentContent" ("parentworkflow", "workflow", "document", "version", "state", "date") SELECT 0 AS "parentworkflow", "workflow", "document", "version", NULL AS "state", max("date") AS "date" FROM "tblWorkflowLog" WHERE "workflowdocumentcontent" = 0 GROUP BY "workflow", "document", "version";
|
||||
|
||||
UPDATE "tblWorkflowLog" SET "workflowdocumentcontent" = "tblWorkflowDocumentContent"."id" FROM "tblWorkflowDocumentContent" WHERE "tblWorkflowLog"."document" = "tblWorkflowDocumentContent"."document" AND "tblWorkflowLog"."version" = "tblWorkflowDocumentContent"."version" AND "tblWorkflowLog"."workflow" = "tblWorkflowDocumentContent"."workflow";
|
||||
|
||||
ALTER TABLE "tblWorkflowLog" ADD CONSTRAINT "tblWorkflowLog_workflowdocumentcontent" FOREIGN KEY ("workflowdocumentcontent") REFERENCES "tblWorkflowDocumentContent" ("id") ON DELETE CASCADE;
|
||||
|
||||
ALTER TABLE "tblWorkflowDocumentContent" ADD COLUMN "parent" INTEGER DEFAULT NULL;
|
||||
|
||||
ALTER TABLE "tblWorkflowDocumentContent" ADD CONSTRAINT "tblWorkflowDocumentContent_parent" FOREIGN KEY ("parent") REFERENCES "tblWorkflowDocumentContent" ("id") ON DELETE CASCADE;
|
||||
|
||||
ALTER TABLE "tblWorkflowDocumentContent" DROP COLUMN "parentworkflow";
|
||||
|
||||
ALTER TABLE "tblWorkflowLog" DROP COLUMN "document";
|
||||
|
||||
ALTER TABLE "tblWorkflowLog" DROP COLUMN "version";
|
||||
|
||||
ALTER TABLE "tblWorkflowLog" DROP COLUMN "workflow";
|
||||
|
||||
CREATE TABLE "tblUserSubstitutes" (
|
||||
"id" SERIAL UNIQUE,
|
||||
"user" INTEGER default null,
|
||||
"substitute" INTEGER default null,
|
||||
UNIQUE ("user", "substitute"),
|
||||
CONSTRAINT "tblUserSubstitutes_user" FOREIGN KEY ("user") REFERENCES "tblUsers" ("id") ON DELETE CASCADE,
|
||||
CONSTRAINT "tblUserSubstitutes_substitute" FOREIGN KEY ("user") REFERENCES "tblUsers" ("id") ON DELETE CASCADE
|
||||
);
|
||||
|
||||
CREATE TABLE "tblDocumentCheckOuts" (
|
||||
"document" INTEGER NOT NULL default '0',
|
||||
"version" INTEGER NOT NULL default '0',
|
||||
"userID" INTEGER NOT NULL default '0',
|
||||
"date" TIMESTAMP NOT NULL,
|
||||
"filename" varchar(255) NOT NULL default '',
|
||||
CONSTRAINT "tblDocumentCheckOuts_document" FOREIGN KEY ("document") REFERENCES "tblDocuments" ("id") ON DELETE CASCADE,
|
||||
CONSTRAINT "tblDocumentCheckOuts_user" FOREIGN KEY ("userID") REFERENCES "tblUsers" ("id") ON DELETE CASCADE
|
||||
);
|
||||
|
||||
CREATE TABLE "tblDocumentRecipients" (
|
||||
"receiptID" SERIAL UNIQUE,
|
||||
"documentID" INTEGER NOT NULL default '0',
|
||||
"version" INTEGER NOT NULL default '0',
|
||||
"type" INTEGER NOT NULL default '0',
|
||||
"required" INTEGER NOT NULL default '0',
|
||||
UNIQUE ("documentID","version","type","required"),
|
||||
CONSTRAINT "tblDocumentRecipients_document" FOREIGN KEY ("documentID") REFERENCES "tblDocuments" ("id") ON DELETE CASCADE
|
||||
);
|
||||
|
||||
CREATE TABLE "tblDocumentReceiptLog" (
|
||||
"receiptLogID" SERIAL UNIQUE,
|
||||
"receiptID" INTEGER NOT NULL default '0',
|
||||
"status" INTEGER NOT NULL default '0',
|
||||
"comment" text NOT NULL,
|
||||
"date" TIMESTAMP NOT NULL,
|
||||
"userID" INTEGER NOT NULL default '0',
|
||||
CONSTRAINT "tblDocumentReceiptLog_recipient" FOREIGN KEY ("receiptID") REFERENCES "tblDocumentRecipients" ("receiptID") ON DELETE CASCADE,
|
||||
CONSTRAINT "tblDocumentReceiptLog_user" FOREIGN KEY ("userID") REFERENCES "tblUsers" ("id") ON DELETE CASCADE
|
||||
);
|
||||
|
||||
CREATE TABLE "tblDocumentRevisors" (
|
||||
"revisionID" SERIAL UNIQUE,
|
||||
"documentID" INTEGER NOT NULL default '0',
|
||||
"version" INTEGER NOT NULL default '0',
|
||||
"type" INTEGER NOT NULL default '0',
|
||||
"required" INTEGER NOT NULL default '0',
|
||||
"startdate" TIMESTAMP default NULL,
|
||||
UNIQUE ("documentID","version","type","required"),
|
||||
CONSTRAINT "tblDocumentRevisors_document" FOREIGN KEY ("documentID") REFERENCES "tblDocuments" ("id") ON DELETE CASCADE
|
||||
);
|
||||
|
||||
CREATE TABLE "tblDocumentRevisionLog" (
|
||||
"revisionLogID" SERIAL UNIQUE,
|
||||
"revisionID" INTEGER NOT NULL default '0',
|
||||
"status" INTEGER NOT NULL default '0',
|
||||
"comment" text NOT NULL,
|
||||
"date" TIMESTAMP NOT NULL,
|
||||
"userID" INTEGER NOT NULL default '0',
|
||||
CONSTRAINT "tblDocumentRevisionLog_revision" FOREIGN KEY ("revisionID") REFERENCES "tblDocumentRevisors" ("revisionID") ON DELETE CASCADE,
|
||||
CONSTRAINT "tblDocumentRevisionLog_user" FOREIGN KEY ("userID") REFERENCES "tblUsers" ("id") ON DELETE CASCADE
|
||||
);
|
||||
|
||||
CREATE TABLE "tblTransmittals" (
|
||||
"id" SERIAL UNIQUE,
|
||||
"name" text NOT NULL,
|
||||
"comment" text NOT NULL,
|
||||
"userID" INTEGER NOT NULL default '0',
|
||||
"date" TIMESTAMP default NULL,
|
||||
"public" INTEGER NOT NULL default '0',
|
||||
CONSTRAINT "tblTransmittals_user" FOREIGN KEY ("userID") REFERENCES "tblUsers" ("id") ON DELETE CASCADE
|
||||
);
|
||||
|
||||
CREATE TABLE "tblTransmittalItems" (
|
||||
"id" SERIAL UNIQUE,
|
||||
"transmittal" INTEGER NOT NULL DEFAULT '0',
|
||||
"document" INTEGER default NULL,
|
||||
"version" INTEGER NOT NULL default '0',
|
||||
"date" TIMESTAMP default NULL,
|
||||
UNIQUE ("transmittal", "document", "version"),
|
||||
CONSTRAINT "tblTransmittalItems_document" FOREIGN KEY ("document") REFERENCES "tblDocuments" ("id") ON DELETE CASCADE,
|
||||
CONSTRAINT "tblTransmittalItem_transmittal" FOREIGN KEY ("transmittal") REFERENCES "tblTransmittals" ("id") ON DELETE CASCADE
|
||||
);
|
||||
|
||||
CREATE TABLE "tblRoles" (
|
||||
"id" SERIAL UNIQUE,
|
||||
"name" varchar(50) default NULL,
|
||||
"role" INTEGER NOT NULL default '0',
|
||||
"noaccess" varchar(30) NOT NULL default '',
|
||||
UNIQUE ("name")
|
||||
);
|
||||
|
||||
INSERT INTO "tblRoles" ("id", "name", "role") VALUES (1, 'Admin', 1);
|
||||
SELECT nextval('"tblRoles_id_seq"');
|
||||
INSERT INTO "tblRoles" ("id", "name", "role") VALUES (2, 'Guest', 2);
|
||||
SELECT nextval('"tblRoles_id_seq"');
|
||||
INSERT INTO "tblRoles" ("id", "name", "role") VALUES (3, 'User', 0);
|
||||
SELECT nextval('"tblRoles_id_seq"');
|
||||
|
||||
ALTER TABLE "tblUsers" ALTER "role" DROP DEFAULT;
|
||||
ALTER TABLE "tblUsers" ALTER "role" SET NOT NULL;
|
||||
UPDATE "tblUsers" SET role=3 WHERE role=0;
|
||||
ALTER TABLE "tblUsers" ADD CONSTRAINT "tblUsers_role" FOREIGN KEY ("role") REFERENCES "tblRoles" ("id");
|
||||
|
||||
CREATE TABLE "tblAros" (
|
||||
"id" SERIAL UNIQUE,
|
||||
"parent" INTEGER,
|
||||
"model" text NOT NULL,
|
||||
"foreignid" INTEGER NOT NULL DEFAULT '0',
|
||||
"alias" varchar(255)
|
||||
);
|
||||
|
||||
CREATE TABLE "tblAcos" (
|
||||
"id" SERIAL UNIQUE,
|
||||
"parent" INTEGER,
|
||||
"model" text NOT NULL,
|
||||
"foreignid" INTEGER NOT NULL DEFAULT '0',
|
||||
"alias" varchar(255)
|
||||
);
|
||||
|
||||
CREATE TABLE "tblArosAcos" (
|
||||
"id" SERIAL UNIQUE,
|
||||
"aro" INTEGER NOT NULL DEFAULT '0',
|
||||
"aco" INTEGER NOT NULL DEFAULT '0',
|
||||
"create" INTEGER NOT NULL DEFAULT '-1',
|
||||
"read" INTEGER NOT NULL DEFAULT '-1',
|
||||
"update" INTEGER NOT NULL DEFAULT '-1',
|
||||
"delete" INTEGER NOT NULL DEFAULT '-1',
|
||||
UNIQUE ("aco", "aro"),
|
||||
CONSTRAINT "tblArosAcos_acos" FOREIGN KEY ("aco") REFERENCES "tblAcos" ("id") ON DELETE CASCADE,
|
||||
CONSTRAINT "tblArosAcos_aros" FOREIGN KEY ("aro") REFERENCES "tblAros" ("id") ON DELETE CASCADE
|
||||
);
|
||||
|
||||
CREATE TABLE "tblSchedulerTask" (
|
||||
"id" SERIAL UNIQUE,
|
||||
"name" varchar(100) DEFAULT NULL,
|
||||
"description" TEXT DEFAULT NULL,
|
||||
"disabled" INTEGER NOT NULL DEFAULT '0',
|
||||
"extension" varchar(100) DEFAULT NULL,
|
||||
"task" varchar(100) DEFAULT NULL,
|
||||
"frequency" varchar(100) DEFAULT NULL,
|
||||
"params" TEXT DEFAULT NULL,
|
||||
"nextrun" TIMESTAMP DEFAULT NULL,
|
||||
"lastrun" TIMESTAMP DEFAULT NULL
|
||||
) ;
|
||||
|
||||
UPDATE "tblVersion" set "major"=6, "minor"=0, "subminor"=0;
|
||||
|
||||
COMMIT;
|
||||
|
||||
206
install/update-6.0.0/update-sqlite3.sql
Normal file
206
install/update-6.0.0/update-sqlite3.sql
Normal file
|
|
@ -0,0 +1,206 @@
|
|||
BEGIN;
|
||||
|
||||
ALTER TABLE `tblDocumentContent` ADD COLUMN `revisiondate` TEXT default NULL;
|
||||
|
||||
ALTER TABLE `tblUsers` ADD COLUMN `secret` varchar(50) default NULL;
|
||||
|
||||
ALTER TABLE `tblWorkflows` ADD COLUMN `layoutdata` text default NULL;
|
||||
|
||||
CREATE TABLE `new_tblWorkflowDocumentContent` (
|
||||
`id` INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
`parent` INTEGER DEFAULT NULL REFERENCES `tblWorkflowDocumentContent` (`id`) ON DELETE CASCADE,
|
||||
`workflow` INTEGER DEFAULT NULL REFERENCES `tblWorkflows` (`id`) ON DELETE CASCADE,
|
||||
`document` INTEGER DEFAULT NULL REFERENCES `tblDocuments` (`id`) ON DELETE CASCADE,
|
||||
`version` INTEGER DEFAULT NULL,
|
||||
`state` INTEGER DEFAULT NULL REFERENCES `tblWorkflowStates` (`id`) ON DELETE CASCADE,
|
||||
`date` datetime NOT NULL
|
||||
) ;
|
||||
|
||||
INSERT INTO `new_tblWorkflowDocumentContent` (`parent`, `workflow`, `document`, `version`, `state`, `date`) SELECT NULL as `parent`, `workflow`, `document`, `version`, `state`, `date` FROM `tblWorkflowDocumentContent`;
|
||||
|
||||
INSERT INTO `new_tblWorkflowDocumentContent` (`parent`, `workflow`, `document`, `version`, `state`, `date`) SELECT NULL, `a`.`workflow`, `a`.`document`, `a`.`version`, NULL AS `state`, max(`a`.`date`) FROM `tblWorkflowLog` `a` LEFT JOIN `tblWorkflowDocumentContent` `b` ON `a`.`document`=`b`.`document` AND `a`.`version`=`b`.`version` AND `a`.`workflow`=`b`.`workflow` WHERE `b`.`document` IS NULL GROUP BY `a`.`document`, `a`.`version`, `a`.`workflow`;
|
||||
|
||||
CREATE TABLE `new_tblWorkflowLog` (
|
||||
`id` INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
`workflowdocumentcontent` INTEGER DEFAULT NULL REFERENCES `tblWorkflowDocumentContent` (`id`) ON DELETE CASCADE,
|
||||
`userid` INTEGER default NULL REFERENCES `tblUsers` (`id`) ON DELETE CASCADE,
|
||||
`transition` INTEGER default NULL REFERENCES `tblWorkflowTransitions` (`id`) ON DELETE CASCADE,
|
||||
`date` datetime NOT NULL,
|
||||
`comment` text
|
||||
) ;
|
||||
|
||||
INSERT INTO `new_tblWorkflowLog` (`id`, `workflowdocumentcontent`, `userid`, `transition`, `date`, `comment`) SELECT `a`.`id`, `b`.`id`, `a`.`userid`, `a`.`transition`, `a`.`date`, `a`.`comment` FROM `tblWorkflowLog` `a` LEFT JOIN `new_tblWorkflowDocumentContent` `b` ON `a`.`document`=`b`.`document` AND `a`.`version`=`b`.`version` AND `a`.`workflow`=`b`.`workflow` WHERE `b`.`document` IS NOT NULL;
|
||||
|
||||
DROP TABLE `tblWorkflowLog`;
|
||||
|
||||
ALTER TABLE `new_tblWorkflowLog` RENAME TO `tblWorkflowLog`;
|
||||
|
||||
DROP TABLE `tblWorkflowDocumentContent`;
|
||||
|
||||
ALTER TABLE `new_tblWorkflowDocumentContent` RENAME TO `tblWorkflowDocumentContent`;
|
||||
|
||||
CREATE TABLE `tblUserSubstitutes` (
|
||||
`id` INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
`user` INTEGER NOT NULL default '0' REFERENCES `tblUsers` (`id`) ON DELETE CASCADE,
|
||||
`substitute` INTEGER NOT NULL default '0' REFERENCES `tblUsers` (`id`) ON DELETE CASCADE,
|
||||
UNIQUE (`user`, `substitute`)
|
||||
);
|
||||
|
||||
CREATE TABLE `tblDocumentCheckOuts` (
|
||||
`document` INTEGER REFERENCES `tblDocuments` (`id`) ON DELETE CASCADE,
|
||||
`version` INTEGER unsigned NOT NULL default '0',
|
||||
`userID` INTEGER NOT NULL default '0' REFERENCES `tblUsers` (`id`),
|
||||
`date` TEXT NOT NULL,
|
||||
`filename` varchar(255) NOT NULL default '',
|
||||
UNIQUE (`document`)
|
||||
) ;
|
||||
|
||||
CREATE TABLE `tblDocumentRecipients` (
|
||||
`receiptID` INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
`documentID` INTEGER NOT NULL default '0' REFERENCES `tblDocuments` (`id`) ON DELETE CASCADE,
|
||||
`version` INTEGER unsigned NOT NULL default '0',
|
||||
`type` INTEGER NOT NULL default '0',
|
||||
`required` INTEGER NOT NULL default '0',
|
||||
UNIQUE (`documentID`,`version`,`type`,`required`)
|
||||
) ;
|
||||
CREATE INDEX `indDocumentRecipientsRequired` ON `tblDocumentRecipients` (`required`);
|
||||
|
||||
CREATE TABLE `tblDocumentReceiptLog` (
|
||||
`receiptLogID` INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
`receiptID` INTEGER NOT NULL default 0 REFERENCES `tblDocumentRecipients` (`receiptID`) ON DELETE CASCADE,
|
||||
`status` INTEGER NOT NULL default 0,
|
||||
`comment` TEXT NOT NULL,
|
||||
`date` TEXT NOT NULL,
|
||||
`userID` INTEGER NOT NULL default 0 REFERENCES `tblUsers` (`id`) ON DELETE CASCADE
|
||||
) ;
|
||||
CREATE INDEX `indDocumentReceiptLogReceiptID` ON `tblDocumentReceiptLog` (`receiptID`);
|
||||
|
||||
CREATE TABLE `tblDocumentRevisors` (
|
||||
`revisionID` INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
`documentID` INTEGER NOT NULL default '0' REFERENCES `tblDocuments` (`id`) ON DELETE CASCADE,
|
||||
`version` INTEGER unsigned NOT NULL default '0',
|
||||
`type` INTEGER NOT NULL default '0',
|
||||
`required` INTEGER NOT NULL default '0',
|
||||
`startdate` TEXT default NULL,
|
||||
UNIQUE (`documentID`,`version`,`type`,`required`)
|
||||
) ;
|
||||
CREATE INDEX `indDocumentRevisorsRequired` ON `tblDocumentRevisors` (`required`);
|
||||
|
||||
CREATE TABLE `tblDocumentRevisionLog` (
|
||||
`revisionLogID` INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
`revisionID` INTEGER NOT NULL default 0 REFERENCES `tblDocumentRevisors` (`revisionID`) ON DELETE CASCADE,
|
||||
`status` INTEGER NOT NULL default 0,
|
||||
`comment` TEXT NOT NULL,
|
||||
`date` TEXT NOT NULL,
|
||||
`userID` INTEGER NOT NULL default 0 REFERENCES `tblUsers` (`id`) ON DELETE CASCADE
|
||||
) ;
|
||||
CREATE INDEX `indDocumentRevisionLogRevisionID` ON `tblDocumentRevisionLog` (`revisionID`);
|
||||
|
||||
CREATE TABLE `tblTransmittals` (
|
||||
`id` INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
`name` text NOT NULL,
|
||||
`comment` text NOT NULL,
|
||||
`userID` INTEGER NOT NULL default '0' REFERENCES `tblUsers` (`id`) ON DELETE CASCADE,
|
||||
`date` TEXT default NULL,
|
||||
`public` INTEGER NOT NULL default '0'
|
||||
);
|
||||
|
||||
CREATE TABLE `tblTransmittalItems` (
|
||||
`id` INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
`transmittal` INTEGER NOT NULL DEFAULT '0' REFERENCES `tblTransmittals` (`id`) ON DELETE CASCADE,
|
||||
`document` INTEGER default NULL REFERENCES `tblDocuments` (`id`) ON DELETE CASCADE,
|
||||
`version` INTEGER unsigned NOT NULL default '0',
|
||||
`date` TEXT default NULL,
|
||||
UNIQUE (transmittal, document, version)
|
||||
);
|
||||
|
||||
CREATE TABLE `tblRoles` (
|
||||
`id` INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
`name` varchar(50) default NULL,
|
||||
`role` INTEGER NOT NULL default '0',
|
||||
`noaccess` varchar(30) NOT NULL default '',
|
||||
UNIQUE (`name`)
|
||||
);
|
||||
|
||||
INSERT INTO `tblRoles` (`id`, `name`, `role`) VALUES (1, 'Admin', 1);
|
||||
INSERT INTO `tblRoles` (`id`, `name`, `role`) VALUES (2, 'Guest', 2);
|
||||
INSERT INTO `tblRoles` (`id`, `name`, `role`) VALUES (3, 'User', 0);
|
||||
|
||||
UPDATE `tblUsers` SET role=3 WHERE role=0;
|
||||
|
||||
CREATE TABLE `new_tblUsers` (
|
||||
`id` INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
`login` varchar(50) default NULL,
|
||||
`pwd` varchar(50) default NULL,
|
||||
`fullName` varchar(100) default NULL,
|
||||
`email` varchar(70) default NULL,
|
||||
`language` varchar(32) NOT NULL,
|
||||
`theme` varchar(32) NOT NULL,
|
||||
`comment` text NOT NULL,
|
||||
`role` INTEGER NOT NULL REFERENCES `tblRoles` (`id`),
|
||||
`hidden` INTEGER NOT NULL default '0',
|
||||
`pwdExpiration` TEXT default NULL,
|
||||
`loginfailures` INTEGER NOT NULL default '0',
|
||||
`disabled` INTEGER NOT NULL default '0',
|
||||
`quota` INTEGER,
|
||||
`homefolder` INTEGER default NULL REFERENCES `tblFolders` (`id`),
|
||||
`secret` varchar(50) default NULL,
|
||||
UNIQUE (`login`)
|
||||
);
|
||||
|
||||
INSERT INTO new_tblUsers SELECT * FROM tblUsers;
|
||||
|
||||
DROP TABLE tblUsers;
|
||||
|
||||
ALTER TABLE new_tblUsers RENAME TO tblUsers;
|
||||
|
||||
CREATE TABLE `tblAros` (
|
||||
`id` INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
`parent` INTEGER,
|
||||
`model` TEXT NOT NULL,
|
||||
`foreignid` INTEGER NOT NULL DEFAULT '0',
|
||||
`alias` TEXT
|
||||
) ;
|
||||
|
||||
CREATE TABLE `tblAcos` (
|
||||
`id` INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
`parent` INTEGER,
|
||||
`model` TEXT NOT NULL,
|
||||
`foreignid` INTEGER NOT NULL DEFAULT '0',
|
||||
`alias` TEXT
|
||||
) ;
|
||||
|
||||
CREATE TABLE `tblArosAcos` (
|
||||
`id` INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
`aro` INTEGER NOT NULL DEFAULT '0' REFERENCES `tblAros` (`id`) ON DELETE CASCADE,
|
||||
`aco` INTEGER NOT NULL DEFAULT '0' REFERENCES `tblAcos` (`id`) ON DELETE CASCADE,
|
||||
`create` INTEGER NOT NULL DEFAULT '-1',
|
||||
`read` INTEGER NOT NULL DEFAULT '-1',
|
||||
`update` INTEGER NOT NULL DEFAULT '-1',
|
||||
`delete` INTEGER NOT NULL DEFAULT '-1',
|
||||
UNIQUE (aco, aro)
|
||||
) ;
|
||||
|
||||
CREATE INDEX `indDocumentStatusLogStatusID` ON `tblDocumentStatusLog` (`StatusID`);
|
||||
CREATE INDEX `indDocumentApproversRequired` ON `tblDocumentApprovers` (`required`);
|
||||
CREATE INDEX `indDocumentApproveLogApproveID` ON `tblDocumentApproveLog` (`approveID`);
|
||||
CREATE INDEX `indDocumentReviewersRequired` ON `tblDocumentReviewers` (`required`);
|
||||
CREATE INDEX `indDocumentReviewLogReviewID` ON `tblDocumentReviewLog` (`reviewID`);
|
||||
|
||||
CREATE TABLE `tblSchedulerTask` (
|
||||
`id` INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
`name` varchar(100) DEFAULT NULL,
|
||||
`description` TEXT DEFAULT NULL,
|
||||
`disabled` INTEGER NOT NULL DEFAULT '0',
|
||||
`extension` varchar(100) DEFAULT NULL,
|
||||
`task` varchar(100) DEFAULT NULL,
|
||||
`frequency` varchar(100) DEFAULT NULL,
|
||||
`params` TEXT DEFAULT NULL,
|
||||
`nextrun` TEXT DEFAULT NULL,
|
||||
`lastrun` TEXT DEFAULT NULL
|
||||
) ;
|
||||
|
||||
UPDATE tblVersion set major=6, minor=0, subminor=0;
|
||||
|
||||
COMMIT;
|
||||
|
||||
200
install/update-6.0.0/update.sql
Normal file
200
install/update-6.0.0/update.sql
Normal file
|
|
@ -0,0 +1,200 @@
|
|||
START TRANSACTION;
|
||||
|
||||
ALTER TABLE `tblDocumentContent` ADD COLUMN `revisiondate` datetime DEFAULT NULL;
|
||||
|
||||
ALTER TABLE `tblUsers` ADD COLUMN `secret` varchar(50) DEFAULT NULL AFTER `pwd`;
|
||||
|
||||
ALTER TABLE `tblWorkflows` ADD COLUMN `layoutdata` text DEFAULT NULL AFTER `initstate`;
|
||||
|
||||
ALTER TABLE `tblWorkflowDocumentContent` ADD COLUMN `id` int(11) NOT NULL AUTO_INCREMENT FIRST, ADD PRIMARY KEY (`id`);
|
||||
|
||||
ALTER TABLE `tblWorkflowLog` ADD COLUMN `workflowdocumentcontent` int(11) NOT NULL DEFAULT '0' AFTER `id`;
|
||||
|
||||
UPDATE `tblWorkflowLog` a, `tblWorkflowDocumentContent` b SET a.`workflowdocumentcontent` = b.`id` WHERE a.`document` = b.`document` AND a.`version` = b.`version` AND a.`workflow` = b.`workflow`;
|
||||
|
||||
INSERT INTO `tblWorkflowDocumentContent` (`parentworkflow`, `workflow`, `document`, `version`, `state`, `date`) SELECT 0 AS `parentworkflow`, `workflow`, `document`, `version`, NULL AS `state`, max(`date`) AS `date` FROM `tblWorkflowLog` WHERE `workflowdocumentcontent` = 0 GROUP BY `workflow`, `document`, `version`;
|
||||
|
||||
UPDATE `tblWorkflowLog` a, `tblWorkflowDocumentContent` b SET a.`workflowdocumentcontent` = b.`id` WHERE a.`document` = b.`document` AND a.`version` = b.`version` AND a.`workflow` = b.`workflow`;
|
||||
|
||||
ALTER TABLE `tblWorkflowLog` ADD CONSTRAINT `tblWorkflowLog_workflowdocumentcontent` FOREIGN KEY (`workflowdocumentcontent`) REFERENCES `tblWorkflowDocumentContent` (`id`) ON DELETE CASCADE;
|
||||
|
||||
ALTER TABLE `tblWorkflowDocumentContent` ADD COLUMN `parent` int(11) DEFAULT NULL AFTER `id`;
|
||||
|
||||
ALTER TABLE `tblWorkflowDocumentContent` ADD CONSTRAINT `tblWorkflowDocumentContent_parent` FOREIGN KEY (`parent`) REFERENCES `tblWorkflowDocumentContent` (`id`) ON DELETE CASCADE;
|
||||
|
||||
ALTER TABLE `tblWorkflowDocumentContent` DROP COLUMN `parentworkflow`;
|
||||
|
||||
ALTER TABLE `tblWorkflowLog` DROP FOREIGN KEY `tblWorkflowLog_document`;
|
||||
|
||||
ALTER TABLE `tblWorkflowLog` DROP COLUMN `document`;
|
||||
|
||||
ALTER TABLE `tblWorkflowLog` DROP COLUMN `version`;
|
||||
|
||||
ALTER TABLE `tblWorkflowLog` DROP FOREIGN KEY `tblWorkflowLog_workflow`;
|
||||
|
||||
ALTER TABLE `tblWorkflowLog` DROP COLUMN `workflow`;
|
||||
|
||||
CREATE TABLE `tblUserSubstitutes` (
|
||||
`id` int(11) NOT NULL AUTO_INCREMENT,
|
||||
`user` int(11) DEFAULT null,
|
||||
`substitute` int(11) DEFAULT null,
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE (`user`, `substitute`),
|
||||
CONSTRAINT `tblUserSubstitutes_user` FOREIGN KEY (`user`) REFERENCES `tblUsers` (`id`) ON DELETE CASCADE,
|
||||
CONSTRAINT `tblUserSubstitutes_substitute` FOREIGN KEY (`substitute`) REFERENCES `tblUsers` (`id`) ON DELETE CASCADE
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
||||
|
||||
CREATE TABLE `tblDocumentCheckOuts` (
|
||||
`document` int(11) NOT NULL DEFAULT '0',
|
||||
`version` smallint(5) unsigned NOT NULL DEFAULT '0',
|
||||
`userID` int(11) NOT NULL DEFAULT '0',
|
||||
`date` datetime NOT NULL,
|
||||
`filename` varchar(255) NOT NULL DEFAULT '',
|
||||
PRIMARY KEY (`document`),
|
||||
CONSTRAINT `tblDocumentCheckOuts_document` FOREIGN KEY (`document`) REFERENCES `tblDocuments` (`id`) ON DELETE CASCADE,
|
||||
CONSTRAINT `tblDocumentCheckOuts_user` FOREIGN KEY (`userID`) REFERENCES `tblUsers` (`id`) ON DELETE CASCADE
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
||||
|
||||
CREATE TABLE `tblDocumentRecipients` (
|
||||
`receiptID` int(11) NOT NULL AUTO_INCREMENT,
|
||||
`documentID` int(11) NOT NULL DEFAULT '0',
|
||||
`version` smallint(5) unsigned NOT NULL DEFAULT '0',
|
||||
`type` tinyint(4) NOT NULL DEFAULT '0',
|
||||
`required` int(11) NOT NULL DEFAULT '0',
|
||||
PRIMARY KEY (`receiptID`),
|
||||
UNIQUE KEY `documentID` (`documentID`,`version`,`type`,`required`),
|
||||
CONSTRAINT `tblDocumentRecipients_document` FOREIGN KEY (`documentID`) REFERENCES `tblDocuments` (`id`) ON DELETE CASCADE
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
||||
CREATE INDEX `indDocumentRecipientsRequired` ON `tblDocumentRecipients` (`required`);
|
||||
|
||||
CREATE TABLE `tblDocumentReceiptLog` (
|
||||
`receiptLogID` int(11) NOT NULL AUTO_INCREMENT,
|
||||
`receiptID` int(11) NOT NULL DEFAULT '0',
|
||||
`status` tinyint(4) NOT NULL DEFAULT '0',
|
||||
`comment` text NOT NULL,
|
||||
`date` datetime NOT NULL,
|
||||
`userID` int(11) NOT NULL DEFAULT '0',
|
||||
PRIMARY KEY (`receiptLogID`),
|
||||
KEY `tblDocumentReceiptLog_receipt` (`receiptID`),
|
||||
KEY `tblDocumentReceiptLog_user` (`userID`),
|
||||
CONSTRAINT `tblDocumentReceiptLog_recipient` FOREIGN KEY (`receiptID`) REFERENCES `tblDocumentRecipients` (`receiptID`) ON DELETE CASCADE,
|
||||
CONSTRAINT `tblDocumentReceiptLog_user` FOREIGN KEY (`userID`) REFERENCES `tblUsers` (`id`) ON DELETE CASCADE
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
||||
|
||||
CREATE TABLE `tblDocumentRevisors` (
|
||||
`revisionID` int(11) NOT NULL AUTO_INCREMENT,
|
||||
`documentID` int(11) NOT NULL DEFAULT '0',
|
||||
`version` smallint(5) unsigned NOT NULL DEFAULT '0',
|
||||
`type` tinyint(4) NOT NULL DEFAULT '0',
|
||||
`required` int(11) NOT NULL DEFAULT '0',
|
||||
`startdate` datetime DEFAULT NULL,
|
||||
PRIMARY KEY (`revisionID`),
|
||||
UNIQUE KEY `documentID` (`documentID`,`version`,`type`,`required`),
|
||||
CONSTRAINT `tblDocumentRevisors_document` FOREIGN KEY (`documentID`) REFERENCES `tblDocuments` (`id`) ON DELETE CASCADE
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
||||
CREATE INDEX `indDocumentRevisorsRequired` ON `tblDocumentRevisors` (`required`);
|
||||
|
||||
CREATE TABLE `tblDocumentRevisionLog` (
|
||||
`revisionLogID` int(11) NOT NULL AUTO_INCREMENT,
|
||||
`revisionID` int(11) NOT NULL DEFAULT '0',
|
||||
`status` tinyint(4) NOT NULL DEFAULT '0',
|
||||
`comment` text NOT NULL,
|
||||
`date` datetime NOT NULL,
|
||||
`userID` int(11) NOT NULL DEFAULT '0',
|
||||
PRIMARY KEY (`revisionLogID`),
|
||||
KEY `tblDocumentRevisionLog_revision` (`revisionID`),
|
||||
KEY `tblDocumentRevisionLog_user` (`userID`),
|
||||
CONSTRAINT `tblDocumentRevisionLog_revision` FOREIGN KEY (`revisionID`) REFERENCES `tblDocumentRevisors` (`revisionID`) ON DELETE CASCADE,
|
||||
CONSTRAINT `tblDocumentRevisionLog_user` FOREIGN KEY (`userID`) REFERENCES `tblUsers` (`id`) ON DELETE CASCADE
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
||||
|
||||
CREATE TABLE `tblTransmittals` (
|
||||
`id` int(11) NOT NULL AUTO_INCREMENT,
|
||||
`name` text NOT NULL,
|
||||
`comment` text NOT NULL,
|
||||
`userID` int(11) NOT NULL DEFAULT '0',
|
||||
`date` datetime DEFAULT NULL,
|
||||
`public` tinyint(1) NOT NULL DEFAULT '0',
|
||||
PRIMARY KEY (`id`),
|
||||
CONSTRAINT `tblTransmittals_user` FOREIGN KEY (`userID`) REFERENCES `tblUsers` (`id`) ON DELETE CASCADE
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
||||
|
||||
CREATE TABLE `tblTransmittalItems` (
|
||||
`id` int(11) NOT NULL AUTO_INCREMENT,
|
||||
`transmittal` int(11) NOT NULL DEFAULT '0',
|
||||
`document` int(11) DEFAULT NULL,
|
||||
`version` smallint(5) unsigned NOT NULL DEFAULT '0',
|
||||
`date` datetime DEFAULT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE (transmittal, document, version),
|
||||
CONSTRAINT `tblTransmittalItems_document` FOREIGN KEY (`document`) REFERENCES `tblDocuments` (`id`) ON DELETE CASCADE,
|
||||
CONSTRAINT `tblTransmittalItem_transmittal` FOREIGN KEY (`transmittal`) REFERENCES `tblTransmittals` (`id`) ON DELETE CASCADE
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
||||
|
||||
CREATE TABLE `tblRoles` (
|
||||
`id` int(11) NOT NULL AUTO_INCREMENT,
|
||||
`name` varchar(50) DEFAULT NULL,
|
||||
`role` smallint(1) NOT NULL DEFAULT '0',
|
||||
`noaccess` varchar(30) NOT NULL DEFAULT '',
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE (`name`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
||||
|
||||
INSERT INTO `tblRoles` (`id`, `name`, `role`) VALUES (1, 'Admin', 1);
|
||||
INSERT INTO `tblRoles` (`id`, `name`, `role`) VALUES (2, 'Guest', 2);
|
||||
INSERT INTO `tblRoles` (`id`, `name`, `role`) VALUES (3, 'User', 0);
|
||||
ALTER TABLE `tblRoles` AUTO_INCREMENT=4;
|
||||
|
||||
ALTER TABLE tblUsers CHANGE role role int(11) NOT NULL;
|
||||
UPDATE `tblUsers` SET role=3 WHERE role=0;
|
||||
ALTER TABLE tblUsers ADD CONSTRAINT `tblUsers_role` FOREIGN KEY (`role`) REFERENCES `tblRoles` (`id`);
|
||||
|
||||
CREATE TABLE `tblAros` (
|
||||
`id` int(11) NOT NULL auto_increment,
|
||||
`parent` int(11),
|
||||
`model` text NOT NULL,
|
||||
`foreignid` int(11) NOT NULL DEFAULT '0',
|
||||
`alias` varchar(255),
|
||||
PRIMARY KEY (`id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
||||
|
||||
CREATE TABLE `tblAcos` (
|
||||
`id` int(11) NOT NULL auto_increment,
|
||||
`parent` int(11),
|
||||
`model` text NOT NULL,
|
||||
`foreignid` int(11) NOT NULL DEFAULT '0',
|
||||
`alias` varchar(255),
|
||||
PRIMARY KEY (`id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
||||
|
||||
CREATE TABLE `tblArosAcos` (
|
||||
`id` int(11) NOT NULL auto_increment,
|
||||
`aro` int(11) NOT NULL DEFAULT '0',
|
||||
`aco` int(11) NOT NULL DEFAULT '0',
|
||||
`create` tinyint(4) NOT NULL DEFAULT '-1',
|
||||
`read` tinyint(4) NOT NULL DEFAULT '-1',
|
||||
`update` tinyint(4) NOT NULL DEFAULT '-1',
|
||||
`delete` tinyint(4) NOT NULL DEFAULT '-1',
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE (aco, aro),
|
||||
CONSTRAINT `tblArosAcos_acos` FOREIGN KEY (`aco`) REFERENCES `tblAcos` (`id`) ON DELETE CASCADE,
|
||||
CONSTRAINT `tblArosAcos_aros` FOREIGN KEY (`aro`) REFERENCES `tblAros` (`id`) ON DELETE CASCADE
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
||||
|
||||
CREATE TABLE `tblSchedulerTask` (
|
||||
`id` int(11) NOT NULL AUTO_INCREMENT,
|
||||
`name` varchar(100) DEFAULT NULL,
|
||||
`description` text DEFAULT NULL,
|
||||
`disabled` smallint(1) NOT NULL DEFAULT '0',
|
||||
`extension` varchar(100) DEFAULT NULL,
|
||||
`task` varchar(100) DEFAULT NULL,
|
||||
`frequency` varchar(100) DEFAULT NULL,
|
||||
`params` text DEFAULT NULL,
|
||||
`nextrun` datetime DEFAULT NULL,
|
||||
`lastrun` datetime DEFAULT NULL,
|
||||
PRIMARY KEY (`id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
||||
|
||||
UPDATE tblVersion set major=6, minor=0, subminor=0;
|
||||
|
||||
COMMIT;
|
||||
52
install/update-6.0.0/update.txt
Normal file
52
install/update-6.0.0/update.txt
Normal file
|
|
@ -0,0 +1,52 @@
|
|||
Caution when you update seeddms with workflow mode `advanced`
|
||||
=============================================================
|
||||
|
||||
The previous database layout for tracking the workflow state of a
|
||||
document content was not very well done. It did not allow to run
|
||||
the document through another workflow at a later time, expecially
|
||||
the same workflow, e.g. for a scheduled revision of a document.
|
||||
|
||||
Technical details
|
||||
==================
|
||||
This update modifies the tables tblWorkflowDocumentContent and
|
||||
tblWorkflowLog. It adds a new autoincrement field as a primary key
|
||||
(id) to tblWorkflowDocumentContent and references that field in
|
||||
tblWorkflowLog (workflowdocumentcontent). Till now the two tables
|
||||
where linked by the fields `document`, `version`, and `workflow` which will
|
||||
be replaced by the two new fields. The fields `document`, `version`, and
|
||||
`workflow` will be removed from tblWorkflowLog. tblWorkflowDocumentContent
|
||||
contained just the workflows currently active for a particlar document.
|
||||
From now on the table will also contain finished workflows, which
|
||||
will have the field `state` set to null. This allows to run even the
|
||||
same workflow again and still be able to distinguish the log entries.
|
||||
|
||||
MySQL
|
||||
------
|
||||
|
||||
The update process will first add the new auto incrementing, primary
|
||||
field to tblWorkflowDocumentContent and a referencing field to
|
||||
tblWorkflowLog. It will then fill out the referencing field with the
|
||||
automatically incremented field value from tblWorkflowDocumentContent
|
||||
by joining the two tables with its common fields document, version,
|
||||
and workflow. This will not fill out all referencing field values,
|
||||
because once a workflow has ended the record in
|
||||
tblWorkflowDocumentContent will be deleted and just the records in
|
||||
tblWorkflowLog are kept. The still missing records in
|
||||
tblWorkflowDocumentContent for already completed workflows will be
|
||||
reconstructed from the records in tblWorkflowLog which do not have a
|
||||
reference to tblWorkflowDocumentContent yet. Once that is done the
|
||||
referencing field in tblWorkflowLog can be filled in a second pass.
|
||||
The date of the new records in tblWorkflowDocumentContent will be
|
||||
taken from the last record for that workflow in tblWorkflowLog. The
|
||||
state of the new records will be set null, indicating that this
|
||||
workflow is no longer active.
|
||||
|
||||
SQLite
|
||||
-------
|
||||
|
||||
The update process will first create new table for tblWorkflowDocumentContent
|
||||
containing a new field for the primary key field. It then copies the
|
||||
records from the old table to the new table. The missing records for
|
||||
workflows which has been finished already are recreated from the old
|
||||
table `tblWorkflowLog`. Which is then replaced by a new table having
|
||||
the foreign key to table `tblWorkflowDocumentContent`.
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user