Compare commits
753 Commits
3.0.0-rc-1
...
master
Author | SHA1 | Date | |
---|---|---|---|
6fcd22b533 | |||
|
fb81b23f6b | ||
|
5f58ecb77f | ||
|
ff9b7ceb9c | ||
|
983250665c | ||
|
6205642cdb | ||
|
b41021f567 | ||
|
1de92c0d26 | ||
|
510544f4ba | ||
|
6180d5d30c | ||
|
11d6213208 | ||
|
c4a9368a7b | ||
|
823874e0a1 | ||
|
7fc3fb042d | ||
|
a1fc11cd93 | ||
|
66fdd15616 | ||
|
781e3b0434 | ||
|
12a5b57fab | ||
|
179df881c1 | ||
|
9260af4734 | ||
|
7efb6fc11e | ||
|
9ee7e3e31b | ||
|
205035fa0c | ||
|
f39dbdfd87 | ||
|
c11a9d3a80 | ||
|
4418a36ccf | ||
|
e3d4fc89dc | ||
|
748ae25fc2 | ||
|
27e3729fcf | ||
|
4e01fa7971 | ||
|
16b1e7c491 | ||
|
fccfde3414 | ||
|
3458f240b7 | ||
|
7a3d2f20a9 | ||
|
d15d4bf8d1 | ||
|
d4a48c6c73 | ||
|
26de217fef | ||
|
4d71bf45ad | ||
|
4c54ec677c | ||
|
1fffac8b8c | ||
|
0c04660f3f | ||
|
0bb182220a | ||
|
a292d0dd30 | ||
|
ea8b89ac04 | ||
|
bc6299e5cf | ||
|
83e2ec500a | ||
|
ba733a2619 | ||
|
1ca4780d82 | ||
|
c133b11bf6 | ||
|
a1fcc93f4e | ||
|
3ef8494b2a | ||
|
b5374b9e6e | ||
|
b5890e1f59 | ||
|
2e9f040519 | ||
|
f02af695b8 | ||
|
6cad99e6c3 | ||
|
d2096f366e | ||
|
db6e971ccc | ||
|
c5804612ae | ||
|
aed9fda0aa | ||
|
b0934f7c4c | ||
|
eb32da3c3e | ||
|
ad8e242d53 | ||
|
988c788710 | ||
|
2c0bcb231a | ||
|
9d1f2cbfdf | ||
|
32a2cde309 | ||
|
ec6e67c8af | ||
|
444493506d | ||
|
0c13a6baf7 | ||
|
5608c32c7e | ||
|
dc8567620b | ||
|
49eefce540 | ||
|
17c5607ce7 | ||
|
6be05bebfe | ||
|
c92191f396 | ||
|
50ea0aafd6 | ||
|
fff00edbef | ||
|
b5af789662 | ||
|
c380ea0bc5 | ||
|
05af7b17a5 | ||
|
ef4ab7a2ea | ||
|
4a65599985 | ||
|
682e39fe5d | ||
|
075c8c006d | ||
|
b215f885a9 | ||
|
53a9860388 | ||
|
007fcb5575 | ||
|
d84776d1aa | ||
|
5e5a8193e9 | ||
|
0823390738 | ||
|
be0a8e52ca | ||
|
f102baf753 | ||
|
035e4f0a79 | ||
|
aa1667261d | ||
|
f24a80be6a | ||
|
c03ca62005 | ||
|
2f44516c7b | ||
|
52b47075d9 | ||
|
1325f17bf8 | ||
|
5150656914 | ||
|
874cd36bd0 | ||
|
aa462d16f8 | ||
|
4a73524c32 | ||
|
e9db9796e3 | ||
|
90df3de829 | ||
|
6fa6c7b686 | ||
|
9ae259dff6 | ||
|
669edf832c | ||
|
d97fe5a81c | ||
|
e88bb3565d | ||
|
306c2d370a | ||
|
b3245aa38d | ||
|
ed04663d08 | ||
|
352b3a9f37 | ||
|
f290fd7519 | ||
|
56eeaea61e | ||
|
34895de5bc | ||
1017b64913 | |||
100c22eb78 | |||
|
62c1661f04 | ||
|
d7ae1f0101 | ||
|
6b0854a273 | ||
|
3dd897f732 | ||
|
e56ef4d608 | ||
|
37156a8ac7 | ||
|
7fe96fda96 | ||
|
9d874e10a5 | ||
|
318462164d | ||
|
af5ba09d38 | ||
|
34b32761ce | ||
|
7350c5105d | ||
|
fea2d7b3c1 | ||
|
f11353c41b | ||
|
8bad3ed188 | ||
|
f40df54772 | ||
|
155b6c5926 | ||
|
559f2d7011 | ||
|
275a1691d1 | ||
|
81b27ddb2e | ||
|
904202488d | ||
|
2b089f3907 | ||
|
35ed664dfd | ||
|
48b28fc3cd | ||
|
4bd4eec53d | ||
|
71bb5af435 | ||
|
ff6ec13df4 | ||
|
22ecc4804e | ||
|
5696968f25 | ||
|
d383bc0c00 | ||
|
90dc2d691a | ||
|
5865cb722d | ||
|
dd0edef2ba | ||
|
400c216869 | ||
|
f2001ec446 | ||
|
d2cb5ad251 | ||
|
2ffa6c130c | ||
|
98a033798f | ||
|
4e2b21ae60 | ||
|
a57befcc69 | ||
|
c4f080184c | ||
|
1978948f4a | ||
|
af45726fe6 | ||
|
df780f4546 | ||
|
09b371036a | ||
|
7c884582a2 | ||
|
cfabdb950d | ||
|
f53065f7f6 | ||
|
624267fe45 | ||
|
401e335e5f | ||
|
ad63bcac02 | ||
|
1a66485d48 | ||
|
770a01a970 | ||
|
78cb2de9b6 | ||
|
4959ccb815 | ||
|
4c2432a35b | ||
|
3d73b9a4b2 | ||
|
c4b79a722c | ||
|
0514965040 | ||
|
bd5b3e1322 | ||
|
86f1fb3ca2 | ||
|
c805fd8eab | ||
|
9eab1525ef | ||
|
814523ba6e | ||
|
13161696ae | ||
|
354bb91234 | ||
|
05b913c53a | ||
|
5ee4ed5864 | ||
|
d4b3c9acc9 | ||
|
95342815e2 | ||
|
f35fb7b207 | ||
|
6177bc1794 | ||
|
878b2aa096 | ||
|
8ee6e1a55f | ||
|
d2ee60e053 | ||
|
39e61b85c4 | ||
|
0a2e37320a | ||
|
f70c3635a9 | ||
|
8050e10c30 | ||
|
3e8085110f | ||
|
2faac6be1a | ||
|
902f3edcf6 | ||
|
3bff7fd30b | ||
|
665db7a4d8 | ||
|
a7546419a4 | ||
|
8d30a041fe | ||
|
dd99ebdb0e | ||
|
03e7f62684 | ||
|
d092a49bab | ||
|
2390af6393 | ||
|
8b263f66a3 | ||
|
3203eed8aa | ||
|
a7742614df | ||
|
15b971412b | ||
|
f8ab89946d | ||
|
70435cee62 | ||
|
fefe1e23a4 | ||
|
477d55d8bf | ||
|
eac23907e7 | ||
|
eeb5ada610 | ||
|
36295d1861 | ||
|
3e82065fa4 | ||
|
6a763593ee | ||
|
d04b40c925 | ||
|
f5ff322c33 | ||
|
ac5f9309c8 | ||
|
79e34ce8cc | ||
|
3e7f000630 | ||
|
d897fa2a4b | ||
|
a8abfcd4a1 | ||
|
c00d5641e4 | ||
|
6bef518ffa | ||
|
311a48487d | ||
|
d305ccf9b3 | ||
|
c985f80452 | ||
|
fd4732d978 | ||
|
945e548ef7 | ||
|
18128ff263 | ||
|
70793cdfae | ||
|
30dcb113ae | ||
|
443d4ac1f3 | ||
|
88964a73eb | ||
|
fcaee13ba3 | ||
|
fab521ff7c | ||
|
7c139a8d0c | ||
|
5d8fa97aa2 | ||
|
f3c0c191db | ||
|
046636c40a | ||
|
c241338fbe | ||
|
d62370b069 | ||
|
ca728839ac | ||
|
05617a3b56 | ||
|
b77e2e6459 | ||
|
2d9c383ddd | ||
|
59fa5c2698 | ||
|
308f7431e7 | ||
|
86a76fc460 | ||
|
4e6bbdfed6 | ||
|
61fcfc83b0 | ||
|
f41fe487fa | ||
|
9b7af18f6a | ||
|
f6df4fda7e | ||
|
17d5d9efcf | ||
|
fed59f988f | ||
|
62d9f31d14 | ||
|
1862b6beb3 | ||
|
311697693f | ||
|
bc752ff2c3 | ||
|
02492dac52 | ||
|
647955fdf0 | ||
|
78ae5cebff | ||
|
a01efb8f92 | ||
|
3fde3df882 | ||
|
f2cfe967ee | ||
|
9839e8916e | ||
|
109a4fa25f | ||
|
e98213ad4c | ||
|
7aa7526a17 | ||
|
60ac53fe94 | ||
|
0df87dde57 | ||
|
8b7f0ace3a | ||
|
d35cf4d358 | ||
|
cae76032d1 | ||
|
f5907bf476 | ||
|
78559de051 | ||
|
d19c53e99a | ||
|
537cbe92f3 | ||
|
5235461791 | ||
|
97e4f4ae4f | ||
|
d007792f3a | ||
|
cdd4c83e4f | ||
|
0cd0337a39 | ||
|
72428be04b | ||
|
e3cfdda60b | ||
|
219bc18cc6 | ||
|
62c059b384 | ||
|
2c8a4ad86e | ||
|
d29ec0374e | ||
|
c99f75c908 | ||
|
f54c9bbd03 | ||
|
92713506e6 | ||
|
6ea38bc90b | ||
|
dbf9baca75 | ||
|
5aeb90852b | ||
|
8b0fe2cdaf | ||
|
8aac741b6f | ||
|
43264318c4 | ||
|
23fc8ef6d5 | ||
|
69f2cf4b4c | ||
|
e56943d659 | ||
|
3485a5b7db | ||
|
60decb3cfa | ||
|
7e6a5b2ba5 | ||
|
c6f4e4ce3e | ||
|
0670d74c1e | ||
|
44ab918292 | ||
|
0ac67766ee | ||
|
953747d90d | ||
|
62bda38b91 | ||
|
db99d2219e | ||
|
939f470666 | ||
|
05ede52ce5 | ||
|
d5589cc1c2 | ||
|
4ac430bc19 | ||
|
b95876e6a1 | ||
|
35f03ee26e | ||
|
7b8ae3a1d8 | ||
|
ca3bfcde1c | ||
|
523fe43b91 | ||
|
764fefb25a | ||
|
9ed88a1e02 | ||
|
46721d4212 | ||
|
111dbb30b9 | ||
|
d01135ac1b | ||
|
d06e80056a | ||
|
ce8ff6efe5 | ||
|
745ecd42aa | ||
|
fedb26fd43 | ||
|
6d632be7b8 | ||
|
79f41a7652 | ||
|
056b02522e | ||
|
4d9eeeb1d0 | ||
|
477b780805 | ||
|
a3709c187b | ||
|
3c0148ddc2 | ||
|
8de106cbb2 | ||
|
9ae189430d | ||
|
ea0a612e4f | ||
|
41cbdadb72 | ||
|
016a50878d | ||
|
3c4018ace3 | ||
|
37d730dfdc | ||
|
0f902f683c | ||
|
02ccb65b27 | ||
|
3b0c8ad3a6 | ||
|
560197eebe | ||
|
0dcac4f324 | ||
|
3ed01ba92f | ||
|
dd699b7165 | ||
|
5b7c2f7ec7 | ||
|
c8e2128c4c | ||
|
be42fe04fb | ||
|
7ca00fecbe | ||
|
f700addda5 | ||
|
5caac8452e | ||
|
02d965e2d9 | ||
|
45726bd388 | ||
|
25fde2aa65 | ||
|
29f1eb3503 | ||
|
2238a52c40 | ||
|
499b604cc3 | ||
|
8a2c03a587 | ||
|
24cdb08449 | ||
|
f7272e8549 | ||
|
136ca3f206 | ||
|
a1a870ed34 | ||
|
aa307e6b15 | ||
|
60301f4aab | ||
|
7fb7a8bec4 | ||
|
38cea82821 | ||
|
d76cc27e8e | ||
|
c86788e7fd | ||
|
9582689f2a | ||
|
dd690decb2 | ||
|
7d2479d5b6 | ||
|
8f52400aea | ||
|
1185785dbd | ||
|
f7d03f66cd | ||
|
05f79ecfa9 | ||
|
b6ab6a806e | ||
|
3ec2419086 | ||
|
6b5a55226b | ||
|
7aae9c62af | ||
|
260600a7f6 | ||
|
326ccaa6be | ||
|
c60d2ed866 | ||
|
9bffcfdf6a | ||
|
65576d5c43 | ||
|
efbf38ca33 | ||
|
73b3a01bc0 | ||
|
84f491bd40 | ||
|
ed6df71041 | ||
|
4db151de66 | ||
f209266260 | |||
932056f731 | |||
4178703f2b | |||
7cc69878ca | |||
|
68308b02a5 | ||
297d7f3cfd | |||
|
37bd252041 | ||
5de09b851b | |||
daf748b173 | |||
e91f6842ab | |||
d5a9d225f2 | |||
c994b0099e | |||
932ebd1821 | |||
a5ae672b9f | |||
234d28a8b8 | |||
4baa85a8c5 | |||
4351cf46b7 | |||
d520df6886 | |||
19d5ab9f06 | |||
|
e8c029186e | ||
|
991c5cb87c | ||
|
454013fd98 | ||
|
3aea482c3c | ||
|
a4836f1142 | ||
|
1ed740b7fa | ||
|
40724c3503 | ||
|
7fe647c3ab | ||
|
81a5b6633c | ||
|
a2b44cd288 | ||
|
7213f77254 | ||
|
46b3a54369 | ||
|
277c1b5359 | ||
|
a49c156007 | ||
|
a559ee24df | ||
|
65a9353c93 | ||
|
9b4929a4c7 | ||
|
543d07cfaf | ||
|
be903af3a4 | ||
|
abf632b3da | ||
|
db204335e6 | ||
|
8997c258a6 | ||
|
bd73cc2f7c | ||
|
5969deb49c | ||
|
60c824a7c2 | ||
|
663caccf7a | ||
|
2b4d50d469 | ||
|
7f73a9c61b | ||
|
c79e019594 | ||
|
4b21758506 | ||
|
5a908d6b61 | ||
|
cc900a16da | ||
|
033a23eaca | ||
|
bfb8956df2 | ||
|
603d68a7b3 | ||
|
3ca6b1a435 | ||
|
a47773cf98 | ||
|
ef34c5bcb1 | ||
|
97d8f0df2e | ||
|
7300b5bd5f | ||
|
2efa603474 | ||
|
8cdc01f3cb | ||
|
634f8b3aca | ||
|
c52bd054d6 | ||
|
28027ae58b | ||
|
0c7856b388 | ||
|
99ad9ecd63 | ||
|
535e48225d | ||
|
ef481b3192 | ||
|
77c5c3d872 | ||
|
65110bd1b4 | ||
|
1234f858e5 | ||
|
0caf4e740e | ||
|
a219883117 | ||
|
9a5738eb1c | ||
|
4a49c8c510 | ||
|
13d7b70ac5 | ||
|
f9b09fbde6 | ||
|
f5933e8bfa | ||
|
c39e4462e8 | ||
|
f6283a4c13 | ||
|
34358be637 | ||
|
45c1291711 | ||
|
550d7f5d3c | ||
|
f860e98018 | ||
|
cebcefe7e2 | ||
|
69b78d0829 | ||
|
3a7db2f7ca | ||
|
f07358cb4a | ||
|
7d6f3828fd | ||
|
daca2e6273 | ||
|
9f0fd7c657 | ||
|
88de2df3c0 | ||
|
858e14ee8c | ||
|
01570e856c | ||
|
55a1d3d5ad | ||
|
57f9fdec63 | ||
|
3a8d69b061 | ||
|
e48022b533 | ||
|
65c7c15c74 | ||
|
31265e7696 | ||
|
22789540ec | ||
|
fb2861ea21 | ||
|
0956496b99 | ||
|
33ab18e826 | ||
|
fe898a7a1c | ||
|
5960afd237 | ||
|
028be8d187 | ||
|
ac0df60a3e | ||
|
523b80fb4c | ||
|
a043dced97 | ||
|
21d00049ba | ||
|
ad4724ed69 | ||
|
3b0874db49 | ||
|
873498e20e | ||
|
3c5722c6d7 | ||
|
8e22dd10a8 | ||
|
1a873cd377 | ||
|
8d8d99e103 | ||
|
2990eadd07 | ||
|
06b23e5459 | ||
|
29d72b9c0e | ||
|
6ec7058094 | ||
|
09c650d487 | ||
|
f96095ad42 | ||
|
b82293d96d | ||
|
99c229fae7 | ||
|
ab5840babe | ||
|
11f9266f10 | ||
|
add02b208d | ||
|
25922d99f3 | ||
|
5cdd216cdb | ||
|
8682bd236e | ||
|
a139c7d351 | ||
|
0418ff76ad | ||
|
0eab3f1622 | ||
|
944552aba2 | ||
|
6b05ee31ab | ||
|
6e72662a1b | ||
|
d06d168850 | ||
|
01eaab29d5 | ||
|
3df5324732 | ||
|
8db64d903d | ||
|
c883a7b1d4 | ||
|
ca681cdb5b | ||
|
dd68103be6 | ||
|
75eb078565 | ||
|
2845a734ef | ||
|
a95936a490 | ||
|
4deedc73b4 | ||
|
e086322332 | ||
|
6b89174901 | ||
|
cb9590c189 | ||
|
99ce0d2b52 | ||
|
77089c79ec | ||
|
e21c26689a | ||
|
ef9cbf98b0 | ||
|
0a2d94e05b | ||
|
39c5886880 | ||
|
ee4ba00fe9 | ||
|
7494efb8ca | ||
|
fd41a589fe | ||
|
167d6c76ac | ||
|
c26db92799 | ||
|
7b49508b11 | ||
|
215bcca079 | ||
|
54cb77b136 | ||
|
b03312f73c | ||
|
2ff27e197b | ||
|
2131df0cd9 | ||
|
d67485af13 | ||
|
df503face9 | ||
|
fe6b4b1c48 | ||
|
b64aa60fa0 | ||
|
1bdb16ed64 | ||
|
3cdcc411a4 | ||
|
027ff8f029 | ||
|
bed05b0592 | ||
|
8bba31b0e2 | ||
|
7a8f960bc0 | ||
|
925ad5f538 | ||
|
f4dbffa7e4 | ||
|
c606be50ef | ||
|
95606d1f0a | ||
|
3556dd9618 | ||
|
877c85575f | ||
|
b266fe6e4f | ||
|
f4a42dae1b | ||
|
e4c8d5b653 | ||
|
7277b5e4a2 | ||
|
c3bad92656 | ||
|
d461059cf0 | ||
|
e54d5278ac | ||
|
c58867577f | ||
|
3cec244e15 | ||
|
999cb74865 | ||
|
d90d09b9ce | ||
|
10c7f00881 | ||
|
47152eb7fb | ||
|
6dbda6f653 | ||
|
2b051ef97b | ||
|
8b886737b8 | ||
|
44ab6fc1e9 | ||
|
85458aa975 | ||
|
672a061f28 | ||
|
f28dc0f500 | ||
|
3bc61705b1 | ||
|
f8ede2240a | ||
|
0b0d046d04 | ||
|
20b7643657 | ||
|
59ebafdf81 | ||
|
60c5be549c | ||
|
55c6f4d093 | ||
|
48f5ad1810 | ||
|
80b6ef4c9b | ||
|
3a89bfeca1 | ||
|
7a723f5250 | ||
|
0e04e44e1f | ||
|
938bb20c3f | ||
|
97a96b5947 | ||
|
37149ec831 | ||
|
5112a6a13b | ||
|
0556d07a56 | ||
|
8d484f62ea | ||
|
4fd6595ded | ||
|
ffd3ac2edf | ||
|
8378d35149 | ||
|
f40eaf1a23 | ||
|
cc880a15fc | ||
|
f15cb63d32 | ||
|
6af93506f1 | ||
|
d0475b22c1 | ||
|
25929d82f4 | ||
|
ccbe2cd580 | ||
|
06a38e9383 | ||
|
af789a7060 | ||
|
ad2c96c667 | ||
|
64428872df | ||
|
abdc734833 | ||
|
5a1b4552ce | ||
|
488a86cbac | ||
|
9325d819c7 | ||
|
01c56da52c | ||
|
2201f188bd | ||
|
672d089b20 | ||
|
2a6766c10e | ||
|
e7eeac9f34 | ||
|
9832ca58ba | ||
|
36f8de957a | ||
|
c3e70309bc | ||
|
41123e987b | ||
|
0ceaafc0ec | ||
|
9b2aa355b9 | ||
|
5550565615 | ||
|
c3e6fd5b35 | ||
|
b53e9aafd7 | ||
|
4c7449ea3e | ||
|
c1638aeb98 | ||
|
08d7347f00 | ||
|
54baa4d6ba | ||
|
2a145bfa3e | ||
|
b4dcbc9846 | ||
|
ca499d5eac | ||
|
c8485c0fa3 | ||
|
31ced3f572 | ||
|
1b6cca8ddf | ||
|
1cb4209be2 | ||
|
843528252b | ||
|
dc0c8a351b | ||
|
489f191a13 | ||
|
1a8a989e87 | ||
|
044faa77f6 | ||
|
65b10bae3c | ||
|
7e966b93a5 | ||
|
ee3a425c59 | ||
|
44239ed459 | ||
|
dd0119602b | ||
|
6f87dfc149 | ||
|
d476f86c8c | ||
|
bc9bb698c5 | ||
|
e44baa99c2 | ||
|
e22d318b92 | ||
|
44e45852d0 | ||
|
d7a25b7c7a | ||
|
4e438d9fd3 | ||
|
cecd302957 | ||
|
b76e2afac1 | ||
|
98cbd6e4dd | ||
|
176b786279 | ||
|
bbdb03d103 | ||
|
2b792cff72 | ||
|
a702d157cd | ||
|
ad43c420bb | ||
|
2b0d2bb9cc | ||
|
a2c98a5a26 | ||
|
a4af2e668f | ||
|
8968be1ffd | ||
|
e68ecf50c6 | ||
|
2ef67de718 | ||
|
ecbd2fd94a | ||
|
e1176ec4ee | ||
|
fc38673b7d | ||
|
dc07f5e757 | ||
|
ba0a035d88 | ||
|
6721c558af | ||
|
aff8dadd27 | ||
|
93431e9a98 | ||
|
17f6bb770d | ||
|
96120bc744 | ||
|
c184469219 | ||
|
d9000c12c7 | ||
|
5e21877efc | ||
|
b7cbca03a7 | ||
|
f9845624d4 | ||
|
403b87bbda | ||
|
4942fdbfda | ||
|
d1ae2a8009 | ||
|
273feb676c | ||
|
80e69f3ef0 | ||
|
2ca6d230e3 | ||
|
6924ae0fb7 | ||
|
0215657650 | ||
|
24e2607fe3 | ||
|
a43338a017 | ||
|
0b44970041 | ||
|
8ef0ed6a29 | ||
|
f63f141177 | ||
|
92b4f8e4d0 | ||
|
9e4ec347cf | ||
|
6a42560c0c | ||
|
7ee6f353aa | ||
|
5ae2c1c4a4 | ||
|
628031a11e | ||
|
3557d5a97f | ||
|
d5dce1f931 | ||
|
081fcf779c | ||
|
27a1efafcf | ||
|
030b62389e | ||
|
6b0e7f17bb | ||
|
660c28e2f8 | ||
|
910e753314 | ||
|
b58cfda4c8 | ||
|
2050174cd7 | ||
|
788fb3462c | ||
|
93c7ddc528 | ||
|
93fb2e63f2 | ||
|
d3dfd7f326 | ||
|
76d47a6f64 | ||
|
177af6b0ec | ||
|
76dab03bc3 | ||
|
3f7a57fd66 |
110
.gitignore
vendored
110
.gitignore
vendored
@ -1,9 +1,14 @@
|
||||
# Mods for HESK-specific files
|
||||
api/vendor
|
||||
api/Tests/integration_test_mfh_settings.php
|
||||
|
||||
# HESK Files
|
||||
admin/admin_suggest_articles.php
|
||||
admin/archive.php
|
||||
admin/custom_statuses.php
|
||||
admin/email_templates.php
|
||||
admin/generate_spam_question.php
|
||||
admin/priority.php
|
||||
admin/resend_notification.php
|
||||
admin/test_connection.php
|
||||
attachments/index.htm
|
||||
cache/
|
||||
@ -15,6 +20,7 @@ header.txt
|
||||
hesk_settings.inc.php
|
||||
img/add_article.png
|
||||
img/add_category.png
|
||||
img/anonymize.png
|
||||
img/article_text.png
|
||||
img/autoassign_off.png
|
||||
img/autoassign_on.png
|
||||
@ -30,8 +36,10 @@ img/delete.png
|
||||
img/delete_off.png
|
||||
img/delete_ticket.png
|
||||
img/edit.png
|
||||
img/email.png
|
||||
img/error.png
|
||||
img/existingticket.png
|
||||
img/export.png
|
||||
img/flag_critical.png
|
||||
img/flag_high.png
|
||||
img/flag_low.png
|
||||
@ -77,6 +85,7 @@ img/lock.png
|
||||
img/login.png
|
||||
img/mail.png
|
||||
img/manage.png
|
||||
img/menu.png
|
||||
img/minus.gif
|
||||
img/minusbottom.gif
|
||||
img/minustop.gif
|
||||
@ -193,60 +202,60 @@ inc/tabs/tabber-minimized.js
|
||||
inc/tabs/tabber.css
|
||||
inc/timer/hesk_timer.js
|
||||
inc/timer/index.htm
|
||||
inc/tiny_mce/3.5.11/langs/en.js
|
||||
inc/tiny_mce/3.5.11/license.txt
|
||||
inc/tiny_mce/3.5.11/themes/advanced/about.htm
|
||||
inc/tiny_mce/3.5.11/themes/advanced/anchor.htm
|
||||
inc/tiny_mce/3.5.11/themes/advanced/charmap.htm
|
||||
inc/tiny_mce/3.5.11/themes/advanced/color_picker.htm
|
||||
inc/tiny_mce/3.5.11/themes/advanced/editor_template.js
|
||||
inc/tiny_mce/3.5.11/themes/advanced/image.htm
|
||||
inc/tiny_mce/3.5.11/themes/advanced/img/colorpicker.jpg
|
||||
inc/tiny_mce/3.5.11/themes/advanced/img/flash.gif
|
||||
inc/tiny_mce/3.5.11/themes/advanced/img/icons.gif
|
||||
inc/tiny_mce/3.5.11/themes/advanced/img/iframe.gif
|
||||
inc/tiny_mce/3.5.11/themes/advanced/img/pagebreak.gif
|
||||
inc/tiny_mce/3.5.11/themes/advanced/img/quicktime.gif
|
||||
inc/tiny_mce/3.5.11/themes/advanced/img/realmedia.gif
|
||||
inc/tiny_mce/3.5.11/themes/advanced/img/shockwave.gif
|
||||
inc/tiny_mce/3.5.11/themes/advanced/img/trans.gif
|
||||
inc/tiny_mce/3.5.11/themes/advanced/img/video.gif
|
||||
inc/tiny_mce/3.5.11/themes/advanced/img/windowsmedia.gif
|
||||
inc/tiny_mce/3.5.11/themes/advanced/js/about.js
|
||||
inc/tiny_mce/3.5.11/themes/advanced/js/anchor.js
|
||||
inc/tiny_mce/3.5.11/themes/advanced/js/charmap.js
|
||||
inc/tiny_mce/3.5.11/themes/advanced/js/color_picker.js
|
||||
inc/tiny_mce/3.5.11/themes/advanced/js/image.js
|
||||
inc/tiny_mce/3.5.11/themes/advanced/js/link.js
|
||||
inc/tiny_mce/3.5.11/themes/advanced/js/source_editor.js
|
||||
inc/tiny_mce/3.5.11/themes/advanced/langs/en.js
|
||||
inc/tiny_mce/3.5.11/themes/advanced/langs/en_dlg.js
|
||||
inc/tiny_mce/3.5.11/themes/advanced/link.htm
|
||||
inc/tiny_mce/3.5.11/themes/advanced/shortcuts.htm
|
||||
inc/tiny_mce/3.5.11/themes/advanced/skins/default/content.css
|
||||
inc/tiny_mce/3.5.11/themes/advanced/skins/default/dialog.css
|
||||
inc/tiny_mce/3.5.11/themes/advanced/skins/default/img/buttons.png
|
||||
inc/tiny_mce/3.5.11/themes/advanced/skins/default/img/items.gif
|
||||
inc/tiny_mce/3.5.11/themes/advanced/skins/default/img/menu_arrow.gif
|
||||
inc/tiny_mce/3.5.11/themes/advanced/skins/default/img/menu_check.gif
|
||||
inc/tiny_mce/3.5.11/themes/advanced/skins/default/img/progress.gif
|
||||
inc/tiny_mce/3.5.11/themes/advanced/skins/default/img/tabs.gif
|
||||
inc/tiny_mce/3.5.11/themes/advanced/skins/default/ui.css
|
||||
inc/tiny_mce/3.5.11/themes/advanced/source_editor.htm
|
||||
inc/tiny_mce/3.5.11/tiny_mce.js
|
||||
inc/tiny_mce/3.5.11/tiny_mce_popup.js
|
||||
inc/tiny_mce/3.5.11/utils/editable_selects.js
|
||||
inc/tiny_mce/3.5.11/utils/form_utils.js
|
||||
inc/tiny_mce/3.5.11/utils/mctabs.js
|
||||
inc/tiny_mce/3.5.11/utils/validate.js
|
||||
inc/tiny_mce/3.5.12/langs/en.js
|
||||
inc/tiny_mce/3.5.12/license.txt
|
||||
inc/tiny_mce/3.5.12/themes/advanced/about.htm
|
||||
inc/tiny_mce/3.5.12/themes/advanced/anchor.htm
|
||||
inc/tiny_mce/3.5.12/themes/advanced/charmap.htm
|
||||
inc/tiny_mce/3.5.12/themes/advanced/color_picker.htm
|
||||
inc/tiny_mce/3.5.12/themes/advanced/editor_template.js
|
||||
inc/tiny_mce/3.5.12/themes/advanced/image.htm
|
||||
inc/tiny_mce/3.5.12/themes/advanced/img/colorpicker.jpg
|
||||
inc/tiny_mce/3.5.12/themes/advanced/img/flash.gif
|
||||
inc/tiny_mce/3.5.12/themes/advanced/img/icons.gif
|
||||
inc/tiny_mce/3.5.12/themes/advanced/img/iframe.gif
|
||||
inc/tiny_mce/3.5.12/themes/advanced/img/pagebreak.gif
|
||||
inc/tiny_mce/3.5.12/themes/advanced/img/quicktime.gif
|
||||
inc/tiny_mce/3.5.12/themes/advanced/img/realmedia.gif
|
||||
inc/tiny_mce/3.5.12/themes/advanced/img/shockwave.gif
|
||||
inc/tiny_mce/3.5.12/themes/advanced/img/trans.gif
|
||||
inc/tiny_mce/3.5.12/themes/advanced/img/video.gif
|
||||
inc/tiny_mce/3.5.12/themes/advanced/img/windowsmedia.gif
|
||||
inc/tiny_mce/3.5.12/themes/advanced/js/about.js
|
||||
inc/tiny_mce/3.5.12/themes/advanced/js/anchor.js
|
||||
inc/tiny_mce/3.5.12/themes/advanced/js/charmap.js
|
||||
inc/tiny_mce/3.5.12/themes/advanced/js/color_picker.js
|
||||
inc/tiny_mce/3.5.12/themes/advanced/js/image.js
|
||||
inc/tiny_mce/3.5.12/themes/advanced/js/link.js
|
||||
inc/tiny_mce/3.5.12/themes/advanced/js/source_editor.js
|
||||
inc/tiny_mce/3.5.12/themes/advanced/langs/en.js
|
||||
inc/tiny_mce/3.5.12/themes/advanced/langs/en_dlg.js
|
||||
inc/tiny_mce/3.5.12/themes/advanced/link.htm
|
||||
inc/tiny_mce/3.5.12/themes/advanced/shortcuts.htm
|
||||
inc/tiny_mce/3.5.12/themes/advanced/skins/default/content.css
|
||||
inc/tiny_mce/3.5.12/themes/advanced/skins/default/dialog.css
|
||||
inc/tiny_mce/3.5.12/themes/advanced/skins/default/img/buttons.png
|
||||
inc/tiny_mce/3.5.12/themes/advanced/skins/default/img/items.gif
|
||||
inc/tiny_mce/3.5.12/themes/advanced/skins/default/img/menu_arrow.gif
|
||||
inc/tiny_mce/3.5.12/themes/advanced/skins/default/img/menu_check.gif
|
||||
inc/tiny_mce/3.5.12/themes/advanced/skins/default/img/progress.gif
|
||||
inc/tiny_mce/3.5.12/themes/advanced/skins/default/img/tabs.gif
|
||||
inc/tiny_mce/3.5.12/themes/advanced/skins/default/ui.css
|
||||
inc/tiny_mce/3.5.12/themes/advanced/source_editor.htm
|
||||
inc/tiny_mce/3.5.12/tiny_mce.js
|
||||
inc/tiny_mce/3.5.12/tiny_mce_popup.js
|
||||
inc/tiny_mce/3.5.12/utils/editable_selects.js
|
||||
inc/tiny_mce/3.5.12/utils/form_utils.js
|
||||
inc/tiny_mce/3.5.12/utils/mctabs.js
|
||||
inc/tiny_mce/3.5.12/utils/validate.js
|
||||
inc/treemenu/TreeMenu.php
|
||||
inc/treemenu/index.htm
|
||||
inc/users_online.inc.php
|
||||
inc/zip/Zip.php
|
||||
inc/zip/index.htm
|
||||
inc/zip/pclzip.lib.php
|
||||
install/hesk.png
|
||||
install/update.php
|
||||
language/en/help_files
|
||||
language/en/emails/category_moved.txt
|
||||
language/en/emails/forgot_ticket_id.txt
|
||||
language/en/emails/index.htm
|
||||
@ -257,16 +266,15 @@ language/en/emails/new_ticket.txt
|
||||
language/en/emails/new_ticket_staff.txt
|
||||
language/en/emails/ticket_assigned_to_you.txt
|
||||
language/en/index.htm
|
||||
language/en/text.php
|
||||
language/index.htm
|
||||
language/*
|
||||
!language/en
|
||||
print_sec_img.php
|
||||
rate.php
|
||||
readme.html
|
||||
robots.txt
|
||||
.idea/
|
||||
attachments/__latest.txt
|
||||
attachments
|
||||
/attachments
|
||||
img/ban.png
|
||||
img/banned.png
|
||||
img/ico_tools.png
|
||||
|
90
.gitlab-ci.yml
Normal file
90
.gitlab-ci.yml
Normal file
@ -0,0 +1,90 @@
|
||||
stages:
|
||||
- validate
|
||||
- test
|
||||
- package
|
||||
|
||||
before_script:
|
||||
- bash ci/docker_install.sh > /dev/null
|
||||
|
||||
validate:7.2:
|
||||
image: php:7.2
|
||||
stage: validate
|
||||
script:
|
||||
- bash ci/php_lint.sh ./
|
||||
|
||||
validate:7.1:
|
||||
image: php:7.1
|
||||
stage: validate
|
||||
script:
|
||||
- bash ci/php_lint.sh ./
|
||||
|
||||
validate:7.0:
|
||||
image: php:7.0
|
||||
stage: validate
|
||||
script:
|
||||
- bash ci/php_lint.sh ./
|
||||
|
||||
validate:5.6:
|
||||
image: php:5.6
|
||||
stage: validate
|
||||
script:
|
||||
- bash ci/php_lint.sh ./
|
||||
|
||||
validate:5.5:
|
||||
image: php:5.5
|
||||
stage: validate
|
||||
script:
|
||||
- bash ci/php_lint.sh ./
|
||||
|
||||
validate:5.4:
|
||||
image: php:5.4
|
||||
stage: validate
|
||||
script:
|
||||
- bash ci/php_lint.sh ./
|
||||
|
||||
validate:5.3:
|
||||
image: php:5.3
|
||||
stage: validate
|
||||
script:
|
||||
- bash ci/php_lint.sh ./
|
||||
|
||||
test:7.1:
|
||||
image: php:7.1
|
||||
stage: test
|
||||
script:
|
||||
- cd api
|
||||
- php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');"
|
||||
- php composer-setup.php
|
||||
- php -r "unlink('composer-setup.php');"
|
||||
- php composer.phar update
|
||||
- php composer.phar install
|
||||
- cd Tests
|
||||
- phpunit
|
||||
|
||||
test:7.2:
|
||||
image: php:7.2
|
||||
stage: test
|
||||
script:
|
||||
- cd api
|
||||
- php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');"
|
||||
- php composer-setup.php
|
||||
- php -r "unlink('composer-setup.php');"
|
||||
- php composer.phar update
|
||||
- php composer.phar install
|
||||
- cd Tests
|
||||
- phpunit
|
||||
|
||||
package:
|
||||
image: tetraweb/php
|
||||
when: manual
|
||||
stage: package
|
||||
script:
|
||||
- apt-get update
|
||||
- apt-get install zip unzip
|
||||
- cd api
|
||||
- composer install --no-dev
|
||||
- cd ../ci
|
||||
- bash build_zip.sh
|
||||
artifacts:
|
||||
paths:
|
||||
- release.zip
|
@ -2,15 +2,15 @@
|
||||
So you want to contribute to Mods for HESK? Awesome! However, there are a few guidelines that need to be followed so the project can be as easy to maintain as possible.
|
||||
|
||||
## Submitting an issue
|
||||
If all you are doing is submitting an issue, please check if your "issue" qualifies as a GitHub issue:
|
||||
- **Feature Requests:** Feature requests are now being recorded at the Mods for HESK [UserVoice page](https://mods-for-hesk.uservoice.com/forums/254758-general). Please do not open these types of issues on GitHub. Issues opened that are "feature requests" will be closed.
|
||||
- **Translations:** Translations are now being recorded at the official Mods for HESK [website](https://mods-for-hesk.mkochcs.com/download.php). Please do not open these types of issues on GitHub. Issues opened that pertain to submitting new translations will be closed.
|
||||
If all you are doing is submitting an issue, please check if your "issue" qualifies as a GitLab issue:
|
||||
- **Feature Requests:** Feature requests are now being recorded at the Mods for HESK [UserVoice page](https://mods-for-hesk.uservoice.com/forums/254758-general). Please do not open these types of issues on GitLab. Issues opened that are "feature requests" will be closed.
|
||||
- **Translations:** Translations are now being recorded at the official Mods for HESK [website](https://mods-for-hesk.mkochcs.com/download.php). Please do not open these types of issues on GitLab. Issues opened that pertain to submitting new translations will be closed.
|
||||
- **Bugs:** Yes, please open these types of issues here. :grinning:
|
||||
|
||||
## Getting Started
|
||||
If you have already completed any of these steps in the past (such as creating a GitHub account), you can skip the respective step.
|
||||
- Make sure you have a [GitHub account](http://github.com/signup/free)
|
||||
- Fork the repository on GitHub (for more help consult the [GitHub documentation](https://help.github.com/articles/fork-a-repo/))
|
||||
If you have already completed any of these steps in the past (such as creating a GitLab account), you can skip the respective step.
|
||||
- Make sure you have a [GitLab account](https://gitlab.com/users/sign_in)
|
||||
- Fork the repository on GitLab
|
||||
|
||||
## Making Changes
|
||||
- Create a feature branch from where to base your work off of
|
||||
@ -22,7 +22,6 @@ If you have already completed any of these steps in the past (such as creating a
|
||||
|
||||
## Submitting Changes
|
||||
- Push your changes to a topic branch in your fork of the repository
|
||||
- Submit a pull request to the official Mods for HESK repository (mkoch227/Mods-for-HESK)
|
||||
- If necessary, sign the Contributor License Agreement by checking the "status checks" area of your pull request.
|
||||
- The owner of Mods for HESK will then inspect and test the code in the pull request. Feedback will be given via GitHub comments.
|
||||
- Submit a pull request to the official Mods for HESK repository (mike-koch/Mods-for-HESK)
|
||||
- The owner of Mods for HESK will then inspect and test the code in the pull request. Feedback will be given via GitLab comments.
|
||||
- The owner of Mods for HESK expects responses within two weeks of the original comment. If there is no feedback within that time range, the pull request will be considered abandoned and subsequently will be closed.
|
||||
|
@ -54,7 +54,15 @@ else {
|
||||
?>
|
||||
<div class="content-wrapper">
|
||||
<section class="content">
|
||||
<?php hesk_handle_messages(); ?>
|
||||
<?php
|
||||
// Service messages
|
||||
$service_messages = mfh_get_service_messages('STAFF_HOME');
|
||||
foreach ($service_messages as $sm) {
|
||||
hesk_service_message($sm);
|
||||
}
|
||||
|
||||
hesk_handle_messages();
|
||||
?>
|
||||
<div class="box">
|
||||
<div class="box-header with-border">
|
||||
<h1 class="box-title">
|
||||
@ -100,23 +108,17 @@ else {
|
||||
</div>
|
||||
</div>
|
||||
<?php
|
||||
$hesk_settings['hesk_license']('HMgPSAxOw0KaWYgKGZpbGVfZXhpc3RzKEhFU0tfUEFUSCAuI
|
||||
CdoZXNrX2xpY2Vuc2UucGhwJykpDQp7DQokaCA9ICghZW1wdHkoJF9TRVJWRVJbJ0hUVFBfSE9TVCddK
|
||||
SkgPyAkX1NFUlZFUlsnSFRUUF9IT1NUJ10gOiAoKCFlbXB0eSgkX1NFUlZFUlsnU0VSVkVSX05BTUUnX
|
||||
SkpID8gJF9TRVJWRVJbJ1NFUlZFUl9OQU1FJ10gOiBnZXRlbnYoJ1NFUlZFUl9OQU1FJykpOw0KJGggP
|
||||
SBzdHJfcmVwbGFjZSgnd3d3LicsJycsc3RydG9sb3dlcigkaCkpOw0KaW5jbHVkZShIRVNLX1BBVEggL
|
||||
iAnaGVza19saWNlbnNlLnBocCcpOw0KaWYgKGlzc2V0KCRoZXNrX3NldHRpbmdzWydsaWNlbnNlJ10pI
|
||||
CYmIHN0cnBvcygkaGVza19zZXR0aW5nc1snbGljZW5zZSddLHNoYTEoJGguJ2gzJkZwMiNMYUEmNTkhd
|
||||
yg4LlpjXSordVI1MTInKSkgIT09IGZhbHNlKQ0Kew0KJHMgPSAwOw0KfQ0KZWxzZQ0Kew0KZWNobyAnP
|
||||
HAgc3R5bGU9InRleHQtYWxpZ246Y2VudGVyO2NvbG9yOnJlZDsiPklOVkFMSUQgTElDRU5TRSAoTk9UI
|
||||
FJFR0lTVEVSRUQgRk9SICcuJGguJykhPC9wPic7DQp9DQp9DQppZiAoJHMpDQp7DQplY2hvICc8aHIgL
|
||||
z48dGFibGUgYm9yZGVyPSIwIiB3aWR0aD0iMTAwJSI+PHRyPjx0ZD48Yj4nLiRoZXNrbGFuZ1sncmVtb
|
||||
3ZlX3N0YXRlbWVudCddLic8L2I+PC90ZD48dGQgc3R5bGU9InRleHQtYWxpZ246cmlnaHQiPjxhIGhyZ
|
||||
WY9IkphdmFzY3JpcHQ6dm9pZCgwKSIgb25jbGljaz0iYWxlcnQoXCcnLiRoZXNrbGFuZ1snc3VwcG9yd
|
||||
F9ub3RpY2UnXS4nXCcpIj4nLiRoZXNrbGFuZ1snc2gnXS4nPC9hPjwvdGQ+PC90cj48L3RhYmxlPjxwP
|
||||
icuJGhlc2tsYW5nWydzdXBwb3J0X3JlbW92ZSddLicuIDxhIGhyZWY9Imh0dHBzOi8vd3d3Lmhlc2suY
|
||||
29tL2J1eS5waHAiIHRhcmdldD0iX2JsYW5rIj4nLiRoZXNrbGFuZ1snY2xpY2tfaW5mbyddLic8L2E+P
|
||||
C9wPic7DQp9DQo=', "\112");
|
||||
/*******************************************************************************
|
||||
The code below handles HESK licensing. Removing or modifying this code without
|
||||
purchasing a HESK license is strictly prohibited.
|
||||
|
||||
To purchase a HESK license and support future HESK development please visit:
|
||||
https://www.hesk.com/buy.php
|
||||
*******************************************************************************/
|
||||
$x1a="\142a".chr(0163).chr(847249408>>23)."\66\x34".chr(796917760>>23)."\x65\156\143".chr(0157)."\x64\145";$hesk_settings['hesk_license']($x1a("\x3c\150r\x20\57\76".chr(503316480>>23)."\x74\141\142l\x65\40".chr(0142).chr(0157).chr(0162)."\144\145r\x3d\42\60".chr(285212672>>23)."\x20\x77\x69".chr(0144)."th".chr(511705088>>23)."\x22".chr(061)."\60\60\x25\42".chr(520093696>>23)."\x3c\164".chr(0162).">\74t\x64\x3e\x3c".chr(0142).chr(076).$hesklang[chr(956301312>>23)."\145\155\157\x76e".chr(796917760>>23)."\x73ta\164e\x6d".chr(847249408>>23)."\156\x74"].chr(503316480>>23)."\x2f\142\x3e".chr(074)."\57t\x64\76".chr(074)."td".chr(268435456>>23)."\x73ty\154\x65\x3d\x22te".chr(1006632960>>23)."t\x2d\141\x6c\x69".chr(0147).chr(922746880>>23)."\x3ar\151\x67ht\"\76".chr(503316480>>23)."\141 \x68\162\145\146\x3d\42".chr(0112).chr(813694976>>23)."v\141".chr(0163).chr(830472192>>23)."\162\x69".chr(0160).chr(0164)."\x3a".chr(989855744>>23)."\157\151d\50\x30".chr(343932928>>23).chr(042)."\40onc\154\151\143\153\x3d".chr(042)."\x61\x6c\145\x72t(\x27".$hesklang["\163".chr(981467136>>23)."\x70".chr(939524096>>23).chr(0157)."\162\164\137n".chr(931135488>>23)."\x74\151".chr(0143)."\x65"].chr(047)."\51\42\x3e".$hesklang["\x73\x68"]."\74".chr(394264576>>23)."\x61\x3e\74\57\164d\76\x3c/\x74\162\76".chr(503316480>>23).chr(057)."t\x61\x62\x6ce\x3e\x3c\x70\x3e".$hesklang[chr(0163)."\x75ppo\x72\x74\137".chr(956301312>>23).chr(847249408>>23)."\155".chr(931135488>>23)."v\x65"]."\x2e\x20\x3c".chr(813694976>>23)."\40\x68re\x66\x3d".chr(285212672>>23)."\150".chr(973078528>>23).chr(973078528>>23)."\160\x73".chr(486539264>>23)."\57\x2f".chr(998244352>>23)."\x77\167".chr(056)."\150".chr(847249408>>23)."s\153\56\x63\157".chr(0155)."/".chr(0142)."\165\171.".chr(0160)."h\x70".chr(285212672>>23)."\x20\x74\141".chr(0162)."g".chr(847249408>>23)."\164\x3d".chr(042)."\137b\x6c".chr(813694976>>23)."\x6ek\x22\76".$hesklang["\x63\154\151\143\153\x5f".chr(880803840>>23)."\x6e".chr(855638016>>23).chr(0157)]."\x3c/\141\x3e\x3c\x2fp".chr(076)."<\150\162\x20\x2f\x3e"),"");
|
||||
/*******************************************************************************
|
||||
END LICENSE CODE
|
||||
*******************************************************************************/
|
||||
|
||||
/* Clean unneeded session variables */
|
||||
hesk_cleanSessionVars('hide');
|
||||
|
@ -189,15 +189,20 @@ if ($hesk_settings['attachments']['use'] && !empty($attachments)) {
|
||||
// Add reply
|
||||
$html = $modsForHesk_settings['rich_text_for_tickets'];
|
||||
if ($submit_as_customer) {
|
||||
hesk_dbQuery("INSERT INTO `" . hesk_dbEscape($hesk_settings['db_pfix']) . "replies` (`replyto`,`name`,`message`,`dt`,`attachments`,`html`) VALUES ('" . intval($replyto) . "','" . hesk_dbEscape(addslashes($ticket['name'])) . "','" . hesk_dbEscape($message . "<br /><br /><i>{$hesklang['creb']} {$_SESSION['name']}</i>") . "',NOW(),'" . hesk_dbEscape($myattachments) . "', '" . $html . "')");
|
||||
hesk_dbQuery("INSERT INTO `" . hesk_dbEscape($hesk_settings['db_pfix']) . "replies` (`replyto`,`name`,`message`,`dt`,`attachments`,`html`) VALUES ('" . intval($replyto) . "','" . hesk_dbEscape(addslashes($ticket['name'])) . "','" . hesk_dbEscape($message . "<br /><br /><i>{$hesklang['creb']} {$_SESSION['name']}</i>") . "', NOW(),'" . hesk_dbEscape($myattachments) . "', '" . $html . "')");
|
||||
} else {
|
||||
hesk_dbQuery("INSERT INTO `" . hesk_dbEscape($hesk_settings['db_pfix']) . "replies` (`replyto`,`name`,`message`,`dt`,`attachments`,`staffid`,`html`) VALUES ('" . intval($replyto) . "','" . hesk_dbEscape(addslashes($_SESSION['name'])) . "','" . hesk_dbEscape($message) . "',NOW(),'" . hesk_dbEscape($myattachments) . "','" . intval($_SESSION['id']) . "', '" . $html . "')");
|
||||
hesk_dbQuery("INSERT INTO `" . hesk_dbEscape($hesk_settings['db_pfix']) . "replies` (`replyto`,`name`,`message`,`dt`,`attachments`,`staffid`,`html`) VALUES ('" . intval($replyto) . "','" . hesk_dbEscape(addslashes($_SESSION['name'])) . "','" . hesk_dbEscape($message) . "', NOW(),'" . hesk_dbEscape($myattachments) . "','" . intval($_SESSION['id']) . "', '" . $html . "')");
|
||||
}
|
||||
|
||||
/* Track ticket status changes for history */
|
||||
$revision = '';
|
||||
|
||||
/* Change the status of priority? */
|
||||
$audit_priority = null;
|
||||
$audit_closed = null;
|
||||
$audit_status = null;
|
||||
$audit_customer_status = null;
|
||||
$audit_assigned_self = null;
|
||||
if (!empty($_POST['set_priority'])) {
|
||||
$priority = intval(hesk_POST('priority'));
|
||||
if ($priority < 0 || $priority > 3) {
|
||||
@ -211,9 +216,17 @@ if (!empty($_POST['set_priority'])) {
|
||||
3 => $hesklang['low']
|
||||
);
|
||||
|
||||
$revision = sprintf($hesklang['thist8'], hesk_date(), $options[$priority], $_SESSION['name'] . ' (' . $_SESSION['user'] . ')');
|
||||
$plain_options = array(
|
||||
0 => 'critical',
|
||||
1 => 'high',
|
||||
2 => 'medium',
|
||||
3 => 'low'
|
||||
);
|
||||
|
||||
$priority_sql = ",`priority`='$priority', `history`=CONCAT(`history`,'" . hesk_dbEscape($revision) . "') ";
|
||||
$priority_sql = ",`priority`='$priority' ";
|
||||
|
||||
$audit_priority = array(0 => $_SESSION['name'] . ' (' . $_SESSION['user'] . ')',
|
||||
1 => $plain_options[$priority]);
|
||||
} else {
|
||||
$priority_sql = "";
|
||||
}
|
||||
@ -234,12 +247,15 @@ if ($ticket['locked']) {
|
||||
|
||||
if ($ticket['status'] != $new_status) {
|
||||
// Does this status close the ticket?
|
||||
$newStatusRs = hesk_dbQuery('SELECT `IsClosed`, `Key` FROM `' . hesk_dbEscape($hesk_settings['db_pfix']) . 'statuses` WHERE `ID` = ' . hesk_dbEscape($new_status));
|
||||
$newStatusRs = hesk_dbQuery('SELECT `IsClosed`, `Key` FROM `' . hesk_dbEscape($hesk_settings['db_pfix']) . 'statuses` WHERE `ID` = ' . intval($new_status));
|
||||
$newStatus = hesk_dbFetchAssoc($newStatusRs);
|
||||
|
||||
if ($newStatus['IsClosed'] && hesk_checkPermission('can_resolve', 0)) {
|
||||
$revision = sprintf($hesklang['thist3'], hesk_date(), $_SESSION['name'] . ' (' . $_SESSION['user'] . ')');
|
||||
$sql_status = " , `closedat`=NOW(), `closedby`=" . intval($_SESSION['id']) . ", `history`=CONCAT(`history`,'" . hesk_dbEscape($revision) . "') ";
|
||||
$audit_closed = array(0 => $_SESSION['name'] . ' (' . $_SESSION['user'] . ')');
|
||||
$audit_status = array(0 => $_SESSION['name'] . ' (' . $_SESSION['user'] . ')',
|
||||
1 => mfh_getDisplayTextForStatusId($new_status)
|
||||
);
|
||||
$sql_status = " , `closedat`=NOW(), `closedby`=" . intval($_SESSION['id']) . " ";
|
||||
|
||||
// Lock the ticket if customers are not allowed to reopen tickets
|
||||
if ($hesk_settings['custopen'] != 1) {
|
||||
@ -247,8 +263,8 @@ if ($ticket['locked']) {
|
||||
}
|
||||
} else {
|
||||
// Ticket isn't being closed, just add the history to the sql query (or tried to close but doesn't have permission)
|
||||
$revision = sprintf($hesklang['thist9'], hesk_date(), $hesklang[$newStatus['Key']], $_SESSION['name'] . ' (' . $_SESSION['user'] . ')');
|
||||
$sql_status = " , `history`=CONCAT(`history`,'" . hesk_dbEscape($revision) . "') ";
|
||||
$audit_status = array(0 => $_SESSION['name'] . ' (' . $_SESSION['user'] . ')',
|
||||
1 => mfh_getDisplayTextForStatusId($new_status));
|
||||
}
|
||||
}
|
||||
} // -> Submit as Customer reply
|
||||
@ -259,8 +275,8 @@ elseif ($submit_as_customer) {
|
||||
$new_status = $customerReplyStatus['ID'];
|
||||
|
||||
if ($ticket['status'] != $new_status) {
|
||||
$revision = sprintf($hesklang['thist9'], hesk_date(), $hesklang['wait_reply'], $_SESSION['name'] . ' (' . $_SESSION['user'] . ')');
|
||||
$sql_status = " , `history`=CONCAT(`history`,'" . hesk_dbEscape($revision) . "') ";
|
||||
$audit_customer_status = array(0 => $_SESSION['name'] . ' (' . $_SESSION['user'] . ')',
|
||||
1 => mfh_getDisplayTextForStatusId($new_status));
|
||||
}
|
||||
} // -> Default: submit as "Replied by staff"
|
||||
else {
|
||||
@ -278,12 +294,21 @@ $sql .= $submit_as_customer ? "`lastreplier`='0', `replierid`='0' " : "`lastrepl
|
||||
if ($time_worked == '00:00:00') {
|
||||
$sql .= ", `lastchange` = NOW() ";
|
||||
} else {
|
||||
$parts = explode(':', $ticket['time_worked']);
|
||||
$seconds = ($parts[0] * 3600) + ($parts[1] * 60) + $parts[2];
|
||||
|
||||
$parts = explode(':', $time_worked);
|
||||
$seconds += ($parts[0] * 3600) + ($parts[1] * 60) + $parts[2];
|
||||
|
||||
require(HESK_PATH . 'inc/reporting_functions.inc.php');
|
||||
$ticket['time_worked'] = hesk_SecondsToHHMMSS($seconds);
|
||||
|
||||
$sql .= ",`time_worked` = ADDTIME(`time_worked`,'" . hesk_dbEscape($time_worked) . "') ";
|
||||
}
|
||||
|
||||
if (!empty($_POST['assign_self']) && (hesk_checkPermission('can_assign_self', 0) || (isset($_REQUEST['isManager']) && $_REQUEST['isManager']))) {
|
||||
$revision = sprintf($hesklang['thist2'], hesk_date(), $_SESSION['name'] . ' (' . $_SESSION['user'] . ')', $_SESSION['name'] . ' (' . $_SESSION['user'] . ')');
|
||||
$sql .= " , `owner`=" . intval($_SESSION['id']) . ", `history`=CONCAT(`history`,'" . hesk_dbEscape($revision) . "') ";
|
||||
$audit_assigned_self = array(0 => $_SESSION['name'] . ' (' . $_SESSION['user'] . ')');
|
||||
$sql .= " , `owner`=" . intval($_SESSION['id']) . " ";
|
||||
}
|
||||
|
||||
$sql .= " $priority_sql ";
|
||||
@ -306,6 +331,29 @@ unset($sql);
|
||||
/* Update number of replies in the users table */
|
||||
hesk_dbQuery("UPDATE `" . hesk_dbEscape($hesk_settings['db_pfix']) . "users` SET `replies`=`replies`+1 WHERE `id`='" . intval($_SESSION['id']) . "'");
|
||||
|
||||
//-- Insert necessary audit trail records
|
||||
if ($audit_priority != null) {
|
||||
mfh_insert_audit_trail_record($replyto, 'TICKET', 'audit_priority', hesk_date(), $audit_priority);
|
||||
}
|
||||
|
||||
if ($audit_closed != null) {
|
||||
mfh_insert_audit_trail_record($replyto, 'TICKET', 'audit_closed', hesk_date(), $audit_closed);
|
||||
}
|
||||
|
||||
if ($audit_status != null) {
|
||||
mfh_insert_audit_trail_record($replyto, 'TICKET', 'audit_status', hesk_date(), $audit_status);
|
||||
}
|
||||
|
||||
if ($audit_customer_status != null) {
|
||||
mfh_insert_audit_trail_record($replyto, 'TICKET', 'audit_status', hesk_date(),
|
||||
$audit_customer_status);
|
||||
}
|
||||
|
||||
if ($audit_assigned_self != null) {
|
||||
mfh_insert_audit_trail_record($replyto, 'TICKET', 'audit_assigned_self', hesk_date(), $audit_assigned_self);
|
||||
}
|
||||
|
||||
|
||||
// --> Prepare reply message
|
||||
|
||||
// 1. Generate the array with ticket info that can be used in emails
|
||||
@ -324,7 +372,9 @@ $info = array(
|
||||
'dt' => hesk_date($ticket['dt'], true),
|
||||
'lastchange' => hesk_date($ticket['lastchange'], true),
|
||||
'id' => $ticket['id'],
|
||||
'language' => $ticket['language']
|
||||
'language' => $ticket['language'],
|
||||
'time_worked' => $ticket['time_worked'],
|
||||
'last_reply_by' => ($submit_as_customer ? $ticket['name'] : $_SESSION['name']),
|
||||
);
|
||||
|
||||
// 2. Add custom fields to the array
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -39,6 +39,8 @@ hesk_checkPermission('can_manage_settings');
|
||||
// A security check
|
||||
hesk_token_check('POST');
|
||||
|
||||
$modsForHesk_settings = mfh_getSettings();
|
||||
|
||||
// Demo mode
|
||||
if (defined('HESK_DEMO')) {
|
||||
hesk_process_messages($hesklang['sdemo'], 'admin_settings.php');
|
||||
@ -52,11 +54,15 @@ $set = array();
|
||||
$set['site_title'] = hesk_input(hesk_POST('s_site_title'), $hesklang['err_sname']);
|
||||
$set['site_title'] = str_replace('\\"', '"', $set['site_title']);
|
||||
$set['site_url'] = hesk_input(hesk_POST('s_site_url'), $hesklang['err_surl']);
|
||||
$set['hesk_title'] = hesk_input(hesk_POST('s_hesk_title'), $hesklang['err_htitle']);
|
||||
$set['hesk_title'] = str_replace('\\"', '"', $set['hesk_title']);
|
||||
$set['hesk_url'] = rtrim(hesk_input(hesk_POST('s_hesk_url'), $hesklang['err_hurl']), '/');
|
||||
$set['webmaster_mail'] = hesk_validateEmail(hesk_POST('s_webmaster_mail'), $hesklang['err_wmmail']);
|
||||
$set['noreply_mail'] = hesk_validateEmail(hesk_POST('s_noreply_mail'), $hesklang['err_nomail']);
|
||||
$set['noreply_name'] = hesk_input(hesk_POST('s_noreply_name'));
|
||||
$set['noreply_name'] = str_replace(array('\\"', '<', '>'), '', $set['noreply_name']);
|
||||
$set['noreply_name'] = trim(preg_replace('/\s{2,}/', ' ', $set['noreply_name']));
|
||||
$set['noreply_name'] = preg_replace("/\n|\r|\t|%0A|%0D|%08|%09/", '', $set['noreply_name']);
|
||||
|
||||
/* --> Language settings */
|
||||
$set['can_sel_lang'] = empty($_POST['s_can_sel_lang']) ? 0 : 1;
|
||||
@ -78,11 +84,6 @@ if (hesk_testMySQL()) {
|
||||
|
||||
/*** HELP DESK ***/
|
||||
|
||||
/* --> Helpdesk settings */
|
||||
$set['hesk_title'] = hesk_input(hesk_POST('s_hesk_title'), $hesklang['err_htitle']);
|
||||
$set['hesk_title'] = str_replace('\\"', '"', $set['hesk_title']);
|
||||
$set['hesk_url'] = rtrim(hesk_input(hesk_POST('s_hesk_url'), $hesklang['err_hurl']), '/');
|
||||
|
||||
// ---> check admin folder
|
||||
$set['admin_dir'] = isset($_POST['s_admin_dir']) && !is_array($_POST['s_admin_dir']) ? preg_replace('/[^a-zA-Z0-9_-]/', '', $_POST['s_admin_dir']) : 'admin';
|
||||
/*
|
||||
@ -140,7 +141,7 @@ $set['secimg_sum'] = '';
|
||||
for ($i = 1; $i <= 10; $i++) {
|
||||
$set['secimg_sum'] .= substr('AEUYBDGHJLMNPQRSTVWXZ123456789', rand(0, 29), 1);
|
||||
}
|
||||
$set['recaptcha_use'] = hesk_checkMinMax(intval(hesk_POST('s_recaptcha_use')), 0, 2, 0);
|
||||
$set['recaptcha_use'] = hesk_checkMinMax(intval(hesk_POST('s_recaptcha_use')), 0, 3, 0);
|
||||
$set['recaptcha_public_key'] = hesk_input(hesk_POST('s_recaptcha_public_key'));
|
||||
$set['recaptcha_private_key'] = hesk_input(hesk_POST('s_recaptcha_private_key'));
|
||||
$set['question_use'] = empty($_POST['s_question_use']) ? 0 : 1;
|
||||
@ -418,13 +419,14 @@ $set['updatedformat'] = hesk_checkMinMax(intval(hesk_POST('s_updatedformat')), 0
|
||||
/*** MISC ***/
|
||||
|
||||
/* --> Date & Time */
|
||||
$set['diff_hours'] = floatval(hesk_POST('s_diff_hours', 0));
|
||||
$set['diff_minutes'] = floatval(hesk_POST('s_diff_minutes', 0));
|
||||
$set['daylight'] = empty($_POST['s_daylight']) ? 0 : 1;
|
||||
$set['timezone'] = hesk_input(hesk_POST('s_timezone'));
|
||||
if (!in_array($set['timezone'], timezone_identifiers_list())) {
|
||||
$set['timezone'] = 'UTC';
|
||||
}
|
||||
$set['timeformat'] = hesk_input(hesk_POST('s_timeformat')) or $set['timeformat'] = 'Y-m-d H:i:s';
|
||||
|
||||
/* --> Other */
|
||||
$set['ip_whois'] = hesk_input(hesk_POST('s_ip_whois', 'http://whois.domaintools.com/{IP}'));
|
||||
$set['ip_whois'] = hesk_input(hesk_POST('s_ip_whois_url', 'http://whois.domaintools.com/{IP}'));
|
||||
|
||||
// If no {IP} tag append it to the end
|
||||
if (strlen($set['ip_whois']) == 0) {
|
||||
@ -449,7 +451,6 @@ foreach ($postArray as $value) {
|
||||
}
|
||||
|
||||
// Save the modsForHesk_settings.inc.php file
|
||||
$set['rtl'] = empty($_POST['rtl']) ? 0 : 1;
|
||||
$set['show-icons'] = empty($_POST['show-icons']) ? 0 : 1;
|
||||
$set['custom-field-setting'] = empty($_POST['custom-field-setting']) ? 0 : 1;
|
||||
$set['customer-email-verification-required'] = empty($_POST['email-verification']) ? 0 : 1;
|
||||
@ -458,6 +459,7 @@ $set['use_bootstrap_theme'] = empty($_POST['use_bootstrap_theme']) ? 0 : 1;
|
||||
$set['new_kb_article_visibility'] = hesk_checkMinMax(intval(hesk_POST('new_kb_article_visibility')), 0, 2, 2);
|
||||
$set['mfh_attachments'] = empty($_POST['email_attachments']) ? 0 : 1;
|
||||
$set['show_number_merged'] = empty($_POST['show_number_merged']) ? 0 : 1;
|
||||
$set['highlight_ticket_rows_based_on_priority'] = empty($_POST['highlight_ticket_rows_based_on_priority']) ? 0 : 1;
|
||||
$set['request_location'] = empty($_POST['request_location']) ? 0 : 1;
|
||||
$set['category_order_column'] = empty($_POST['category_order_column']) ? 'cat_order' : 'name';
|
||||
|
||||
@ -480,6 +482,7 @@ $set['navbar_title_url'] = hesk_POST('navbar_title_url');
|
||||
$set['enable_calendar'] = hesk_checkMinMax(intval(hesk_POST('enable_calendar')), 0, 2, 2);
|
||||
$set['first_day_of_week'] = hesk_POST('first-day-of-week', 0);
|
||||
$set['default_view'] = hesk_POST('default-view', 'month');
|
||||
$set['calendar_show_start_time'] = hesk_POST('calendar-show-start-time', 'true');
|
||||
|
||||
if ($set['customer-email-verification-required']) {
|
||||
//-- Don't allow multiple emails if verification is required
|
||||
@ -496,8 +499,125 @@ $set['dropdownItemTextColor'] = hesk_input(hesk_POST('dropdownItemTextColor'));
|
||||
$set['dropdownItemTextHoverColor'] = hesk_input(hesk_POST('dropdownItemTextHoverColor'));
|
||||
$set['questionMarkColor'] = hesk_input(hesk_POST('questionMarkColor'));
|
||||
$set['dropdownItemTextHoverBackgroundColor'] = hesk_input(hesk_POST('dropdownItemTextHoverBackgroundColor'));
|
||||
$set['admin_color_scheme'] = hesk_input(hesk_POST('admin-color-scheme'));
|
||||
mfh_updateSetting('rtl', $set['rtl']);
|
||||
|
||||
$set['bootswatch_theme'] = hesk_POST('bootswatch-theme');
|
||||
|
||||
$set['admin_navbar_background'] = hesk_input(hesk_POST('admin-navbar-background-color'));
|
||||
$set['admin_navbar_background_hover'] = hesk_input(hesk_POST('admin-navbar-background-hover-color'));
|
||||
$set['admin_navbar_brand_background'] = hesk_input(hesk_POST('admin-navbar-brand-background-color'));
|
||||
$set['admin_navbar_brand_background_hover'] = hesk_input(hesk_POST('admin-navbar-brand-background-hover-color'));
|
||||
$set['admin_navbar_brand_text'] = hesk_input(hesk_POST('admin-navbar-brand-text-color'));
|
||||
$set['admin_navbar_brand_text_hover'] = hesk_input(hesk_POST('admin-navbar-brand-text-hover-color'));
|
||||
$set['admin_navbar_text'] = hesk_input(hesk_POST('admin-navbar-text-color'));
|
||||
$set['admin_navbar_text_hover'] = hesk_input(hesk_POST('admin-navbar-text-hover-color'));
|
||||
$set['admin_sidebar_background'] = hesk_input(hesk_POST('admin-sidebar-background-color'));
|
||||
$set['admin_sidebar_background_hover'] = hesk_input(hesk_POST('admin-sidebar-header-background-color'));
|
||||
$set['admin_sidebar_font_weight'] = hesk_input(hesk_POST('admin-sidebar-font-weight'));
|
||||
$set['admin_sidebar_header_background'] = hesk_input(hesk_POST('admin-sidebar-header-background-color'));
|
||||
$set['admin_sidebar_header_text'] = hesk_input(hesk_POST('admin-sidebar-header-text-color'));
|
||||
$set['admin_sidebar_text'] = hesk_input(hesk_POST('admin-sidebar-text-color'));
|
||||
$set['admin_sidebar_text_hover'] = hesk_input(hesk_POST('admin-sidebar-text-hover-color'));
|
||||
|
||||
$set['login_background_type'] = hesk_input(hesk_POST('login-background'));
|
||||
$set['login_box_header'] = hesk_input(hesk_POST('login-box-header'));
|
||||
$set['business_hours_sunday'] = hesk_POST_array('business-hours-sunday');
|
||||
$set['business_hours_monday'] = hesk_POST_array('business-hours-monday');
|
||||
$set['business_hours_tuesday'] = hesk_POST_array('business-hours-tuesday');
|
||||
$set['business_hours_wednesday'] = hesk_POST_array('business-hours-wednesday');
|
||||
$set['business_hours_thursday'] = hesk_POST_array('business-hours-thursday');
|
||||
$set['business_hours_friday'] = hesk_POST_array('business-hours-friday');
|
||||
$set['business_hours_saturday'] = hesk_POST_array('business-hours-saturday');
|
||||
|
||||
$changedBackground = false;
|
||||
$loadedAttachmentFuncs = false;
|
||||
if ($set['login_background_type'] == 'color') {
|
||||
if (file_exists($hesk_settings['cache_dir'] . '/lb_' . $set['login_background'])) {
|
||||
unlink($hesk_settings['cache_dir'] . '/lb_' . $set['login_background']);
|
||||
}
|
||||
$set['login_background'] = hesk_input(hesk_POST('login-background-color'));
|
||||
if ($set['login_background'] == '') {
|
||||
$set['login_background'] = '#d2d6de';
|
||||
}
|
||||
|
||||
$changedBackground = true;
|
||||
} else {
|
||||
if (!$loadedAttachmentFuncs) {
|
||||
include(HESK_PATH . 'inc/attachments.inc.php');
|
||||
include(HESK_PATH . 'inc/posting_functions.inc.php');
|
||||
$loadedAttachmentFuncs = true;
|
||||
}
|
||||
|
||||
|
||||
$file_name = hesk_cleanFileName($_FILES['login-background-image']['name']);
|
||||
|
||||
|
||||
if (!empty($_FILES['login-background-image']['name'])) {
|
||||
$file_size = $_FILES['login-background-image']['size'];
|
||||
if ($file_size > $hesk_settings['attachments']['max_size']) {
|
||||
return hesk_fileError(sprintf($hesklang['file_too_large'], $file_name));
|
||||
}
|
||||
$ext = strtolower(strrchr($file_name, "."));
|
||||
|
||||
if (file_exists($hesk_settings['cache_dir'] . '/lb_' . $modsForHesk_settings['login_background'])) {
|
||||
unlink($hesk_settings['cache_dir'] . '/lb_' . $modsForHesk_settings['login_background']);
|
||||
}
|
||||
|
||||
$saved_name = 'login-background' . $ext;
|
||||
|
||||
$file_to_move = $_FILES['login-background-image']['tmp_name'];
|
||||
|
||||
|
||||
if (!move_uploaded_file($file_to_move, dirname(dirname(__FILE__)) . '/' . $hesk_settings['cache_dir'] . '/lb_' . $saved_name)) {
|
||||
hesk_error($hesklang['cannot_move_tmp']);
|
||||
}
|
||||
|
||||
$set['login_background'] = $saved_name;
|
||||
$changedBackground = true;
|
||||
}
|
||||
}
|
||||
$changedLoginImage = false;
|
||||
if ($set['login_box_header'] == 'image') {
|
||||
if (!$loadedAttachmentFuncs) {
|
||||
include(HESK_PATH . 'inc/attachments.inc.php');
|
||||
include(HESK_PATH . 'inc/posting_functions.inc.php');
|
||||
$loadedAttachmentFuncs = true;
|
||||
}
|
||||
|
||||
|
||||
$file_name = hesk_cleanFileName($_FILES['login-box-header-image']['name']);
|
||||
|
||||
if (!empty($_FILES['login-box-header-image']['name'])) {
|
||||
$file_size = $_FILES['login-box-header-image']['size'];
|
||||
if ($file_size > $hesk_settings['attachments']['max_size']) {
|
||||
return hesk_fileError(sprintf($hesklang['file_too_large'], $file_name));
|
||||
}
|
||||
$ext = strtolower(strrchr($file_name, "."));
|
||||
|
||||
if (file_exists($hesk_settings['cache_dir'] . '/lbh_' . $modsForHesk_settings['login_box_header_image'])) {
|
||||
unlink($hesk_settings['cache_dir'] . '/lbh_' . $modsForHesk_settings['login_box_header_image']);
|
||||
}
|
||||
|
||||
$saved_name = 'login-box-header-image' . $ext;
|
||||
|
||||
$file_to_move = $_FILES['login-box-header-image']['tmp_name'];
|
||||
|
||||
|
||||
if (!move_uploaded_file($file_to_move, dirname(dirname(__FILE__)) . '/' . $hesk_settings['cache_dir'] . '/lbh_' . $saved_name)) {
|
||||
hesk_error($hesklang['cannot_move_tmp']);
|
||||
}
|
||||
|
||||
$set['login_box_header_image'] = $saved_name;
|
||||
$changedLoginImage = true;
|
||||
}
|
||||
} else {
|
||||
if (file_exists($hesk_settings['cache_dir'] . '/lbh_' . $set['login_box_header_image'])) {
|
||||
unlink($hesk_settings['cache_dir'] . '/lbh_' . $set['login_box_header_image']);
|
||||
}
|
||||
|
||||
$set['login_box_header_image'] = '';
|
||||
$changedLoginImage = true;
|
||||
}
|
||||
|
||||
mfh_updateSetting('show_icons', $set['show-icons']);
|
||||
mfh_updateSetting('custom_field_setting', $set['custom-field-setting']);
|
||||
mfh_updateSetting('customer_email_verification_required', $set['customer-email-verification-required']);
|
||||
@ -506,6 +626,7 @@ mfh_updateSetting('use_bootstrap_theme', $set['use_bootstrap_theme']);
|
||||
mfh_updateSetting('new_kb_article_visibility', $set['new_kb_article_visibility']);
|
||||
mfh_updateSetting('attachments', $set['mfh_attachments']);
|
||||
mfh_updateSetting('show_number_merged', $set['show_number_merged']);
|
||||
mfh_updateSetting('highlight_ticket_rows_based_on_priority', $set['highlight_ticket_rows_based_on_priority']);
|
||||
mfh_updateSetting('request_location', $set['request_location']);
|
||||
mfh_updateSetting('category_order_column', $set['category_order_column'], true);
|
||||
mfh_updateSetting('rich_text_for_tickets', $set['rich_text_for_tickets']);
|
||||
@ -523,6 +644,21 @@ mfh_updateSetting('dropdownItemTextColor', $set['dropdownItemTextColor'], true);
|
||||
mfh_updateSetting('dropdownItemTextHoverColor', $set['dropdownItemTextHoverColor'], true);
|
||||
mfh_updateSetting('questionMarkColor', $set['questionMarkColor'], true);
|
||||
mfh_updateSetting('dropdownItemTextHoverBackgroundColor', $set['dropdownItemTextHoverBackgroundColor'], true);
|
||||
mfh_updateSetting('admin_navbar_background', $set['admin_navbar_background'], true);
|
||||
mfh_updateSetting('admin_navbar_background_hover', $set['admin_navbar_background_hover'], true);
|
||||
mfh_updateSetting('admin_navbar_brand_background', $set['admin_navbar_brand_background'], true);
|
||||
mfh_updateSetting('admin_navbar_brand_background_hover', $set['admin_navbar_brand_background_hover'], true);
|
||||
mfh_updateSetting('admin_navbar_brand_text', $set['admin_navbar_brand_text'], true);
|
||||
mfh_updateSetting('admin_navbar_brand_text_hover', $set['admin_navbar_brand_text_hover'], true);
|
||||
mfh_updateSetting('admin_navbar_text', $set['admin_navbar_text'], true);
|
||||
mfh_updateSetting('admin_navbar_text_hover', $set['admin_navbar_text_hover'], true);
|
||||
mfh_updateSetting('admin_sidebar_background', $set['admin_sidebar_background'], true);
|
||||
mfh_updateSetting('admin_sidebar_background_hover', $set['admin_sidebar_background_hover'], true);
|
||||
mfh_updateSetting('admin_sidebar_font_weight', $set['admin_sidebar_font_weight'], true);
|
||||
mfh_updateSetting('admin_sidebar_header_background', $set['admin_sidebar_header_background'], true);
|
||||
mfh_updateSetting('admin_sidebar_header_text', $set['admin_sidebar_header_text'], true);
|
||||
mfh_updateSetting('admin_sidebar_text', $set['admin_sidebar_text'], true);
|
||||
mfh_updateSetting('admin_sidebar_text_hover', $set['admin_sidebar_text_hover'], true);
|
||||
mfh_updateSetting('display_user_agent_information', $set['display_user_agent_information']);
|
||||
mfh_updateSetting('navbar_title_url', $set['navbar_title_url'], true);
|
||||
if ($set['use_mailgun'] == 1) {
|
||||
@ -533,8 +669,44 @@ mfh_updateSetting('use_mailgun', $set['use_mailgun'], false);
|
||||
mfh_updateSetting('enable_calendar', $set['enable_calendar'], false);
|
||||
mfh_updateSetting('first_day_of_week', $set['first_day_of_week'], false);
|
||||
mfh_updateSetting('default_calendar_view', $set['default_view'], true);
|
||||
mfh_updateSetting('calendar_show_start_time', $set['calendar_show_start_time'], true);
|
||||
mfh_updateSetting('admin_color_scheme', $set['admin_color_scheme'], true);
|
||||
|
||||
mfh_updateSetting('login_background_type', $set['login_background_type'], true);
|
||||
if ($changedBackground) {
|
||||
mfh_updateSetting('login_background', $set['login_background'], true);
|
||||
}
|
||||
|
||||
mfh_updateSetting('login_box_header', $set['login_box_header'], true);
|
||||
if ($changedLoginImage) {
|
||||
mfh_updateSetting('login_box_header_image', $set['login_box_header_image'], true);
|
||||
}
|
||||
|
||||
mfh_updateSetting('bootswatch_theme', $set['bootswatch_theme'], true);
|
||||
|
||||
// Update business hours
|
||||
hesk_dbQuery("UPDATE `" . hesk_dbEscape($hesk_settings['db_pfix']) . "mfh_calendar_business_hours`
|
||||
SET `start_time` = '" . hesk_dbEscape($set['business_hours_sunday'][0]) . "',
|
||||
`end_time` = '" . hesk_dbEscape($set['business_hours_sunday'][1]) . "' WHERE `day_of_week` = " . intval(0));
|
||||
hesk_dbQuery("UPDATE `" . hesk_dbEscape($hesk_settings['db_pfix']) . "mfh_calendar_business_hours`
|
||||
SET `start_time` = '" . hesk_dbEscape($set['business_hours_monday'][0]) . "',
|
||||
`end_time` = '" . hesk_dbEscape($set['business_hours_monday'][1]) . "' WHERE `day_of_week` = " . intval(1));
|
||||
hesk_dbQuery("UPDATE `" . hesk_dbEscape($hesk_settings['db_pfix']) . "mfh_calendar_business_hours`
|
||||
SET `start_time` = '" . hesk_dbEscape($set['business_hours_tuesday'][0]) . "',
|
||||
`end_time` = '" . hesk_dbEscape($set['business_hours_tuesday'][1]) . "' WHERE `day_of_week` = " . intval(2));
|
||||
hesk_dbQuery("UPDATE `" . hesk_dbEscape($hesk_settings['db_pfix']) . "mfh_calendar_business_hours`
|
||||
SET `start_time` = '" . hesk_dbEscape($set['business_hours_wednesday'][0]) . "',
|
||||
`end_time` = '" . hesk_dbEscape($set['business_hours_wednesday'][1]) . "' WHERE `day_of_week` = " . intval(3));
|
||||
hesk_dbQuery("UPDATE `" . hesk_dbEscape($hesk_settings['db_pfix']) . "mfh_calendar_business_hours`
|
||||
SET `start_time` = '" . hesk_dbEscape($set['business_hours_thursday'][0]) . "',
|
||||
`end_time` = '" . hesk_dbEscape($set['business_hours_thursday'][1]) . "' WHERE `day_of_week` = " . intval(4));
|
||||
hesk_dbQuery("UPDATE `" . hesk_dbEscape($hesk_settings['db_pfix']) . "mfh_calendar_business_hours`
|
||||
SET `start_time` = '" . hesk_dbEscape($set['business_hours_friday'][0]) . "',
|
||||
`end_time` = '" . hesk_dbEscape($set['business_hours_friday'][1]) . "' WHERE `day_of_week` = " . intval(5));
|
||||
hesk_dbQuery("UPDATE `" . hesk_dbEscape($hesk_settings['db_pfix']) . "mfh_calendar_business_hours`
|
||||
SET `start_time` = '" . hesk_dbEscape($set['business_hours_saturday'][0]) . "',
|
||||
`end_time` = '" . hesk_dbEscape($set['business_hours_saturday'][1]) . "' WHERE `day_of_week` = " . intval(6));
|
||||
|
||||
// Prepare settings file and save it
|
||||
$settings_file_content = '<?php
|
||||
// Settings file for HESK ' . $set['hesk_version'] . '
|
||||
@ -544,6 +716,8 @@ $settings_file_content = '<?php
|
||||
// --> General settings
|
||||
$hesk_settings[\'site_title\']=\'' . $set['site_title'] . '\';
|
||||
$hesk_settings[\'site_url\']=\'' . $set['site_url'] . '\';
|
||||
$hesk_settings[\'hesk_title\']=\'' . $set['hesk_title'] . '\';
|
||||
$hesk_settings[\'hesk_url\']=\'' . $set['hesk_url'] . '\';
|
||||
$hesk_settings[\'webmaster_mail\']=\'' . $set['webmaster_mail'] . '\';
|
||||
$hesk_settings[\'noreply_mail\']=\'' . $set['noreply_mail'] . '\';
|
||||
$hesk_settings[\'noreply_name\']=\'' . $set['noreply_name'] . '\';
|
||||
@ -566,8 +740,6 @@ $hesk_settings[\'db_vrsn\']=' . $set['db_vrsn'] . ';
|
||||
// ==> HELP DESK
|
||||
|
||||
// --> Help desk settings
|
||||
$hesk_settings[\'hesk_title\']=\'' . $set['hesk_title'] . '\';
|
||||
$hesk_settings[\'hesk_url\']=\'' . $set['hesk_url'] . '\';
|
||||
$hesk_settings[\'admin_dir\']=\'' . $set['admin_dir'] . '\';
|
||||
$hesk_settings[\'attach_dir\']=\'' . $set['attach_dir'] . '\';
|
||||
$hesk_settings[\'cache_dir\']=\'' . $set['cache_dir'] . '\';
|
||||
@ -708,16 +880,14 @@ $hesk_settings[\'open_only\']=' . $set['open_only'] . ';
|
||||
$hesk_settings[\'ticket_list\']=array(' . $set['ticket_list'] . ');
|
||||
|
||||
// --> Other
|
||||
$hesk_settings[\'submittedformat\']=\'' . $set['submittedformat'] . '\';
|
||||
$hesk_settings[\'updatedformat\']=\'' . $set['updatedformat'] . '\';
|
||||
$hesk_settings[\'submittedformat\']=' . $set['submittedformat'] . ';
|
||||
$hesk_settings[\'updatedformat\']=' . $set['updatedformat'] . ';
|
||||
|
||||
|
||||
// ==> MISC
|
||||
|
||||
// --> Date & Time
|
||||
$hesk_settings[\'diff_hours\']=' . $set['diff_hours'] . ';
|
||||
$hesk_settings[\'diff_minutes\']=' . $set['diff_minutes'] . ';
|
||||
$hesk_settings[\'daylight\']=' . $set['daylight'] . ';
|
||||
$hesk_settings[\'timezone\']=\'' . $set['timezone'] . '\';
|
||||
$hesk_settings[\'timeformat\']=\'' . $set['timeformat'] . '\';
|
||||
|
||||
// --> Other
|
||||
@ -760,6 +930,12 @@ if (!$pop3_OK) {
|
||||
$tmp[] = '<span style="color:red; font-weight:bold">' . $hesklang['pop3e'] . ':</span> ' . $pop3_error . '<br /><br /><a href="Javascript:void(0)" onclick="Javascript:hesk_toggleLayerDisplay(\'pop3log\')">' . $hesklang['pop3log'] . '</a><div id="pop3log" style="display:none"> <br /><textarea name="log" rows="10" cols="60">' . $pop3_log . '</textarea></div>';
|
||||
}
|
||||
|
||||
// Clear the cache folder
|
||||
hesk_purge_cache('kb');
|
||||
hesk_purge_cache('cf');
|
||||
hesk_purge_cache('export', 14400);
|
||||
hesk_purge_cache('status');
|
||||
|
||||
// Show the settings page and display any notices or success
|
||||
if (count($tmp)) {
|
||||
$errors = implode('<br /><br />', $tmp);
|
||||
|
@ -123,9 +123,9 @@ foreach ($hesk_settings['custom_fields'] as $k=>$v) {
|
||||
$tmpvar[$k] = hesk_POST($k);
|
||||
$_SESSION["as_$k"] = '';
|
||||
if (preg_match("/^[0-9]{4}-(0[1-9]|1[0-2])-(0[1-9]|[1-2][0-9]|3[0-1])$/", $tmpvar[$k])) {
|
||||
$date = strtotime($tmpvar[$k] . ' t00:00:00');
|
||||
$dmin = strlen($v['value']['dmin']) ? strtotime($v['value']['dmin'] . ' t00:00:00') : false;
|
||||
$dmax = strlen($v['value']['dmax']) ? strtotime($v['value']['dmax'] . ' t00:00:00') : false;
|
||||
$date = strtotime($tmpvar[$k] . ' t00:00:00 UTC');
|
||||
$dmin = strlen($v['value']['dmin']) ? strtotime($v['value']['dmin'] . ' t00:00:00 UTC') : false;
|
||||
$dmax = strlen($v['value']['dmax']) ? strtotime($v['value']['dmax'] . ' t00:00:00 UTC') : false;
|
||||
|
||||
$_SESSION["as_$k"] = $tmpvar[$k];
|
||||
|
||||
@ -176,11 +176,11 @@ foreach ($hesk_settings['custom_fields'] as $k=>$v) {
|
||||
$tmpvar['trackid'] = hesk_createID();
|
||||
|
||||
// Log who submitted ticket
|
||||
$tmpvar['history'] = sprintf($hesklang['thist7'], hesk_date(), $_SESSION['name'] . ' (' . $_SESSION['user'] . ')');
|
||||
$tmpvar['openedby'] = $_SESSION['id'];
|
||||
|
||||
// Owner
|
||||
$tmpvar['owner'] = 0;
|
||||
$autoassign_owner = null;
|
||||
if (hesk_checkPermission('can_assign_others', 0)) {
|
||||
$tmpvar['owner'] = intval(hesk_POST('owner'));
|
||||
|
||||
@ -192,7 +192,6 @@ if (hesk_checkPermission('can_assign_others', 0)) {
|
||||
$autoassign_owner = hesk_autoAssignTicket($tmpvar['category']);
|
||||
if ($autoassign_owner) {
|
||||
$tmpvar['owner'] = intval($autoassign_owner['id']);
|
||||
$tmpvar['history'] .= sprintf($hesklang['thist10'], hesk_date(), $autoassign_owner['name'] . ' (' . $autoassign_owner['user'] . ')');
|
||||
} else {
|
||||
$tmpvar['owner'] = 0;
|
||||
}
|
||||
@ -301,6 +300,11 @@ if (!$modsForHesk_settings['rich_text_for_tickets']) {
|
||||
$tmpvar['message'] = nl2br($tmpvar['message']);
|
||||
}
|
||||
|
||||
// Track who assigned the ticket
|
||||
if ($tmpvar['owner'] > 0) {
|
||||
$tmpvar['assignedby'] = !empty($autoassign_owner) ? -1 : $_SESSION['id'];
|
||||
}
|
||||
|
||||
$tmpvar['latitude'] = hesk_POST('latitude', 'E-4');
|
||||
$tmpvar['longitude'] = hesk_POST('longitude', 'E-4');
|
||||
|
||||
@ -315,6 +319,14 @@ $tmpvar['screen_resolution_width'] = "NULL";
|
||||
// Insert ticket to database
|
||||
$ticket = hesk_newTicket($tmpvar);
|
||||
|
||||
mfh_insert_audit_trail_record($ticket['id'], 'TICKET', 'audit_created', hesk_date(),
|
||||
array(0 => $_SESSION['name'] . ' (' . $_SESSION['user'] . ')'));
|
||||
|
||||
if ($autoassign_owner) {
|
||||
mfh_insert_audit_trail_record($ticket['id'], 'TICKET', 'audit_autoassigned', hesk_date(),
|
||||
array(0 => $autoassign_owner['name'] . ' (' . $autoassign_owner['user'] . ')'));
|
||||
}
|
||||
|
||||
// Notify the customer about the ticket?
|
||||
if ($notify && $email_available) {
|
||||
hesk_notifyCustomer($modsForHesk_settings);
|
||||
|
File diff suppressed because it is too large
Load Diff
43
admin/anonymize_ticket.php
Normal file
43
admin/anonymize_ticket.php
Normal file
@ -0,0 +1,43 @@
|
||||
<?php
|
||||
/**
|
||||
*
|
||||
* This file is part of HESK - PHP Help Desk Software.
|
||||
*
|
||||
* (c) Copyright Klemen Stirn. All rights reserved.
|
||||
* https://www.hesk.com
|
||||
*
|
||||
* For the full copyright and license agreement information visit
|
||||
* https://www.hesk.com/eula.php
|
||||
*
|
||||
*/
|
||||
|
||||
define('IN_SCRIPT',1);
|
||||
define('HESK_PATH','../');
|
||||
|
||||
/* Get all the required files and functions */
|
||||
require(HESK_PATH . 'hesk_settings.inc.php');
|
||||
require(HESK_PATH . 'inc/common.inc.php');
|
||||
require(HESK_PATH . 'inc/admin_functions.inc.php');
|
||||
require(HESK_PATH . 'inc/privacy_functions.inc.php');
|
||||
hesk_load_database_functions();
|
||||
|
||||
hesk_session_start();
|
||||
hesk_dbConnect();
|
||||
hesk_isLoggedIn();
|
||||
|
||||
// Check permissions for this feature
|
||||
hesk_checkPermission('can_privacy');
|
||||
|
||||
// A security check
|
||||
hesk_token_check();
|
||||
|
||||
// Tracking ID
|
||||
$trackingID = hesk_cleanID() or die($hesklang['int_error'].': '.$hesklang['no_trackID']);
|
||||
|
||||
// Anonymize the ticket and redirect back
|
||||
if (hesk_anonymizeTicket(0, $trackingID))
|
||||
{
|
||||
hesk_process_messages($hesklang['success_anon'],'admin_ticket.php?track='.$trackingID.'&Refresh='.mt_rand(10000,99999),'SUCCESS');
|
||||
}
|
||||
|
||||
hesk_error($hesklang['no_permission']);
|
@ -1,37 +1,9 @@
|
||||
<?php
|
||||
/*******************************************************************************
|
||||
* Title: Help Desk Software HESK
|
||||
* Version: 2.6.5 from 28th August 2015
|
||||
* Author: Klemen Stirn
|
||||
* Website: https://www.hesk.com
|
||||
********************************************************************************
|
||||
* COPYRIGHT AND TRADEMARK NOTICE
|
||||
* Copyright 2005-2015 Klemen Stirn. All Rights Reserved.
|
||||
* HESK is a registered trademark of Klemen Stirn.
|
||||
* The HESK may be used and modified free of charge by anyone
|
||||
* AS LONG AS COPYRIGHT NOTICES AND ALL THE COMMENTS REMAIN INTACT.
|
||||
* By using this code you agree to indemnify Klemen Stirn from any
|
||||
* liability that might arise from it's use.
|
||||
* Selling the code for this program, in part or full, without prior
|
||||
* written consent is expressly forbidden.
|
||||
* Using this code, in part or full, to create derivate work,
|
||||
* new scripts or products is expressly forbidden. Obtain permission
|
||||
* before redistributing this software over the Internet or in
|
||||
* any other medium. In all cases copyright and header must remain intact.
|
||||
* This Copyright is in full effect in any country that has International
|
||||
* Trade Agreements with the United States of America or
|
||||
* with the European Union.
|
||||
* Removing any of the copyright notices without purchasing a license
|
||||
* is expressly forbidden. To remove HESK copyright notice you must purchase
|
||||
* a license for this script. For more information on how to obtain
|
||||
* a license please visit the page below:
|
||||
* https://www.hesk.com/buy.php
|
||||
*******************************************************************************/
|
||||
|
||||
define('IN_SCRIPT', 1);
|
||||
define('HESK_PATH', '../');
|
||||
define('PAGE_TITLE', 'ADMIN_SETTINGS');
|
||||
define('MFH_PAGE_LAYOUT', 'TOP_AND_SIDE');
|
||||
define('PAGE_TITLE', 'ADMIN_API_SETTINGS');
|
||||
define('MFH_PAGE_LAYOUT', 'TOP_ONLY');
|
||||
|
||||
// Make sure the install folder is deleted
|
||||
if (is_dir(HESK_PATH . 'install')) {
|
||||
@ -120,7 +92,7 @@ require_once(HESK_PATH . 'inc/show_admin_nav.inc.php');
|
||||
<ul class="nav nav-tabs">
|
||||
<li class="active"><a href="#general" data-toggle="tab"><?php echo $hesklang['tab_1']; ?></a></li>
|
||||
<li><a href="#user-security" data-toggle="tab"><?php echo $hesklang['user_security']; ?></a></li>
|
||||
<li><a href="#" target="_blank"><?php echo $hesklang['api_documentation']; ?> <i class="fa fa-external-link"></i></a></li>
|
||||
<li><a href="https://mods-for-hesk.readme.io/reference" target="_blank"><?php echo $hesklang['api_documentation']; ?> <i class="fa fa-external-link"></i></a></li>
|
||||
</ul>
|
||||
<div class="tab-content summaryList tabPadding">
|
||||
<div class="tab-pane fade in active" id="general">
|
||||
@ -147,13 +119,29 @@ require_once(HESK_PATH . 'inc/show_admin_nav.inc.php');
|
||||
<?php echo $hesklang['disable']; ?>
|
||||
</label>
|
||||
</span>
|
||||
<span>
|
||||
<i id="public-api-success" class="fa fa-check-circle fa-2x green hide media-middle"
|
||||
data-toggle="tooltip" title="<?php echo $hesklang['changes_saved']; ?>"></i>
|
||||
<i id="public-api-failure" class="fa fa-times-circle fa-2x red hide media-middle"
|
||||
data-toggle="tooltip" title="<?php echo $hesklang['save_failed_check_logs']; ?>"></i>
|
||||
<i id="public-api-saving" class="fa fa-spin fa-spinner fa-2x hide media-middle"
|
||||
data-toggle="tooltip" title="<?php echo $hesklang['saving']; ?>"></i>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="url-rewrite" class="col-sm-3 control-label">
|
||||
<?php echo $hesklang['url_rewrite']; ?>
|
||||
<i class="fa fa-question-circle settingsquestionmark" data-toggle="popover"
|
||||
title="<?php echo $hesklang['url_rewrite']; ?>"
|
||||
data-content="<?php echo $hesklang['url_rewrite_help']; ?>"></i>
|
||||
</label>
|
||||
<div class="col-sm-9">
|
||||
<span class="btn-group" data-toggle="buttons">
|
||||
<?php
|
||||
$on = $modsForHesk_settings['api_url_rewrite'] == '1' ? 'active' : '';
|
||||
$off = $modsForHesk_settings['api_url_rewrite'] == '1' ? '' : 'active';
|
||||
?>
|
||||
<label id="enable-url-rewrite-button" class="btn btn-success <?php echo $on; ?>">
|
||||
<input type="radio" name="url-rewrite" value="1"> <i class="fa fa-check-circle"></i>
|
||||
<?php echo $hesklang['enable']; ?>
|
||||
</label>
|
||||
<label id="disable-url-rewrite-button" class="btn btn-danger <?php echo $off; ?>">
|
||||
<input type="radio" name="url-rewrite" value="0"> <i class="fa fa-times-circle"></i>
|
||||
<?php echo $hesklang['disable']; ?>
|
||||
</label>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
@ -232,7 +220,8 @@ require_once(HESK_PATH . 'inc/show_admin_nav.inc.php');
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
|
||||
<?php
|
||||
echo mfh_get_hidden_fields_for_language(array('success', 'url_rewrite_saved', 'api_settings_saved', 'an_error_occurred'));
|
||||
|
||||
require_once(HESK_PATH . 'inc/footer.inc.php');
|
||||
exit();
|
@ -1,32 +1,15 @@
|
||||
<?php
|
||||
/*******************************************************************************
|
||||
* Title: Help Desk Software HESK
|
||||
* Version: 2.6.1 from 26th February 2015
|
||||
* Author: Klemen Stirn
|
||||
* Website: https://www.hesk.com
|
||||
********************************************************************************
|
||||
* COPYRIGHT AND TRADEMARK NOTICE
|
||||
* Copyright 2005-2015 Klemen Stirn. All Rights Reserved.
|
||||
* HESK is a registered trademark of Klemen Stirn.
|
||||
* The HESK may be used and modified free of charge by anyone
|
||||
* AS LONG AS COPYRIGHT NOTICES AND ALL THE COMMENTS REMAIN INTACT.
|
||||
* By using this code you agree to indemnify Klemen Stirn from any
|
||||
* liability that might arise from it's use.
|
||||
* Selling the code for this program, in part or full, without prior
|
||||
* written consent is expressly forbidden.
|
||||
* Using this code, in part or full, to create derivate work,
|
||||
* new scripts or products is expressly forbidden. Obtain permission
|
||||
* before redistributing this software over the Internet or in
|
||||
* any other medium. In all cases copyright and header must remain intact.
|
||||
* This Copyright is in full effect in any country that has International
|
||||
* Trade Agreements with the United States of America or
|
||||
* with the European Union.
|
||||
* Removing any of the copyright notices without purchasing a license
|
||||
* is expressly forbidden. To remove HESK copyright notice you must purchase
|
||||
* a license for this script. For more information on how to obtain
|
||||
* a license please visit the page below:
|
||||
* https://www.hesk.com/buy.php
|
||||
*******************************************************************************/
|
||||
/**
|
||||
*
|
||||
* This file is part of HESK - PHP Help Desk Software.
|
||||
*
|
||||
* (c) Copyright Klemen Stirn. All rights reserved.
|
||||
* https://www.hesk.com
|
||||
*
|
||||
* For the full copyright and license agreement information visit
|
||||
* https://www.hesk.com/eula.php
|
||||
*
|
||||
*/
|
||||
|
||||
define('IN_SCRIPT', 1);
|
||||
define('HESK_PATH', '../');
|
||||
@ -69,8 +52,9 @@ $owner = intval(hesk_REQUEST('owner'));
|
||||
|
||||
/* If ID is -1 the ticket will be unassigned */
|
||||
if ($owner == -1) {
|
||||
$revision = sprintf($hesklang['thist2'], hesk_date(), '<i>' . $hesklang['unas'] . '</i>', $_SESSION['name'] . ' (' . $_SESSION['user'] . ')');
|
||||
$res = hesk_dbQuery("UPDATE `" . hesk_dbEscape($hesk_settings['db_pfix']) . "tickets` SET `owner`=0 , `history`=CONCAT(`history`,'" . hesk_dbEscape($revision) . "') WHERE `trackid`='" . hesk_dbEscape($trackingID) . "'");
|
||||
$res = hesk_dbQuery("UPDATE `" . hesk_dbEscape($hesk_settings['db_pfix']) . "tickets` SET `owner`=0, `assignedby`=NULL WHERE `trackid`='" . hesk_dbEscape($trackingID) . "'");
|
||||
mfh_insert_audit_trail_record($ticket['id'], 'TICKET', 'audit_unassigned', hesk_date(),
|
||||
array(0 => $_SESSION['name'] . ' (' . $_SESSION['user'] . ')'));
|
||||
|
||||
hesk_process_messages($hesklang['tunasi2'], $_SERVER['PHP_SELF'], 'SUCCESS');
|
||||
} elseif ($owner < 1) {
|
||||
@ -92,8 +76,9 @@ if (!$row['isadmin']) {
|
||||
// Make sure two people don't assign a ticket to a different user at the same time
|
||||
if ($ticket['owner'] && $ticket['owner'] != $owner && hesk_REQUEST('unassigned') && hesk_GET('confirm') != 'Y') {
|
||||
$new_owner = ($owner == $_SESSION['id']) ? $hesklang['scoy'] : sprintf($hesklang['scot'], $row['name']);
|
||||
$originalOwner = intval($ticket['owner']);
|
||||
|
||||
$res = hesk_dbQuery("SELECT `name` FROM `".hesk_dbEscape($hesk_settings['db_pfix'])."users` WHERE `id`='{$ticket['owner']}' LIMIT 1");
|
||||
$res = hesk_dbQuery("SELECT `name` FROM `".hesk_dbEscape($hesk_settings['db_pfix'])."users` WHERE `id`='{$originalOwner}' LIMIT 1");
|
||||
|
||||
if (hesk_dbNumRows($res) == 1) {
|
||||
$row = hesk_dbFetchAssoc($res);
|
||||
@ -112,8 +97,25 @@ if ($ticket['owner'] && $ticket['owner'] != $owner && hesk_REQUEST('unassigned')
|
||||
|
||||
/* Assigning to self? */
|
||||
if ($can_assign_others || ($owner == $_SESSION['id'] && $can_assign_self)) {
|
||||
$revision = sprintf($hesklang['thist2'], hesk_date(), $row['name'] . ' (' . $row['user'] . ')', $_SESSION['name'] . ' (' . $_SESSION['user'] . ')');
|
||||
$res = hesk_dbQuery("UPDATE `" . hesk_dbEscape($hesk_settings['db_pfix']) . "tickets` SET `owner`={$owner} , `history`=CONCAT(`history`,'" . hesk_dbEscape($revision) . "') WHERE `trackid`='" . hesk_dbEscape($trackingID) . "'");
|
||||
$assignedby = intval(hesk_SESSION('id'));
|
||||
if ($assignedby > 0) {
|
||||
$assignedby = ',`assignedby`=' . $assignedby;
|
||||
} else {
|
||||
$assignedby = '';
|
||||
}
|
||||
|
||||
|
||||
$res = hesk_dbQuery("UPDATE `" . hesk_dbEscape($hesk_settings['db_pfix']) . "tickets` SET `owner`={$owner} {$assignedby} WHERE `trackid`='" . hesk_dbEscape($trackingID) . "'");
|
||||
|
||||
if ($owner == $_SESSION['id'] && $can_assign_self) {
|
||||
mfh_insert_audit_trail_record($ticket['id'], 'TICKET', 'audit_assigned_self', hesk_date(),
|
||||
array(0 => $_SESSION['name'] . ' (' . $_SESSION['user'] . ')'));
|
||||
} else {
|
||||
// current user -> assigned user
|
||||
mfh_insert_audit_trail_record($ticket['id'], 'TICKET', 'audit_assigned', hesk_date(),
|
||||
array(0 => $_SESSION['name'] . ' (' . $_SESSION['user'] . ')',
|
||||
1 => $row['name'] . ' (' . $row['user'] . ')'));
|
||||
}
|
||||
|
||||
if ($owner != $_SESSION['id'] && !hesk_checkPermission('can_view_ass_others', 0)) {
|
||||
$_SERVER['PHP_SELF'] = 'admin_main.php';
|
||||
@ -135,13 +137,14 @@ $info = array(
|
||||
'trackid' => $ticket['trackid'],
|
||||
'status' => $ticket['status'],
|
||||
'name' => $ticket['name'],
|
||||
'lastreplier' => $ticket['lastreplier'],
|
||||
'subject' => $ticket['subject'],
|
||||
'message' => $ticket['message'],
|
||||
'attachments' => $ticket['attachments'],
|
||||
'dt' => hesk_date($ticket['dt'], true),
|
||||
'lastchange' => hesk_date($ticket['lastchange'], true),
|
||||
'id' => $ticket['id'],
|
||||
'time_worked' => $ticket['time_worked'],
|
||||
'last_reply_by' => hesk_getReplierName($ticket),
|
||||
);
|
||||
|
||||
// 2. Add custom fields to the array
|
||||
|
@ -200,7 +200,7 @@ require_once(HESK_PATH . 'inc/show_admin_nav.inc.php');
|
||||
if ($can_unban) {
|
||||
echo '
|
||||
<td class="' . $color . ' text-left">
|
||||
<a href="banned_emails.php?a=unban&id=' . $ban['id'] . '&token=' . hesk_token_echo(0) . '" onclick="return confirm_delete();">
|
||||
<a name="Unban '.$ban['email'].'" href="banned_emails.php?a=unban&id=' . $ban['id'] . '&token=' . hesk_token_echo(0) . '" onclick="return confirm_delete();">
|
||||
<i class="fa fa-times red font-size-16p" data-toggle="tooltip" data-placement="top" data-original-title="' . $hesklang['delban'] . '"></i>
|
||||
</a>
|
||||
</td>
|
||||
@ -239,7 +239,7 @@ function ban_email()
|
||||
hesk_token_check();
|
||||
|
||||
// Get the email
|
||||
$email = strtolower(hesk_input(hesk_REQUEST('email')));
|
||||
$email = hesk_emailCleanup(strtolower(hesk_input(hesk_REQUEST('email'))));
|
||||
|
||||
// Nothing entered?
|
||||
if (!strlen($email)) {
|
||||
|
@ -263,7 +263,7 @@ require_once(HESK_PATH . 'inc/show_admin_nav.inc.php');
|
||||
if ($can_unban) {
|
||||
echo '
|
||||
<td class="' . $color . ' text-left">
|
||||
<a href="banned_ips.php?a=unban&id=' . $ban['id'] . '&token=' . hesk_token_echo(0) . '" onclick="return confirm_delete();">
|
||||
<a name="Unban '.$ban['ip_display'].'" href="banned_ips.php?a=unban&id=' . $ban['id'] . '&token=' . hesk_token_echo(0) . '" onclick="return confirm_delete();">
|
||||
<i class="fa fa-times red font-size-16p" data-toggle="tooltip" data-placement="top" data-original-title="' . $hesklang['delban'] . '"></i></a>
|
||||
</td>
|
||||
';
|
||||
|
@ -1,32 +1,4 @@
|
||||
<?php
|
||||
/*******************************************************************************
|
||||
* Title: Help Desk Software HESK
|
||||
* Version: 2.6.5 from 28th August 2015
|
||||
* Author: Klemen Stirn
|
||||
* Website: https://www.hesk.com
|
||||
********************************************************************************
|
||||
* COPYRIGHT AND TRADEMARK NOTICE
|
||||
* Copyright 2005-2015 Klemen Stirn. All Rights Reserved.
|
||||
* HESK is a registered trademark of Klemen Stirn.
|
||||
* The HESK may be used and modified free of charge by anyone
|
||||
* AS LONG AS COPYRIGHT NOTICES AND ALL THE COMMENTS REMAIN INTACT.
|
||||
* By using this code you agree to indemnify Klemen Stirn from any
|
||||
* liability that might arise from it's use.
|
||||
* Selling the code for this program, in part or full, without prior
|
||||
* written consent is expressly forbidden.
|
||||
* Using this code, in part or full, to create derivate work,
|
||||
* new scripts or products is expressly forbidden. Obtain permission
|
||||
* before redistributing this software over the Internet or in
|
||||
* any other medium. In all cases copyright and header must remain intact.
|
||||
* This Copyright is in full effect in any country that has International
|
||||
* Trade Agreements with the United States of America or
|
||||
* with the European Union.
|
||||
* Removing any of the copyright notices without purchasing a license
|
||||
* is expressly forbidden. To remove HESK copyright notice you must purchase
|
||||
* a license for this script. For more information on how to obtain
|
||||
* a license please visit the page below:
|
||||
* https://www.hesk.com/buy.php
|
||||
*******************************************************************************/
|
||||
|
||||
define('IN_SCRIPT', 1);
|
||||
define('VALIDATOR', 1);
|
||||
@ -61,14 +33,26 @@ if ($modsForHesk_settings['enable_calendar'] == '0') {
|
||||
|
||||
// Get categories for the dropdown
|
||||
$order_by = $modsForHesk_settings['category_order_column'];
|
||||
$rs = hesk_dbQuery("SELECT `id`, `name`, `color` FROM `" . hesk_dbEscape($hesk_settings['db_pfix']) . "categories` WHERE `usage` <> 1 ORDER BY `" . hesk_dbEscape($order_by) . "`");
|
||||
$rs = hesk_dbQuery("SELECT `id`, `name`, `background_color`, `foreground_color`, `display_border_outline`
|
||||
FROM `" . hesk_dbEscape($hesk_settings['db_pfix']) . "categories`
|
||||
WHERE `usage` <> 1 ORDER BY `" . hesk_dbEscape($order_by) . "`");
|
||||
$categories = array();
|
||||
while ($row = hesk_dbFetchAssoc($rs)) {
|
||||
if (!$_SESSION['isadmin'] && !in_array($row['id'], $_SESSION['categories'])) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$row['css_style'] = $row['color'] == null ? 'color: black; border: solid 1px #000;' : 'border: solid 1px ' . $row['color'] . '; background: ' . $row['color'];
|
||||
$row['css_style'] = "background: {$row['background_color']};";
|
||||
$row['background_volatile'] = 'background-volatile';
|
||||
if ($row['foreground_color'] != 'AUTO') {
|
||||
$row['background_volatile'] = '';
|
||||
$row['css_style'] .= " color: {$row['foreground_color']};";
|
||||
|
||||
if ($row['display_border_outline'] == '1') {
|
||||
$row['css_style'] .= " border: solid 1px {$row['foreground_color']};";
|
||||
}
|
||||
}
|
||||
|
||||
$categories[] = $row;
|
||||
}
|
||||
|
||||
@ -83,10 +67,9 @@ require_once(HESK_PATH . 'inc/show_admin_nav.inc.php');
|
||||
<ul class="sidebar-menu">
|
||||
<li class="header text-uppercase"><?php echo $hesklang['calendar_categories']; ?></li>
|
||||
<?php foreach ($categories as $category): ?>
|
||||
<!-- TODO Clean this up -->
|
||||
<li>
|
||||
<div class="ticket-info">
|
||||
<div class="hide-on-overflow no-wrap event-category background-volatile"
|
||||
<div class="hide-on-overflow no-wrap event-category <?php echo $category['background_volatile']; ?>"
|
||||
data-select-toggle="category-toggle" data-name="category-toggle" data-category-value="<?php echo $category['id']; ?>"
|
||||
data-checked="1"
|
||||
data-toggle="tooltip"
|
||||
@ -152,6 +135,16 @@ require_once(HESK_PATH . 'inc/show_admin_nav.inc.php');
|
||||
</div>
|
||||
</div>
|
||||
<div class="box-body no-padding">
|
||||
<?php if (hesk_checkPermission('can_man_calendar', 0)): ?>
|
||||
<div class="row" style="padding-right: 10px">
|
||||
<div class="col-xs-12 text-right">
|
||||
<button class="btn btn-success" id="create-event-button">
|
||||
<i class="fa fa-plus-circle"></i>
|
||||
<?php echo $hesklang['new_event']; ?>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
<div id="calendar"></div>
|
||||
</div>
|
||||
</div>
|
||||
@ -214,7 +207,9 @@ require_once(HESK_PATH . 'inc/show_admin_nav.inc.php');
|
||||
echo '<option value="">'.$hesklang['select'].'</option>';
|
||||
}
|
||||
foreach ($categories as $category): ?>
|
||||
<option value="<?php echo $category['id']; ?>" data-color="<?php echo htmlspecialchars($category['color']); ?>">
|
||||
<option value="<?php echo $category['id']; ?>" data-background-color="<?php echo htmlspecialchars($category['background_color']); ?>"
|
||||
data-foreground-color="<?php echo htmlspecialchars($category['foreground_color']); ?>"
|
||||
data-display-border="<?php echo htmlspecialchars($category['display_border_outline']); ?>">
|
||||
<?php echo $category['name']; ?>
|
||||
</option>
|
||||
<?php endforeach; ?>
|
||||
@ -287,10 +282,10 @@ require_once(HESK_PATH . 'inc/show_admin_nav.inc.php');
|
||||
</div>
|
||||
<div class="col-sm-4">
|
||||
<select name="reminder-unit" class="form-control">
|
||||
<option value="0"><?php echo $hesklang['event_min_before_event']; ?></option>
|
||||
<option value="1"><?php echo $hesklang['event_hours_before_event']; ?></option>
|
||||
<option value="2"><?php echo $hesklang['event_days_before_event']; ?></option>
|
||||
<option value="3"><?php echo $hesklang['event_weeks_before_event']; ?></option>
|
||||
<option value="MINUTE"><?php echo $hesklang['event_min_before_event']; ?></option>
|
||||
<option value="HOUR"><?php echo $hesklang['event_hours_before_event']; ?></option>
|
||||
<option value="DAY"><?php echo $hesklang['event_days_before_event']; ?></option>
|
||||
<option value="WEEK"><?php echo $hesklang['event_weeks_before_event']; ?></option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
@ -339,6 +334,13 @@ require_once(HESK_PATH . 'inc/show_admin_nav.inc.php');
|
||||
</div>
|
||||
<form id="edit-form" class="form-horizontal" data-toggle="validator">
|
||||
<div class="modal-body">
|
||||
<ul class="nav nav-tabs" role="tablist" id="edit-modal-tabs">
|
||||
<li role="presentation" class="active"><a href="#edit-contents" aria-controls="home" role="tab" data-toggle="tab"><?php echo $hesklang['information']; ?></a></li>
|
||||
<li role="presentation"><a href="#edit-history" aria-controls="profile" role="tab" data-toggle="tab"><?php echo $hesklang['thist']; ?></a></li>
|
||||
</ul>
|
||||
<div class="tab-content" id="information-tab">
|
||||
<div role="tabpanel" class="tab-pane active" id="edit-contents">
|
||||
<br>
|
||||
<div class="row">
|
||||
<div class="col-md-12">
|
||||
<div class="form-group">
|
||||
@ -384,7 +386,9 @@ require_once(HESK_PATH . 'inc/show_admin_nav.inc.php');
|
||||
echo '<option value="">'.$hesklang['select'].'</option>';
|
||||
}
|
||||
foreach ($categories as $category): ?>
|
||||
<option value="<?php echo $category['id']; ?>" data-color="<?php echo $category['color']; ?>">
|
||||
<option value="<?php echo $category['id']; ?>" data-background-color="<?php echo htmlspecialchars($category['background_color']); ?>"
|
||||
data-foreground-color="<?php echo htmlspecialchars($category['foreground_color']); ?>"
|
||||
data-display-border="<?php echo htmlspecialchars($category['display_border_outline']); ?>">
|
||||
<?php echo $category['name']; ?>
|
||||
</option>
|
||||
<?php endforeach; ?>
|
||||
@ -456,10 +460,10 @@ require_once(HESK_PATH . 'inc/show_admin_nav.inc.php');
|
||||
</div>
|
||||
<div class="col-sm-4">
|
||||
<select name="reminder-unit" class="form-control">
|
||||
<option value="0"><?php echo $hesklang['event_min_before_event']; ?></option>
|
||||
<option value="1"><?php echo $hesklang['event_hours_before_event']; ?></option>
|
||||
<option value="2"><?php echo $hesklang['event_days_before_event']; ?></option>
|
||||
<option value="3"><?php echo $hesklang['event_weeks_before_event']; ?></option>
|
||||
<option value="MINUTE"><?php echo $hesklang['event_min_before_event']; ?></option>
|
||||
<option value="HOUR"><?php echo $hesklang['event_hours_before_event']; ?></option>
|
||||
<option value="DAY"><?php echo $hesklang['event_days_before_event']; ?></option>
|
||||
<option value="WEEK"><?php echo $hesklang['event_weeks_before_event']; ?></option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
@ -481,6 +485,20 @@ require_once(HESK_PATH . 'inc/show_admin_nav.inc.php');
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div role="tabpanel" class="tab-pane" id="edit-history">
|
||||
<br>
|
||||
<table class="table table-striped">
|
||||
<thead>
|
||||
<tr>
|
||||
<th><?php echo $hesklang['date']; ?></th>
|
||||
<th><?php echo $hesklang['description']; ?></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody id="history-table"></tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<input type="hidden" name="id">
|
||||
<div class="btn-group">
|
||||
@ -548,22 +566,34 @@ require_once(HESK_PATH . 'inc/show_admin_nav.inc.php');
|
||||
<strong><?php echo $hesklang['category']; ?></strong>
|
||||
<span></span>
|
||||
</div>
|
||||
<div class="popover-status">
|
||||
<strong><?php echo $hesklang['status']; ?></strong>
|
||||
<span></span>
|
||||
</div>
|
||||
<div class="popover-priority">
|
||||
<strong><?php echo $hesklang['priority']; ?></strong>
|
||||
<span></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<?php
|
||||
echo mfh_get_hidden_fields_for_language(array('error_loading_events',
|
||||
'error_deleting_event',
|
||||
'event_deleted',
|
||||
'event_created',
|
||||
'error_creating_event',
|
||||
'event_updated',
|
||||
'error_updating_event',
|
||||
'ticket_due_date_updated',
|
||||
'error_updating_ticket_due_date',
|
||||
'critical',
|
||||
'high',
|
||||
'medium',
|
||||
'low',
|
||||
'audit_event_created',
|
||||
'audit_event_updated'));
|
||||
?>
|
||||
<div style="display: none">
|
||||
<p id="lang_error_loading_events"><?php echo $hesklang['error_loading_events']; ?></p>
|
||||
<p id="lang_error_deleting_event"><?php echo $hesklang['error_deleting_event']; ?></p>
|
||||
<p id="lang_event_deleted"><?php echo $hesklang['event_deleted']; ?></p>
|
||||
<p id="lang_event_created"><?php echo $hesklang['event_created']; ?></p>
|
||||
<p id="lang_error_creating_event"><?php echo $hesklang['error_creating_event']; ?></p>
|
||||
<p id="lang_event_updated"><?php echo $hesklang['event_updated']; ?></p>
|
||||
<p id="lang_error_updating_event"><?php echo $hesklang['error_updating_event']; ?></p>
|
||||
<p id="lang_ticket_due_date_updated"><?php echo $hesklang['ticket_due_date_updated']; ?></p>
|
||||
<p id="lang_error_updating_ticket_due_date"><?php echo $hesklang['error_updating_ticket_due_date']; ?></p>
|
||||
<p id="setting_first_day_of_week"><?php echo $modsForHesk_settings['first_day_of_week']; ?></p>
|
||||
<p id="setting_default_view">
|
||||
<?php
|
||||
@ -575,7 +605,21 @@ require_once(HESK_PATH . 'inc/show_admin_nav.inc.php');
|
||||
echo $view_array[$_SESSION['default_calendar_view']];
|
||||
?>
|
||||
</p>
|
||||
<p id="setting_show_start_time"><?php echo $modsForHesk_settings['calendar_show_start_time']; ?></p>
|
||||
<?php
|
||||
$businessHoursRs = hesk_dbQuery("SELECT * FROM `" . hesk_dbEscape($hesk_settings['db_pfix']) . "mfh_calendar_business_hours`");
|
||||
while ($row = hesk_dbFetchAssoc($businessHoursRs)):
|
||||
?>
|
||||
<p id="business_hours_<?php echo $row['day_of_week']; ?>_start"><?php echo $row['start_time']; ?></p>
|
||||
<p id="business_hours_<?php echo $row['day_of_week']; ?>_end"><?php echo $row['end_time']; ?></p>
|
||||
<?php endwhile; ?>
|
||||
</div>
|
||||
<script type="text/html" id="audit-trail-template">
|
||||
<tr>
|
||||
<td data-property="date"></td>
|
||||
<td data-property="description"></td>
|
||||
</tr>
|
||||
</script>
|
||||
<?php
|
||||
|
||||
require_once(HESK_PATH . 'inc/footer.inc.php');
|
||||
|
@ -37,6 +37,10 @@ hesk_token_check();
|
||||
/* Ticket ID */
|
||||
$trackingID = hesk_cleanID() or die($hesklang['int_error'] . ': ' . $hesklang['no_trackID']);
|
||||
|
||||
$ticket_id_rs = hesk_dbQuery("SELECT `id` FROM `" . hesk_dbEscape($hesk_settings['db_pfix']) . "tickets` WHERE `trackid` = '" . hesk_dbEscape($trackingID) . "'");
|
||||
$ticket_id_row = hesk_dbFetchAssoc($ticket_id_rs);
|
||||
$ticket_id = $ticket_id_row['id'];
|
||||
|
||||
/* Valid statuses */
|
||||
$statusSql = "SELECT `ID` FROM `" . hesk_dbEscape($hesk_settings['db_pfix']) . "statuses`";
|
||||
$status_options = array();
|
||||
@ -54,6 +58,11 @@ if (!isset($status_options[$status])) {
|
||||
|
||||
$locked = 0;
|
||||
|
||||
$audit_closed = null;
|
||||
$audit_locked = null;
|
||||
$audit_status = null;
|
||||
$audit_opened = null;
|
||||
|
||||
$statusRow = hesk_dbFetchAssoc(hesk_dbQuery("SELECT `ID`, `IsClosed` FROM `" . hesk_dbEscape($hesk_settings['db_pfix']) . "statuses` WHERE ID = " . $status));
|
||||
if ($statusRow['IsClosed']) // Closed
|
||||
{
|
||||
@ -62,10 +71,14 @@ if ($statusRow['IsClosed']) // Closed
|
||||
}
|
||||
|
||||
$action = $hesklang['ticket_been'] . ' ' . $hesklang['close'];
|
||||
$revision = sprintf($hesklang['thist3'], hesk_date(), $_SESSION['name'] . ' (' . $_SESSION['user'] . ')');
|
||||
$audit_closed = array(0 => $_SESSION['name'] . ' (' . $_SESSION['user'] . ')');
|
||||
$audit_status = array(0 => $_SESSION['name'] . ' (' . $_SESSION['user'] . ')',
|
||||
1 => $status_options[$status]);
|
||||
|
||||
|
||||
if ($hesk_settings['custopen'] != 1) {
|
||||
$locked = 1;
|
||||
$audit_locked = array();
|
||||
}
|
||||
|
||||
// Notify customer of closed ticket?
|
||||
@ -88,24 +101,46 @@ if ($statusRow['IsClosed']) // Closed
|
||||
|
||||
// Log who marked the ticket resolved
|
||||
$closedby_sql = ' , `closedat`=NOW(), `closedby`=' . intval($_SESSION['id']) . ' ';
|
||||
} elseif ($statusRow['IsNewTicketStatus'] == '0') //Ticket is still open, but not new
|
||||
} elseif ($statusRow['IsNewTicketStatus'] == 0) //Ticket is still open, but not new
|
||||
{
|
||||
$action = sprintf($hesklang['tsst'], $status_options[$status]);
|
||||
$revision = sprintf($hesklang['thist9'], hesk_date(), $status_options[$status], $_SESSION['name'] . ' (' . $_SESSION['user'] . ')');
|
||||
$audit_status = array(0 => $_SESSION['name'] . ' (' . $_SESSION['user'] . ')',
|
||||
1 => $status_options[$status]);
|
||||
|
||||
|
||||
// Ticket is not resolved
|
||||
$closedby_sql = ' , `closedat`=NULL, `closedby`=NULL ';
|
||||
} else // Ticket is marked as "NEW"
|
||||
{
|
||||
$action = $hesklang['ticket_been'] . ' ' . $hesklang['opened'];
|
||||
$revision = sprintf($hesklang['thist4'], hesk_date(), $_SESSION['name'] . ' (' . $_SESSION['user'] . ')');
|
||||
$audit_opened = array(0 => $_SESSION['name'] . ' (' . $_SESSION['user'] . ')');
|
||||
|
||||
// Ticket is not resolved
|
||||
$closedby_sql = ' , `closedat`=NULL, `closedby`=NULL ';
|
||||
}
|
||||
|
||||
|
||||
hesk_dbQuery("UPDATE `" . hesk_dbEscape($hesk_settings['db_pfix']) . "tickets` SET `status`='{$status}', `locked`='{$locked}' $closedby_sql , `history`=CONCAT(`history`,'" . hesk_dbEscape($revision) . "') WHERE `trackid`='" . hesk_dbEscape($trackingID) . "'");
|
||||
hesk_dbQuery("UPDATE `" . hesk_dbEscape($hesk_settings['db_pfix']) . "tickets` SET `status`='{$status}', `locked`='{$locked}' $closedby_sql WHERE `trackid`='" . hesk_dbEscape($trackingID) . "'");
|
||||
|
||||
if ($audit_status !== null) {
|
||||
mfh_insert_audit_trail_record($ticket_id, 'TICKET', 'audit_status', hesk_date(),
|
||||
$audit_status);
|
||||
}
|
||||
|
||||
if ($audit_closed !== null) {
|
||||
mfh_insert_audit_trail_record($ticket_id, 'TICKET', 'audit_closed', hesk_date(),
|
||||
$audit_closed);
|
||||
}
|
||||
|
||||
if ($audit_locked !== null) {
|
||||
mfh_insert_audit_trail_record($ticket_id, 'TICKET', 'audit_automatically_locked', hesk_date(),
|
||||
array());
|
||||
}
|
||||
|
||||
if ($audit_opened !== null) {
|
||||
mfh_insert_audit_trail_record($ticket_id, 'TICKET', 'audit_opened', hesk_date(),
|
||||
$audit_opened);
|
||||
}
|
||||
|
||||
if (hesk_dbAffectedRows() != 1) {
|
||||
hesk_error("$hesklang[int_error]: $hesklang[trackID_not_found].");
|
||||
|
@ -166,7 +166,31 @@ require_once(HESK_PATH . 'inc/show_admin_nav.inc.php');
|
||||
</div>
|
||||
<?php
|
||||
}
|
||||
?>
|
||||
|
||||
$descriptions = hesk_SESSION(array('new_cf','descriptions')); ?>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="description[]" class="col-sm-3 control-label">
|
||||
<?php echo $hesklang['description']; ?>
|
||||
</label>
|
||||
<?php if ($hesk_settings['can_sel_lang'] && count($hesk_settings['languages']) > 1): ?>
|
||||
<table border="0">
|
||||
<?php foreach ($hesk_settings['languages'] as $lang => $info): ?>
|
||||
<tr>
|
||||
<td><?php echo $lang; ?></td>
|
||||
<td>
|
||||
<textarea class="form-control"
|
||||
name="description[<?php echo $lang; ?>]"><?php echo (isset($descriptions[$lang]) ? $descriptions[$lang] : ''); ?></textarea>
|
||||
</td>
|
||||
</tr>
|
||||
<?php endforeach; ?>
|
||||
</table>
|
||||
<?php else: ?>
|
||||
<div class="col-sm-9">
|
||||
<textarea class="form-control"
|
||||
name="description[<?php echo $hesk_settings['language']; ?>]"><?php echo (isset($descriptions[$hesk_settings['language']]) ? $descriptions[$hesk_settings['language']] : ''); ?></textarea>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="name[]" class="col-sm-3 control-label">
|
||||
@ -222,7 +246,7 @@ require_once(HESK_PATH . 'inc/show_admin_nav.inc.php');
|
||||
<?php echo $hesklang['custom_l']; ?>
|
||||
</label>
|
||||
<div class="col-sm-3">
|
||||
<input type="text" class="form-control" name="max_length"
|
||||
<input type="text" class="form-control" name="readonly_max_length"
|
||||
value="<?php echo isset($value['max_length']) ? intval($value['max_length']) : '255'; ?>" size="5">
|
||||
</div>
|
||||
</div>
|
||||
@ -231,7 +255,7 @@ require_once(HESK_PATH . 'inc/show_admin_nav.inc.php');
|
||||
<?php echo $hesklang['defw']; ?>
|
||||
</label>
|
||||
<div class="col-sm-3">
|
||||
<input type="text" class="form-control" name="default_value"
|
||||
<input type="text" class="form-control" name="readonly_default_value"
|
||||
value="<?php echo isset($value['default_value']) ? $value['default_value'] : ''; ?>" size="30">
|
||||
</div>
|
||||
</div>
|
||||
@ -495,7 +519,9 @@ require_once(HESK_PATH . 'inc/show_admin_nav.inc.php');
|
||||
<?php echo $hesklang['email_custom_field_label']; ?>
|
||||
</label>
|
||||
<div class="col-sm-8">
|
||||
<?php $address_type = empty($value['email_type']) ? 'none' : $value['email_type']; ?>
|
||||
<?php
|
||||
$address_type = empty($value['email_type']) ? 'none' : $value['email_type'];
|
||||
?>
|
||||
<div class="radio">
|
||||
<label>
|
||||
<input type="radio" name="email_type" value="none"
|
||||
@ -732,7 +758,7 @@ require_once(HESK_PATH . 'inc/show_admin_nav.inc.php');
|
||||
$num_before = 0;
|
||||
$num_after = 0;
|
||||
|
||||
foreach ($hesk_settings['custom_fields'] as $id => $cf) {
|
||||
foreach ($hesk_settings['custom_fields'] as $tmp_id => $cf) {
|
||||
if ($cf['place']) {
|
||||
$num_after++;
|
||||
} else {
|
||||
@ -741,8 +767,8 @@ require_once(HESK_PATH . 'inc/show_admin_nav.inc.php');
|
||||
}
|
||||
|
||||
$k = 1;
|
||||
foreach ($hesk_settings['custom_fields'] as $id => $cf) {
|
||||
$id = intval(str_replace('custom', '', $id));
|
||||
foreach ($hesk_settings['custom_fields'] as $tmp_id => $cf) {
|
||||
$tmp_id = intval(str_replace('custom', '', $tmp_id));
|
||||
|
||||
if ($hide_up) {
|
||||
$hide_up = false;
|
||||
@ -771,8 +797,17 @@ require_once(HESK_PATH . 'inc/show_admin_nav.inc.php');
|
||||
$cf['category'] = count($cf['category']) ? $hesklang['cf_cat'] : $hesklang['cf_all'];
|
||||
?>
|
||||
<tr>
|
||||
<td><?php echo $id; ?></td>
|
||||
<td><?php echo $cf['name']; ?></td>
|
||||
<td><?php echo $tmp_id; ?></td>
|
||||
<td>
|
||||
<?php
|
||||
echo $cf['name'];
|
||||
if ($cf['mfh_description'] !== null && trim($cf['mfh_description']) !== '') {
|
||||
echo ' <i class="fa fa-info-circle" data-toggle="popover"
|
||||
data-title="' . htmlspecialchars($hesklang['description']) . '"
|
||||
data-content="' . htmlspecialchars($cf['mfh_description']) . '"></i>';
|
||||
}
|
||||
?>
|
||||
</td>
|
||||
<td><?php echo $cf['type']; ?></td>
|
||||
<td><?php echo $cf['use']; ?></td>
|
||||
<td><?php echo $cf['req']; ?></td>
|
||||
@ -791,33 +826,33 @@ require_once(HESK_PATH . 'inc/show_admin_nav.inc.php');
|
||||
} elseif ($k == 1 || $hide_up) {
|
||||
?>
|
||||
<i class="fa fa-fw icon-link"> </i>
|
||||
<a href="custom_fields.php?a=order_cf&id=<?php echo $id; ?>&move=15&token=<?php hesk_token_echo(); ?>">
|
||||
<a href="custom_fields.php?a=order_cf&id=<?php echo $tmp_id; ?>&move=15&token=<?php hesk_token_echo(); ?>">
|
||||
<i class="fa fa-arrow-down fa-fw icon-link green" data-toggle="tooltip" title="<?php echo $hesklang['move_dn']; ?>"></i>
|
||||
</a>
|
||||
<?php
|
||||
} elseif ($k == $hesk_settings['num_custom_fields'] || $k == $num_before) {
|
||||
?>
|
||||
<a href="custom_fields.php?a=order_cf&id=<?php echo $id; ?>&move=-15&token=<?php hesk_token_echo(); ?>">
|
||||
<a href="custom_fields.php?a=order_cf&id=<?php echo $tmp_id; ?>&move=-15&token=<?php hesk_token_echo(); ?>">
|
||||
<i class="fa fa-arrow-up fa-fw icon-link green" data-toggle="tooltip" title="<?php echo $hesklang['move_up']; ?>"></i>
|
||||
</a>
|
||||
<i class="fa fa-fw icon-link"> </i>
|
||||
<?php
|
||||
} else {
|
||||
?>
|
||||
<a href="custom_fields.php?a=order_cf&id=<?php echo $id; ?>&move=-15&token=<?php hesk_token_echo(); ?>">
|
||||
<a href="custom_fields.php?a=order_cf&id=<?php echo $tmp_id; ?>&move=-15&token=<?php hesk_token_echo(); ?>">
|
||||
<i class="fa fa-arrow-up fa-fw icon-link green" data-toggle="tooltip" title="<?php echo $hesklang['move_up']; ?>"></i>
|
||||
</a>
|
||||
<a href="custom_fields.php?a=order_cf&id=<?php echo $id; ?>&move=15&token=<?php hesk_token_echo(); ?>">
|
||||
<a href="custom_fields.php?a=order_cf&id=<?php echo $tmp_id; ?>&move=15&token=<?php hesk_token_echo(); ?>">
|
||||
<i class="fa fa-arrow-down fa-fw icon-link green" data-toggle="tooltip" title="<?php echo $hesklang['move_dn']; ?>"></i>
|
||||
</a>
|
||||
<?php
|
||||
}
|
||||
}
|
||||
?>
|
||||
<a href="custom_fields.php?a=edit_cf&id=<?php echo $id; ?>">
|
||||
<a name="Edit <?php echo $cf['name']; ?>" href="custom_fields.php?a=edit_cf&id=<?php echo $tmp_id; ?>">
|
||||
<i class="fa fa-pencil fa-fw icon-link orange" data-toggle="tooltip" title="<?php echo $hesklang['edit']; ?>"></i>
|
||||
</a>
|
||||
<a href="custom_fields.php?a=remove_cf&id=<?php echo $id; ?>&token=<?php hesk_token_echo(); ?>"
|
||||
<a name="Delete <?php echo $cf['name']; ?>" href="custom_fields.php?a=remove_cf&id=<?php echo $tmp_id; ?>&token=<?php hesk_token_echo(); ?>"
|
||||
onclick="return hesk_confirmExecute('<?php echo hesk_makeJsString($hesklang['del_cf']); ?>');">
|
||||
<i class="fa fa-times fa-fw icon-link red" data-toggle="tooltip" title="<?php echo $hesklang['delete']; ?>"></i>
|
||||
</a>
|
||||
@ -885,6 +920,7 @@ function save_cf()
|
||||
`req` = '{$cf['req']}',
|
||||
`category` = ".(count($cf['categories']) ? "'".json_encode($cf['categories'])."'" : 'NULL').",
|
||||
`name` = '".hesk_dbEscape($cf['names'])."',
|
||||
`mfh_description` = '".hesk_dbEscape($cf['descriptions'])."',
|
||||
`value` = ".(strlen($cf['value']) ? "'".hesk_dbEscape($cf['value'])."'" : 'NULL')."
|
||||
WHERE `id`={$id}");
|
||||
|
||||
@ -916,6 +952,9 @@ function edit_cf()
|
||||
$cf['names'] = json_decode($cf['name'], true);
|
||||
unset($cf['name']);
|
||||
|
||||
$cf['descriptions'] = json_decode($cf['mfh_description'], true);
|
||||
unset($cf['mfh_description']);
|
||||
|
||||
if (strlen($cf['category']))
|
||||
{
|
||||
$cf['categories'] = json_decode($cf['category'], true);
|
||||
@ -994,7 +1033,7 @@ function remove_cf()
|
||||
$id = intval( hesk_GET('id') ) or hesk_error($hesklang['cf_e_id']);
|
||||
|
||||
// Reset the custom field
|
||||
hesk_dbQuery("UPDATE `".hesk_dbEscape($hesk_settings['db_pfix'])."custom_fields` SET `use`='0', `place`='0', `type`='text', `req`='0', `category`=NULL, `name`='', `value`=NULL, `order`=1000 WHERE `id`={$id}");
|
||||
hesk_dbQuery("UPDATE `".hesk_dbEscape($hesk_settings['db_pfix'])."custom_fields` SET `use`='0', `place`='0', `type`='text', `req`='0', `category`=NULL, `name`='', `mfh_description`=NULL, `value`=NULL, `order`=1000 WHERE `id`={$id}");
|
||||
|
||||
// Were we successful?
|
||||
if ( hesk_dbAffectedRows() == 1 )
|
||||
@ -1057,6 +1096,27 @@ function cf_validate()
|
||||
$hesk_error_buffer[] = $hesklang['err_custname'];
|
||||
}
|
||||
|
||||
// Descriptions
|
||||
$cf['descriptions'] = hesk_POST_array('description');
|
||||
|
||||
// Make sure only non-empty descriptions pass
|
||||
foreach ($cf['descriptions'] as $key => $description) {
|
||||
if (!isset($hesk_settings['languages'][$key])) {
|
||||
unset($cf['descriptions'][$key]);
|
||||
} else {
|
||||
$description = is_array($description) ? '' : hesk_input($description, 0, 0, HESK_SLASH);
|
||||
|
||||
if (strlen($description) < 1)
|
||||
{
|
||||
unset($cf['descriptions'][$key]);
|
||||
}
|
||||
else
|
||||
{
|
||||
$cf['descriptions'][$key] = stripslashes($description);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Get type and values
|
||||
$cf['type'] = hesk_POST('type');
|
||||
switch ($cf['type'])
|
||||
@ -1202,8 +1262,8 @@ function cf_validate()
|
||||
break;
|
||||
|
||||
case 'readonly':
|
||||
$max_length = hesk_POST('max_length');
|
||||
$value = hesk_POST('default_value');
|
||||
$max_length = hesk_POST('readonly_max_length');
|
||||
$value = hesk_POST('readonly_default_value');
|
||||
$cf['value'] = array('default_value' => $value, 'max_length' => $max_length);
|
||||
break;
|
||||
|
||||
@ -1264,8 +1324,10 @@ function cf_validate()
|
||||
}
|
||||
|
||||
$cf['names'] = addslashes(json_encode($cf['names']));
|
||||
$cf['descriptions'] = addslashes(json_encode($cf['descriptions']));
|
||||
$cf['value'] = $cf['type'] == 'date' ? json_encode($cf['value']) : addslashes(json_encode($cf['value']));
|
||||
|
||||
|
||||
return $cf;
|
||||
} // END cf_validate()
|
||||
|
||||
@ -1305,6 +1367,7 @@ function new_cf()
|
||||
`req` = '{$cf['req']}',
|
||||
`category` = ".(count($cf['categories']) ? "'".json_encode($cf['categories'])."'" : 'NULL').",
|
||||
`name` = '".hesk_dbEscape($cf['names'])."',
|
||||
`mfh_description` = '".hesk_dbEscape($cf['descriptions'])."',
|
||||
`value` = ".(strlen($cf['value']) ? "'".hesk_dbEscape($cf['value'])."'" : 'NULL').",
|
||||
`order` = 990
|
||||
WHERE `id`={$_SESSION['cford']}");
|
||||
|
@ -81,12 +81,130 @@ $i = 0;
|
||||
|
||||
// Possible priorities
|
||||
$priorities = array(
|
||||
'critical' => array('value' => 0, 'text' => $hesklang['critical'], 'formatted' => '<font class="critical">' . $hesklang['critical'] . '</font>'),
|
||||
'high' => array('value' => 1, 'text' => $hesklang['high'], 'formatted' => '<font class="important">' . $hesklang['high'] . '</font>'),
|
||||
'medium' => array('value' => 2, 'text' => $hesklang['medium'], 'formatted' => '<font class="medium">' . $hesklang['medium'] . '</font>'),
|
||||
'low' => array('value' => 3, 'text' => $hesklang['low'], 'formatted' => $hesklang['low']),
|
||||
'critical' => array('value' => 0, 'lang' => 'critical', 'text' => $hesklang['critical'], 'formatted' => '<font class="critical">' . $hesklang['critical'] . '</font>'),
|
||||
'high' => array('value' => 1, 'lang' => 'high', 'text' => $hesklang['high'], 'formatted' => '<font class="important">' . $hesklang['high'] . '</font>'),
|
||||
'medium' => array('value' => 2, 'lang' => 'medium', 'text' => $hesklang['medium'], 'formatted' => '<font class="medium">' . $hesklang['medium'] . '</font>'),
|
||||
'low' => array('value' => 3, 'lang' => 'low', 'text' => $hesklang['low'], 'formatted' => $hesklang['low']),
|
||||
);
|
||||
|
||||
// Assign tickets to
|
||||
if ( isset($_POST['assign']) && $_POST['assign'] == $hesklang['assi']) {
|
||||
if ( ! isset($_POST['owner']) || $_POST['owner'] == '') {
|
||||
hesk_process_messages($hesklang['assign_no'], $referer, 'NOTICE');
|
||||
}
|
||||
|
||||
$end_message = array();
|
||||
$num_assigned = 0;
|
||||
|
||||
// Permissions
|
||||
$can_assign_others = hesk_checkPermission('can_assign_others',0);
|
||||
if ($can_assign_others) {
|
||||
$can_assign_self = true;
|
||||
} else {
|
||||
$can_assign_self = hesk_checkPermission('can_assign_self',0);
|
||||
}
|
||||
|
||||
$owner = intval( hesk_POST('owner') );
|
||||
|
||||
if ($owner == -1) {
|
||||
foreach ($_POST['id'] as $this_id) {
|
||||
if (is_array($this_id)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$this_id = intval($this_id) or hesk_error($hesklang['id_not_valid']);
|
||||
|
||||
$res = hesk_dbQuery("UPDATE `".hesk_dbEscape($hesk_settings['db_pfix'])."tickets` SET `owner`=0, `assignedby`=NULL WHERE `id`={$this_id} LIMIT 1");
|
||||
mfh_insert_audit_trail_record($this_id, 'TICKET', 'audit_unassigned', hesk_date(), array(0 => $_SESSION['name'].' ('.$_SESSION['user'].')'));
|
||||
|
||||
$end_message[] = sprintf($hesklang['assign_2'], $this_id);
|
||||
$i++;
|
||||
}
|
||||
|
||||
hesk_process_messages($hesklang['assign_1'],$referer,'SUCCESS');
|
||||
}
|
||||
|
||||
$res = hesk_dbQuery("SELECT `id`,`user`,`name`,`email`,`isadmin`,`categories`,`notify_assigned` FROM `".hesk_dbEscape($hesk_settings['db_pfix'])."users` WHERE `id`='{$owner}' LIMIT 1");
|
||||
$owner_data = hesk_dbFetchAssoc($res);
|
||||
|
||||
if (!$owner_data['isadmin']) {
|
||||
$owner_data['categories']=explode(',',$owner_data['categories']);
|
||||
}
|
||||
|
||||
require(HESK_PATH . 'inc/email_functions.inc.php');
|
||||
|
||||
foreach ($_POST['id'] as $this_id) {
|
||||
if (is_array($this_id)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$this_id = intval($this_id) or hesk_error($hesklang['id_not_valid']);
|
||||
|
||||
$result = hesk_dbQuery("SELECT * FROM `".hesk_dbEscape($hesk_settings['db_pfix'])."tickets` WHERE `id`={$this_id} LIMIT 1");
|
||||
if (hesk_dbNumRows($result) != 1) {
|
||||
continue;
|
||||
}
|
||||
$ticket = hesk_dbFetchAssoc($result);
|
||||
|
||||
if ($ticket['owner'] == $owner) {
|
||||
$end_message[] = sprintf($hesklang['assign_3'], $ticket['trackid'], $owner_data['name']);
|
||||
$i++;
|
||||
continue;
|
||||
}
|
||||
if ($owner_data['isadmin'] || in_array($ticket['category'],$owner_data['categories'])) {
|
||||
hesk_dbQuery("UPDATE `".hesk_dbEscape($hesk_settings['db_pfix'])."tickets` SET `owner`={$owner}, `assignedby`=".intval($_SESSION['id'])." WHERE `id`={$this_id} LIMIT 1");
|
||||
mfh_insert_audit_trail_record($this_id, 'TICKET', 'audit_assigned', hesk_date(), array(0 => $_SESSION['name'].' ('.$_SESSION['user'].')',
|
||||
1 => $owner_data['name'].' ('.$owner_data['user'].')'));
|
||||
|
||||
$end_message[] = sprintf($hesklang['assign_4'], $ticket['trackid'], $owner_data['name']);
|
||||
$num_assigned++;
|
||||
|
||||
$ticket['owner'] = $owner;
|
||||
|
||||
/* --> Prepare message */
|
||||
|
||||
// 1. Generate the array with ticket info that can be used in emails
|
||||
$info = array(
|
||||
'email' => $ticket['email'],
|
||||
'category' => $ticket['category'],
|
||||
'priority' => $ticket['priority'],
|
||||
'owner' => $ticket['owner'],
|
||||
'trackid' => $ticket['trackid'],
|
||||
'status' => $ticket['status'],
|
||||
'name' => $ticket['name'],
|
||||
'subject' => $ticket['subject'],
|
||||
'message' => $ticket['message'],
|
||||
'attachments' => $ticket['attachments'],
|
||||
'dt' => hesk_date($ticket['dt'], true),
|
||||
'lastchange' => hesk_date($ticket['lastchange'], true),
|
||||
'id' => $ticket['id'],
|
||||
'time_worked' => $ticket['time_worked'],
|
||||
'last_reply_by' => hesk_getReplierName($ticket),
|
||||
);
|
||||
|
||||
// 2. Add custom fields to the array
|
||||
foreach ($hesk_settings['custom_fields'] as $k => $v) {
|
||||
$info[$k] = $v['use'] ? $ticket[$k] : '';
|
||||
}
|
||||
|
||||
// 3. Make sure all values are properly formatted for email
|
||||
$ticket = hesk_ticketToPlain($info, 1, 0);
|
||||
|
||||
/* Notify the new owner? */
|
||||
if ($ticket['owner'] != intval($_SESSION['id'])) {
|
||||
hesk_notifyAssignedStaff(false, 'ticket_assigned_to_you', $modsForHesk_settings);
|
||||
}
|
||||
} else {
|
||||
$end_message[] = sprintf($hesklang['assign_5'], $ticket['trackid'], $owner_data['name']);
|
||||
}
|
||||
|
||||
$i++;
|
||||
}
|
||||
|
||||
hesk_process_messages(sprintf($hesklang['assign_log'], $num_assigned, ($i - $num_assigned), implode("\n", $end_message)),$referer,($num_assigned == 0) ? 'ERROR' : ($num_assigned < $i ? 'NOTICE' : 'SUCCESS'));
|
||||
}
|
||||
|
||||
|
||||
// Change priority
|
||||
if (array_key_exists($_POST['a'], $priorities)) {
|
||||
// A security check
|
||||
@ -113,8 +231,10 @@ if (array_key_exists($_POST['a'], $priorities)) {
|
||||
|
||||
hesk_okCategory($ticket['category']);
|
||||
|
||||
$revision = sprintf($hesklang['thist8'], hesk_date(), $priority['formatted'], $_SESSION['name'] . ' (' . $_SESSION['user'] . ')');
|
||||
hesk_dbQuery("UPDATE `" . hesk_dbEscape($hesk_settings['db_pfix']) . "tickets` SET `priority`='{$priority['value']}', `history`=CONCAT(`history`,'" . hesk_dbEscape($revision) . "') WHERE `id`={$this_id}");
|
||||
hesk_dbQuery("UPDATE `" . hesk_dbEscape($hesk_settings['db_pfix']) . "tickets` SET `priority`='{$priority['value']}' WHERE `id`={$this_id}");
|
||||
mfh_insert_audit_trail_record($this_id, 'TICKET', 'audit_priority', hesk_date(),
|
||||
array(0 => $_SESSION['name'] . ' (' . $_SESSION['user'] . ')',
|
||||
1 => $priority['lang']));
|
||||
|
||||
$i++;
|
||||
}
|
||||
@ -133,8 +253,6 @@ elseif ($_POST['a'] == 'delete') {
|
||||
require(HESK_PATH . 'inc/email_functions.inc.php');
|
||||
}
|
||||
|
||||
$revision = sprintf($hesklang['thist3'], hesk_date(), $_SESSION['name'] . ' (' . $_SESSION['user'] . ')');
|
||||
|
||||
foreach ($_POST['id'] as $this_id) {
|
||||
if (is_array($this_id)) {
|
||||
continue;
|
||||
@ -211,7 +329,185 @@ elseif ($_POST['a'] == 'tag' || $_POST['a'] == 'untag') {
|
||||
}
|
||||
|
||||
hesk_process_messages(sprintf($action, $i), $referer, 'SUCCESS');
|
||||
} /* JUST CLOSE */
|
||||
}
|
||||
/* EXPORT */
|
||||
elseif ($_POST['a']=='export') {
|
||||
/* Check permissions for this feature */
|
||||
hesk_checkPermission('can_export');
|
||||
|
||||
/* A security check */
|
||||
hesk_token_check('POST');
|
||||
|
||||
$ids_to_export = array();
|
||||
|
||||
foreach ($_POST['id'] as $this_id) {
|
||||
if ( is_array($this_id) ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$ids_to_export[] = intval($this_id) or hesk_error($hesklang['id_not_valid']);
|
||||
$i++;
|
||||
}
|
||||
|
||||
if ($i < 1) {
|
||||
hesk_process_messages($hesklang['no_selected'], $referer, 'NOTICE');
|
||||
}
|
||||
|
||||
// Start SQL statement for selecting tickets
|
||||
$sql = "SELECT * FROM `".hesk_dbEscape($hesk_settings['db_pfix'])."tickets` WHERE `id` IN (".implode(',', $ids_to_export).") ";
|
||||
$sql .= " AND " . hesk_myCategories();
|
||||
$sql .= " AND " . hesk_myOwnership();
|
||||
|
||||
require_once(HESK_PATH . 'inc/custom_fields.inc.php');
|
||||
require(HESK_PATH . 'inc/export_functions.inc.php');
|
||||
|
||||
list($success_msg, $tickets_exported) = hesk_export_to_XML($sql, true);
|
||||
|
||||
if ($tickets_exported > 0) {
|
||||
hesk_process_messages($success_msg,$referer,'SUCCESS');
|
||||
} else {
|
||||
hesk_process_messages($hesklang['n2ex'],$referer,'NOTICE');
|
||||
}
|
||||
}
|
||||
/* ANONYMIZE */
|
||||
elseif ($_POST['a']=='anonymize') {
|
||||
/* Check permissions for this feature */
|
||||
hesk_checkPermission('can_privacy');
|
||||
|
||||
/* A security check */
|
||||
hesk_token_check('POST');
|
||||
|
||||
require(HESK_PATH . 'inc/privacy_functions.inc.php');
|
||||
|
||||
foreach ($_POST['id'] as $this_id) {
|
||||
if (is_array($this_id)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$this_id = intval($this_id) or hesk_error($hesklang['id_not_valid']);
|
||||
$result = hesk_dbQuery("SELECT `id`,`trackid`,`name`,`category` FROM `".hesk_dbEscape($hesk_settings['db_pfix'])."tickets` WHERE `id`='".intval($this_id)."' AND ".hesk_myOwnership()." LIMIT 1");
|
||||
if (hesk_dbNumRows($result) != 1) {
|
||||
continue;
|
||||
}
|
||||
$ticket = hesk_dbFetchAssoc($result);
|
||||
|
||||
hesk_okCategory($ticket['category']);
|
||||
|
||||
hesk_anonymizeTicket(null, null, true);
|
||||
$i++;
|
||||
}
|
||||
|
||||
hesk_process_messages(sprintf($hesklang['num_tickets_anon'],$i),$referer,'SUCCESS');
|
||||
}
|
||||
/* PRINT */
|
||||
elseif ($_POST['a']=='print') {
|
||||
/* Check permissions for this feature */
|
||||
hesk_checkPermission('can_view_tickets');
|
||||
|
||||
/* A security check */
|
||||
hesk_token_check('POST');
|
||||
|
||||
// Load custom fields
|
||||
require_once(HESK_PATH . 'inc/custom_fields.inc.php');
|
||||
|
||||
// List of staff
|
||||
if (!isset($admins)) {
|
||||
$admins = array();
|
||||
$res2 = hesk_dbQuery("SELECT `id`,`name` FROM `".hesk_dbEscape($hesk_settings['db_pfix'])."users` ORDER BY `id` ASC");
|
||||
while ($row=hesk_dbFetchAssoc($res2)) {
|
||||
$admins[$row['id']]=$row['name'];
|
||||
}
|
||||
}
|
||||
|
||||
// List of categories
|
||||
$hesk_settings['categories'] = array();
|
||||
$res2 = hesk_dbQuery('SELECT `id`, `name` FROM `'.hesk_dbEscape($hesk_settings['db_pfix']).'categories` WHERE ' . hesk_myCategories('id') . ' ORDER BY `cat_order` ASC');
|
||||
while ($row=hesk_dbFetchAssoc($res2)) {
|
||||
$hesk_settings['categories'][$row['id']] = $row['name'];
|
||||
}
|
||||
|
||||
// Print page head
|
||||
header('Content-Type: text/html; charset=utf-8');
|
||||
?>
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
|
||||
<html>
|
||||
<head>
|
||||
<title><?php echo $hesk_settings['hesk_title']; ?></title>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=<?php echo $hesklang['ENCODING']; ?>">
|
||||
<style type="text/css">
|
||||
body, table, td, p {
|
||||
color : black;
|
||||
font-family : Verdana, Geneva, Arial, Helvetica, sans-serif;
|
||||
font-size : <?php echo $hesk_settings['print_font_size']; ?>px;
|
||||
}
|
||||
table {
|
||||
border-collapse:collapse;
|
||||
}
|
||||
hr {
|
||||
border: 0;
|
||||
color: #9e9e9e;
|
||||
background-color: #9e9e9e;
|
||||
height: 1px;
|
||||
width: 100%;
|
||||
text-align: left;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body onload="window.print()">
|
||||
<?php
|
||||
|
||||
// Loop through ticket IDs and print them
|
||||
foreach ($_POST['id'] as $this_id) {
|
||||
if (is_array($this_id)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$this_id = intval($this_id) or hesk_error($hesklang['id_not_valid']);
|
||||
$result = hesk_dbQuery("SELECT `t1`.* , `ticketStatus`.`IsClosed` AS `isClosed`, `ticketStatus`.`Key` AS `statusKey`, `t2`.name AS `repliername`
|
||||
FROM `" . hesk_dbEscape($hesk_settings['db_pfix']) . "tickets` AS `t1` LEFT JOIN `" . hesk_dbEscape($hesk_settings['db_pfix']) . "users` AS `t2` ON `t1`.`replierid` = `t2`.`id`
|
||||
INNER JOIN `" . hesk_dbEscape($hesk_settings['db_pfix']) . "statuses` AS `ticketStatus` ON `t1`.`status` = `ticketStatus`.`ID`
|
||||
WHERE `t1`.`id`='{$this_id}' LIMIT 1");
|
||||
if (hesk_dbNumRows($result) != 1) {
|
||||
continue;
|
||||
}
|
||||
$ticket = hesk_dbFetchAssoc($result);
|
||||
|
||||
// Check that we have proper permissions to view this ticket
|
||||
hesk_okCategory($ticket['category']);
|
||||
|
||||
$can_view_ass_by = hesk_checkPermission('can_view_ass_by', 0);
|
||||
$can_view_unassigned = hesk_checkPermission('can_view_unassigned',0);
|
||||
|
||||
if ($ticket['owner'] && $ticket['owner'] != $_SESSION['id'] && ! hesk_checkPermission('can_view_ass_others',0)) {
|
||||
// Maybe this user is allowed to view tickets he/she assigned?
|
||||
if ( ! $can_view_ass_by || $ticket['assignedby'] != $_SESSION['id']) {
|
||||
hesk_error($hesklang['ycvtao']);
|
||||
}
|
||||
}
|
||||
|
||||
if (!$ticket['owner'] && ! $can_view_unassigned) {
|
||||
hesk_error($hesklang['ycovtay']);
|
||||
}
|
||||
|
||||
// All good, continue...
|
||||
|
||||
$category['name'] = isset($hesk_settings['categories'][$ticket['category']]) ? $hesk_settings['categories'][$ticket['category']] : $hesklang['catd'];
|
||||
|
||||
// Get replies
|
||||
$res = hesk_dbQuery("SELECT * FROM `".hesk_dbEscape($hesk_settings['db_pfix'])."replies` WHERE `replyto`='{$ticket['id']}' ORDER BY `id` ASC");
|
||||
$replies = hesk_dbNumRows($res);
|
||||
|
||||
// Print ticket
|
||||
require(HESK_PATH . 'inc/print_template.inc.php');
|
||||
flush();
|
||||
}
|
||||
?>
|
||||
</body>
|
||||
</html>
|
||||
<?php
|
||||
exit();
|
||||
}
|
||||
/* JUST CLOSE */
|
||||
else {
|
||||
/* Check permissions for this feature */
|
||||
hesk_checkPermission('can_view_tickets');
|
||||
@ -222,8 +518,6 @@ else {
|
||||
hesk_token_check('POST');
|
||||
require(HESK_PATH . 'inc/email_functions.inc.php');
|
||||
|
||||
$revision = sprintf($hesklang['thist3'], hesk_date(), $_SESSION['name'] . ' (' . $_SESSION['user'] . ')');
|
||||
|
||||
foreach ($_POST['id'] as $this_id) {
|
||||
if (is_array($this_id)) {
|
||||
continue;
|
||||
@ -239,7 +533,11 @@ else {
|
||||
$closedStatusRS = hesk_dbQuery("SELECT * FROM `" . hesk_dbEscape($hesk_settings['db_pfix']) . "statuses` WHERE `IsStaffClosedOption` = 1");
|
||||
$closedStatus = hesk_dbFetchAssoc($closedStatusRS);
|
||||
|
||||
hesk_dbQuery("UPDATE `" . hesk_dbEscape($hesk_settings['db_pfix']) . "tickets` SET `status`='" . $closedStatus['ID'] . "', `closedat`=NOW(), `closedby`=" . intval($_SESSION['id']) . ", `history`=CONCAT(`history`,'" . hesk_dbEscape($revision) . "') WHERE `id`='" . intval($this_id) . "'");
|
||||
hesk_dbQuery("UPDATE `" . hesk_dbEscape($hesk_settings['db_pfix']) . "tickets` SET `status`='" . $closedStatus['ID'] . "', `closedat`=NOW(), `closedby`=" . intval($_SESSION['id']) . " WHERE `id`='" . intval($this_id) . "'");
|
||||
|
||||
mfh_insert_audit_trail_record($this_id, 'TICKET', 'audit_closed', hesk_date(),
|
||||
array(0 => $_SESSION['name'] . ' (' . $_SESSION['user'] . ')'));
|
||||
|
||||
$i++;
|
||||
|
||||
// Notify customer of closed ticket?
|
||||
@ -284,6 +582,14 @@ function hesk_fullyDeleteTicket()
|
||||
/* Delete ticket notes */
|
||||
hesk_dbQuery("DELETE FROM `" . hesk_dbEscape($hesk_settings['db_pfix']) . "notes` WHERE `ticket`='" . intval($ticket['id']) . "'");
|
||||
|
||||
/* Delete audit trail records */
|
||||
hesk_dbQuery("DELETE FROM `" . hesk_dbEscape($hesk_settings['db_pfix']) . "audit_trail_to_replacement_values`
|
||||
WHERE `audit_trail_id` IN (
|
||||
SELECT `id` FROM `" . hesk_dbEscape($hesk_settings['db_pfix']) . "audit_trail`
|
||||
WHERE `entity_type` = 'TICKET' AND `entity_id` = " . intval($ticket['id']) . ")");
|
||||
hesk_dbQuery("DELETE FROM `" . hesk_dbEscape($hesk_settings['db_pfix']) . "audit_trail` WHERE `entity_type`='TICKET'
|
||||
AND `entity_id` = " . intval($ticket['id']));
|
||||
|
||||
/* Delete ticket reply drafts */
|
||||
hesk_dbQuery("DELETE FROM `" . hesk_dbEscape($hesk_settings['db_pfix']) . "reply_drafts` WHERE `ticket`=" . intval($ticket['id']));
|
||||
|
||||
|
@ -24,6 +24,8 @@ require(HESK_PATH . 'inc/admin_functions.inc.php');
|
||||
require(HESK_PATH . 'inc/mail_functions.inc.php');
|
||||
require(HESK_PATH . 'inc/custom_fields.inc.php');
|
||||
hesk_load_database_functions();
|
||||
require(HESK_PATH . 'inc/posting_functions.inc.php');
|
||||
require(HESK_PATH . 'inc/view_attachment_functions.inc.php');
|
||||
|
||||
hesk_session_start();
|
||||
hesk_dbConnect();
|
||||
@ -34,6 +36,7 @@ if (!isset($_REQUEST['isManager']) || !$_REQUEST['isManager']) {
|
||||
hesk_checkPermission('can_view_tickets');
|
||||
hesk_checkPermission('can_edit_tickets');
|
||||
}
|
||||
|
||||
$modsForHesk_settings = mfh_getSettings();
|
||||
|
||||
/* Ticket ID */
|
||||
@ -63,6 +66,7 @@ if (!isset($_REQUEST['isManager']) || !$_REQUEST['isManager']) {
|
||||
hesk_okCategory($ticket['category']);
|
||||
}
|
||||
|
||||
|
||||
if (hesk_isREQUEST('reply')) {
|
||||
$tmpvar['id'] = intval(hesk_REQUEST('reply')) or die($hesklang['id_not_valid']);
|
||||
|
||||
@ -76,16 +80,51 @@ if (hesk_isREQUEST('reply')) {
|
||||
$is_reply = 1;
|
||||
}
|
||||
|
||||
// Count number of existing attachments for this post
|
||||
$number_of_attachments = $is_reply ? hesk_countAttachments($reply['attachments']) : hesk_countAttachments($ticket['attachments']);
|
||||
|
||||
if (isset($_POST['save'])) {
|
||||
/* A security check */
|
||||
hesk_token_check('POST');
|
||||
|
||||
$hesk_error_buffer = array();
|
||||
|
||||
// Add attachments?
|
||||
if ($hesk_settings['attachments']['use'] && $number_of_attachments < $hesk_settings['attachments']['max_number']) {
|
||||
require_once(HESK_PATH . 'inc/attachments.inc.php');
|
||||
|
||||
$attachments = array();
|
||||
|
||||
$use_legacy_attachments = hesk_POST('use-legacy-attachments', 0);
|
||||
|
||||
if ($use_legacy_attachments) {
|
||||
for ($i = $number_of_attachments + 1; $i <= $hesk_settings['attachments']['max_number']; $i++) {
|
||||
$att = hesk_uploadFile($i);
|
||||
if ($att !== false && !empty($att)) {
|
||||
$attachments[$i] = $att;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// The user used the new drag-and-drop system.
|
||||
$temp_attachment_ids = hesk_POST_array('attachment-ids');
|
||||
foreach ($temp_attachment_ids as $temp_attachment_id) {
|
||||
// Simply get the temp info and move it to the attachments table
|
||||
$temp_attachment = mfh_getTemporaryAttachment($temp_attachment_id);
|
||||
$attachments[] = $temp_attachment;
|
||||
mfh_deleteTemporaryAttachment($temp_attachment_id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ($is_reply) {
|
||||
$tmpvar['message'] = hesk_input(hesk_POST('message')) or $hesk_error_buffer[] = $hesklang['enter_message'];
|
||||
|
||||
if (count($hesk_error_buffer)) {
|
||||
// Remove any successfully uploaded attachments
|
||||
if ($hesk_settings['attachments']['use'] && isset($attachments)) {
|
||||
hesk_removeAttachments($attachments);
|
||||
}
|
||||
|
||||
$myerror = '<ul>';
|
||||
foreach ($hesk_error_buffer as $error) {
|
||||
$myerror .= "<li>$error</li>\n";
|
||||
@ -101,7 +140,14 @@ if (isset($_POST['save'])) {
|
||||
|
||||
$tmpvar['html'] = hesk_POST('html');
|
||||
|
||||
hesk_dbQuery("UPDATE `" . hesk_dbEscape($hesk_settings['db_pfix']) . "replies` SET `html`='" . $tmpvar['html'] . "', `message`='" . hesk_dbEscape($tmpvar['message']) . "' WHERE `id`='" . intval($tmpvar['id']) . "' AND `replyto`='" . intval($ticket['id']) . "'");
|
||||
if ($hesk_settings['attachments']['use'] && !empty($attachments)) {
|
||||
foreach ($attachments as $myatt) {
|
||||
hesk_dbQuery("INSERT INTO `".hesk_dbEscape($hesk_settings['db_pfix'])."attachments` (`ticket_id`,`saved_name`,`real_name`,`size`) VALUES ('".hesk_dbEscape($trackingID)."','".hesk_dbEscape($myatt['saved_name'])."','".hesk_dbEscape($myatt['real_name'])."','".intval($myatt['size'])."')");
|
||||
$myattachments .= hesk_dbInsertID() . '#' . $myatt['real_name'] . '#' . $myatt['saved_name'] . ',';
|
||||
}
|
||||
}
|
||||
|
||||
hesk_dbQuery("UPDATE `" . hesk_dbEscape($hesk_settings['db_pfix']) . "replies` SET `html`='" . $tmpvar['html'] . "', `message`='" . hesk_dbEscape($tmpvar['message']) . "', `attachments`=CONCAT(`attachments`, '".hesk_dbEscape($myattachments)."') WHERE `id`='" . intval($tmpvar['id']) . "' AND `replyto`='" . intval($ticket['id']) . "'");
|
||||
} else {
|
||||
$tmpvar['language'] = hesk_POST('customerLanguage');
|
||||
$tmpvar['name'] = hesk_input(hesk_POST('name')) or $hesk_error_buffer[] = $hesklang['enter_your_name'];
|
||||
@ -147,7 +193,7 @@ if (isset($_POST['save'])) {
|
||||
|
||||
if (isset($_POST[$k]) && is_array($_POST[$k])) {
|
||||
foreach ($_POST[$k] as $myCB) {
|
||||
$tmpvar[$k] .= ( is_array($myCB) ? '' : hesk_input($myCB) ) . '<br>';
|
||||
$tmpvar[$k] .= ( is_array($myCB) ? '' : hesk_input($myCB) ) . '<br />';
|
||||
}
|
||||
$tmpvar[$k]=substr($tmpvar[$k],0,-6);
|
||||
} else {
|
||||
@ -161,9 +207,9 @@ if (isset($_POST['save'])) {
|
||||
$_SESSION["as_$k"] = '';
|
||||
|
||||
if (preg_match("/^[0-9]{4}-(0[1-9]|1[0-2])-(0[1-9]|[1-2][0-9]|3[0-1])$/", $tmpvar[$k])) {
|
||||
$date = strtotime($tmpvar[$k] . ' t00:00:00');
|
||||
$dmin = strlen($v['value']['dmin']) ? strtotime($v['value']['dmin'] . ' t00:00:00') : false;
|
||||
$dmax = strlen($v['value']['dmax']) ? strtotime($v['value']['dmax'] . ' t00:00:00') : false;
|
||||
$date = strtotime($tmpvar[$k] . ' t00:00:00 UTC');
|
||||
$dmin = strlen($v['value']['dmin']) ? strtotime($v['value']['dmin'] . ' t00:00:00 UTC') : false;
|
||||
$dmax = strlen($v['value']['dmax']) ? strtotime($v['value']['dmax'] . ' t00:00:00 UTC') : false;
|
||||
|
||||
$_SESSION["as_$k"] = $tmpvar[$k];
|
||||
|
||||
@ -208,6 +254,11 @@ if (isset($_POST['save'])) {
|
||||
}
|
||||
|
||||
if (count($hesk_error_buffer)) {
|
||||
// Remove any successfully uploaded attachments
|
||||
if ($hesk_settings['attachments']['use'] && isset($attachments)) {
|
||||
hesk_removeAttachments($attachments);
|
||||
}
|
||||
|
||||
$myerror = '<ul>';
|
||||
foreach ($hesk_error_buffer as $error) {
|
||||
$myerror .= "<li>$error</li>\n";
|
||||
@ -221,6 +272,13 @@ if (isset($_POST['save'])) {
|
||||
$tmpvar['message'] = nl2br($tmpvar['message']);
|
||||
}
|
||||
|
||||
if ($hesk_settings['attachments']['use'] && !empty($attachments)) {
|
||||
foreach ($attachments as $myatt) {
|
||||
hesk_dbQuery("INSERT INTO `".hesk_dbEscape($hesk_settings['db_pfix'])."attachments` (`ticket_id`,`saved_name`,`real_name`,`size`) VALUES ('".hesk_dbEscape($trackingID)."','".hesk_dbEscape($myatt['saved_name'])."','".hesk_dbEscape($myatt['real_name'])."','".intval($myatt['size'])."')");
|
||||
$myattachments .= hesk_dbInsertID() . '#' . $myatt['real_name'] . '#' . $myatt['saved_name'] . ',';
|
||||
}
|
||||
}
|
||||
|
||||
$custom_SQL = '';
|
||||
for ($i = 1; $i <= 50; $i++) {
|
||||
$custom_SQL .= '`custom'.$i.'`=' . (isset($tmpvar['custom'.$i]) ? "'".hesk_dbEscape($tmpvar['custom'.$i])."'" : "''") . ',';
|
||||
@ -232,6 +290,7 @@ if (isset($_POST['save'])) {
|
||||
`email`='" . hesk_dbEscape($tmpvar['email']) . "',
|
||||
`subject`='" . hesk_dbEscape($tmpvar['subject']) . "',
|
||||
`message`='" . hesk_dbEscape($tmpvar['message']) . "',
|
||||
`attachments`=CONCAT(`attachments`, '".hesk_dbEscape($myattachments)."'),
|
||||
`language`='" . hesk_dbEscape($tmpvar['language']) . "',
|
||||
`html`='" . hesk_dbEscape($tmpvar['html']) . "',
|
||||
$custom_SQL
|
||||
@ -278,7 +337,7 @@ require_once(HESK_PATH . 'inc/show_admin_nav.inc.php');
|
||||
$onsubmit = 'onsubmit="return validateRichText(\'message-help-block\', \'message-group\', \'message\', \''.htmlspecialchars($hesklang['this_field_is_required']).'\')"';
|
||||
}
|
||||
?>
|
||||
<form role="form" class="form-horizontal" method="post" action="edit_post.php" name="form1" <?php echo $onsubmit; ?>>
|
||||
<form role="form" class="form-horizontal" method="post" action="edit_post.php" name="form1" enctype="multipart/form-data" <?php echo $onsubmit; ?>>
|
||||
<?php
|
||||
/* If it's not a reply edit all the fields */
|
||||
if (!$is_reply) {
|
||||
@ -309,7 +368,7 @@ require_once(HESK_PATH . 'inc/show_admin_nav.inc.php');
|
||||
<label for="subject" class="col-sm-3 control-label"><?php echo $hesklang['subject'] . $required; ?></label>
|
||||
|
||||
<div class="col-sm-9">
|
||||
<input class="form-control" type="text" name="subject" size="40" maxlength="40"
|
||||
<input class="form-control" type="text" name="subject" size="40" maxlength="70"
|
||||
value="<?php echo $ticket['subject']; ?>"
|
||||
placeholder="<?php echo htmlspecialchars($hesklang['subject']); ?>"/>
|
||||
</div>
|
||||
@ -321,7 +380,7 @@ require_once(HESK_PATH . 'inc/show_admin_nav.inc.php');
|
||||
</label>
|
||||
|
||||
<div class="col-sm-9">
|
||||
<input class="form-control" type="text" name="name" size="40" maxlength="30"
|
||||
<input class="form-control" type="text" name="name" size="40" maxlength="50"
|
||||
value="<?php echo $ticket['name']; ?>"
|
||||
placeholder="<?php echo htmlspecialchars($hesklang['name']); ?>"
|
||||
data-error="<?php echo $hesklang['this_field_is_required']; ?>"
|
||||
@ -354,7 +413,7 @@ require_once(HESK_PATH . 'inc/show_admin_nav.inc.php');
|
||||
$k_value = $ticket[$k];
|
||||
|
||||
if ($v['type'] == 'checkbox') {
|
||||
$k_value = explode('<br>', $k_value);
|
||||
$k_value = explode('<br />', $k_value);
|
||||
}
|
||||
|
||||
if ($v['req'] == 2) {
|
||||
@ -386,6 +445,9 @@ require_once(HESK_PATH . 'inc/show_admin_nav.inc.php');
|
||||
|
||||
echo '<div class="radio"><label><input type="radio" name="' . $k . '" value="' . $option . '" ' . $checked . ' ' . $required_attribute . '> ' . $option . '</label></div>';
|
||||
}
|
||||
if (!empty($v['mfh_description'])) {
|
||||
echo '<div class="help-block">' . $v['mfh_description'] . '</div>';
|
||||
}
|
||||
echo '<div class="help-block with-errors"></div></div>
|
||||
</div>';
|
||||
|
||||
@ -416,9 +478,11 @@ require_once(HESK_PATH . 'inc/show_admin_nav.inc.php');
|
||||
|
||||
echo '<option ' . $selected . '>' . $option . '</option>';
|
||||
}
|
||||
|
||||
echo '</select>
|
||||
<div class="help-block with-errors"></div>
|
||||
if (!empty($v['mfh_description'])) {
|
||||
echo '<div class="help-block">' . $v['mfh_description'] . '</div>';
|
||||
}
|
||||
echo '</select>';
|
||||
echo '<div class="help-block with-errors"></div>
|
||||
</div>
|
||||
</div>';
|
||||
break;
|
||||
@ -439,6 +503,9 @@ require_once(HESK_PATH . 'inc/show_admin_nav.inc.php');
|
||||
|
||||
echo '<div class="checkbox"><label><input type="checkbox" name="' . $k . '[]" value="' . $option . '" ' . $checked . ' ' . $required_attribute . '> ' . $option . '</label></div>';
|
||||
}
|
||||
if (!empty($v['mfh_description'])) {
|
||||
echo '<div class="help-block">' . $v['mfh_description'] . '</div>';
|
||||
}
|
||||
echo '<div class="help-block with-errors"></div>
|
||||
</div>
|
||||
</div>';
|
||||
@ -453,8 +520,11 @@ require_once(HESK_PATH . 'inc/show_admin_nav.inc.php');
|
||||
<div class="form-group' . $cls . '">
|
||||
<label for="' . $k . '" class="col-sm-3 control-label">' . $v['name'] . ' ' . $v['req'] . '</label>
|
||||
<div class="col-sm-9">
|
||||
<textarea name="' . $k . '" class="form-control" rows="' . intval($v['value']['rows']) . '" cols="' . intval($v['value']['cols']) . '" ' . $required_attribute . '>' . $k_value . '</textarea>
|
||||
<div class="help-block with-errors"></div>
|
||||
<textarea name="' . $k . '" class="form-control" rows="' . intval($v['value']['rows']) . '" cols="' . intval($v['value']['cols']) . '" ' . $required_attribute . '>' . $k_value . '</textarea>';
|
||||
if (!empty($v['mfh_description'])) {
|
||||
echo '<div class="help-block">' . $v['mfh_description'] . '</div>';
|
||||
}
|
||||
echo '<div class="help-block with-errors"></div>
|
||||
</div>
|
||||
</div>';
|
||||
break;
|
||||
@ -473,8 +543,11 @@ require_once(HESK_PATH . 'inc/show_admin_nav.inc.php');
|
||||
<div class="form-group' . $cls . '">
|
||||
<label for="' . $k . '" class="col-sm-3 control-label">' . $v['name'] . ' ' . $v['req'] . '</label>
|
||||
<div class="col-sm-9">
|
||||
<input type="text" name="' . $k . '" value="' . $k_value . '" class="datepicker form-control" size="10" ' . $required_attribute . '>
|
||||
<div class="help-block with-errors"></div>
|
||||
<input type="text" name="' . $k . '" value="' . $k_value . '" class="datepicker form-control" size="10" ' . $required_attribute . '>';
|
||||
if (!empty($v['mfh_description'])) {
|
||||
echo '<div class="help-block">' . $v['mfh_description'] . '</div>';
|
||||
}
|
||||
echo '<div class="help-block with-errors"></div>
|
||||
</div>
|
||||
</div>';
|
||||
break;
|
||||
@ -489,8 +562,11 @@ require_once(HESK_PATH . 'inc/show_admin_nav.inc.php');
|
||||
<div class="form-group' . $cls . '">
|
||||
<label for="' . $k . '" class="col-sm-3 control-label">' . $v['name'] . ' ' . $v['req'] . '</label>
|
||||
<div class="col-sm-9">
|
||||
<input class="form-control" type="text" name="' . $k . '" id="' . $k . '" value="' . $k_value . '" size="40" ' . $suggest . ' ' . $required_attribute . '>
|
||||
<div class="help-block with-errors"></div>
|
||||
<input class="form-control" type="text" name="' . $k . '" id="' . $k . '" value="' . $k_value . '" size="40" ' . $suggest . ' ' . $required_attribute . '>';
|
||||
if (!empty($v['mfh_description'])) {
|
||||
echo '<div class="help-block">' . $v['mfh_description'] . '</div>';
|
||||
}
|
||||
echo '<div class="help-block with-errors"></div>
|
||||
</div>
|
||||
<div id="' . $k . '_suggestions"></div>
|
||||
</div>
|
||||
@ -501,9 +577,7 @@ require_once(HESK_PATH . 'inc/show_admin_nav.inc.php');
|
||||
case 'hidden':
|
||||
case 'readonly':
|
||||
default:
|
||||
if (strlen($k_value) != 0) {
|
||||
$v['value']['default_value'] = $k_value;
|
||||
}
|
||||
$k_value = hesk_msgToPlain($k_value,0,0);
|
||||
|
||||
$cls = in_array($k, $_SESSION['iserror']) ? ' isError' : '';
|
||||
|
||||
@ -511,8 +585,11 @@ require_once(HESK_PATH . 'inc/show_admin_nav.inc.php');
|
||||
<div class="form-group' . $cls . '">
|
||||
<label for="' . $k . '" class="col-sm-3 control-label">' . $v['name'] . ' ' . $v['req'] . '</label>
|
||||
<div class="col-sm-9">
|
||||
<input type="text" class="form-control" name="' . $k . '" size="40" maxlength="' . intval($v['value']['max_length']) . '" value="' . $v['value']['default_value'] . '" ' . $required_attribute . '>
|
||||
<div class="help-block with-errors"></div>
|
||||
<input type="text" class="form-control" name="' . $k . '" size="40" maxlength="' . intval($v['value']['max_length']) . '" value="' . $k_value . '" ' . $required_attribute . '>';
|
||||
if (!empty($v['mfh_description'])) {
|
||||
echo '<div class="help-block">' . $v['mfh_description'] . '</div>';
|
||||
}
|
||||
echo '<div class="help-block with-errors"></div>
|
||||
</div>
|
||||
</div>
|
||||
';
|
||||
@ -542,6 +619,19 @@ require_once(HESK_PATH . 'inc/show_admin_nav.inc.php');
|
||||
<div class="help-block with-errors" id="message-help-block"></div>
|
||||
</div>
|
||||
</div>
|
||||
<?php if ($hesk_settings['attachments']['use'] && $number_of_attachments < $hesk_settings['attachments']['max_number']) : ?>
|
||||
<div class="form-group">
|
||||
<label for="attachments" class="control-label col-sm-3"><?php echo $hesklang['attachments']; ?>:</label>
|
||||
|
||||
<div class="col-sm-9">
|
||||
<?php build_dropzone_markup(true, 'filedrop', $number_of_attachments + 1); ?>
|
||||
</div>
|
||||
</div>
|
||||
<?php
|
||||
display_dropzone_field(HESK_PATH . 'internal-api/ticket/upload-attachment.php',
|
||||
'filedrop',
|
||||
$hesk_settings['attachments']['max_number'] - $number_of_attachments);
|
||||
endif; ?>
|
||||
<div class="form-group">
|
||||
<input type="hidden" name="save" value="1">
|
||||
<input type="hidden" name="track" value="<?php echo $trackingID; ?>">
|
||||
@ -554,16 +644,20 @@ require_once(HESK_PATH . 'inc/show_admin_nav.inc.php');
|
||||
}
|
||||
?>
|
||||
</div>
|
||||
<div class="form-group" style="text-align: center">
|
||||
<div class="form-group">
|
||||
<div class="col-md-9 col-md-offset-3">
|
||||
<?php
|
||||
$html = $ticket['html'] ? 1 : 0;
|
||||
?>
|
||||
<input type="hidden" name="html" value="<?php echo $html; ?>">
|
||||
<input type="submit" value="<?php echo $hesklang['save_changes']; ?>" class="btn btn-default">
|
||||
<div class="btn-group">
|
||||
<input type="submit" value="<?php echo $hesklang['save_changes']; ?>" class="btn btn-primary">
|
||||
<a class="btn btn-default" href="javascript:history.go(-1)"><?php echo $hesklang['back']; ?></a>
|
||||
</div>
|
||||
<?php if (isset($_REQUEST['isManager']) && $_REQUEST['isManager']): ?>
|
||||
<input type="hidden" name="isManager" value="1">
|
||||
<?php endif; ?>
|
||||
<a class="btn btn-default" href="javascript:history.go(-1)"><?php echo $hesklang['back']; ?></a>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
@ -574,21 +668,15 @@ require_once(HESK_PATH . 'inc/show_admin_nav.inc.php');
|
||||
<?php if ($ticket['html']): ?>
|
||||
<script type="text/javascript">
|
||||
/* <![CDATA[ */
|
||||
tinyMCE.init({
|
||||
mode: "textareas",
|
||||
editor_selector: "htmlEditor",
|
||||
elements: "content",
|
||||
theme: "advanced",
|
||||
convert_urls: false,
|
||||
|
||||
theme_advanced_buttons1: "cut,copy,paste,|,undo,redo,|,formatselect,fontselect,fontsizeselect,|,bold,italic,underline,strikethrough,|,justifyleft,justifycenter,justifyright,justifyfull",
|
||||
theme_advanced_buttons2: "sub,sup,|,charmap,|,bullist,numlist,|,outdent,indent,insertdate,inserttime,preview,|,forecolor,backcolor,|,hr,removeformat,visualaid,|,link,unlink,anchor,image,cleanup,code",
|
||||
theme_advanced_buttons3: "",
|
||||
|
||||
theme_advanced_toolbar_location: "top",
|
||||
theme_advanced_toolbar_align: "left",
|
||||
theme_advanced_statusbar_location: "bottom",
|
||||
theme_advanced_resizing: true
|
||||
$(document).ready(function() {
|
||||
$('.htmlEditor').summernote({
|
||||
height: 200,
|
||||
toolbar: [
|
||||
['style', ['bold', 'italic', 'underline', 'clear']],
|
||||
['font', ['strikethrough', 'superscript', 'subscript']],
|
||||
['para', ['ul', 'ol']]
|
||||
]
|
||||
});
|
||||
});
|
||||
/* ]]> */
|
||||
</script>
|
||||
@ -598,3 +686,14 @@ require_once(HESK_PATH . 'inc/show_admin_nav.inc.php');
|
||||
<?php
|
||||
require_once(HESK_PATH . 'inc/footer.inc.php');
|
||||
exit();
|
||||
|
||||
function hesk_countAttachments($attachments_string) {
|
||||
if ( ! strlen($attachments_string) || strpos($attachments_string, ',') === false) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
$att = explode(',', substr($attachments_string, 0, -1));
|
||||
|
||||
return count($att);
|
||||
|
||||
} // END hesk_countAttachments()
|
||||
|
347
admin/export.php
347
admin/export.php
@ -37,7 +37,7 @@ $modsForHesk_settings = mfh_getSettings();
|
||||
$delete = hesk_GET('delete');
|
||||
if (strlen($delete) && preg_match('/^hesk_export_[0-9_\-]+$/', $delete)) {
|
||||
hesk_unlink(HESK_PATH.$hesk_settings['cache_dir'].'/'.$delete.'.zip');
|
||||
hesk_process_messages($hesklang['fd'], 'export.php','SUCCESS');
|
||||
hesk_process_messages($hesklang['fd'], hesk_verifyGoto(),'SUCCESS');
|
||||
}
|
||||
|
||||
// Set default values
|
||||
@ -291,350 +291,15 @@ $orderBy = $modsForHesk_settings['category_order_column'];
|
||||
$res2 = hesk_dbQuery("SELECT `id`, `name` FROM `" . hesk_dbEscape($hesk_settings['db_pfix']) . "categories` WHERE " . hesk_myCategories('id') . " ORDER BY `" . $orderBy . "` ASC");
|
||||
while ($row = hesk_dbFetchAssoc($res2)) {
|
||||
$my_cat[$row['id']] = hesk_msgToPlain($row['name'], 1);
|
||||
$row['name'] = (strlen($row['name']) > 50) ? substr($row['name'], 0, 50) . '...' : $row['name'];
|
||||
$row['name'] = (hesk_mb_strlen($row['name']) > 50) ? hesk_mb_substr($row['name'],0,50) . '...' : $row['name'];
|
||||
$cat_selected = ($row['id'] == $category) ? 'selected="selected"' : '';
|
||||
$category_options .= '<option value="' . $row['id'] . '" ' . $cat_selected . '>' . $row['name'] . '</option>';
|
||||
}
|
||||
|
||||
// Generate export file
|
||||
if (isset($_GET['w'])) {
|
||||
// We'll need HH:MM:SS format for hesk_date() here
|
||||
$hesk_settings['timeformat'] = 'H:i:s';
|
||||
|
||||
// Get staff names
|
||||
$admins = array();
|
||||
$result = hesk_dbQuery("SELECT `id`,`name` FROM `" . hesk_dbEscape($hesk_settings['db_pfix']) . "users` ORDER BY `name` ASC");
|
||||
while ($row = hesk_dbFetchAssoc($result)) {
|
||||
$admins[$row['id']] = $row['name'];
|
||||
}
|
||||
|
||||
// This will be the export directory
|
||||
$export_dir = HESK_PATH.$hesk_settings['cache_dir'].'/';
|
||||
|
||||
// This will be the name of the export and the XML file
|
||||
$export_name = 'hesk_export_' . date('Y-m-d_H-i-s') . '_' . mt_rand(10000, 99999);
|
||||
$save_to = $export_dir . $export_name . '.xml';
|
||||
|
||||
// Do we have the export directory?
|
||||
if (is_dir($export_dir) || (@mkdir($export_dir, 0777) && is_writable($export_dir))) {
|
||||
// Is there an index.htm file?
|
||||
if (!file_exists($export_dir.'index.htm')) {
|
||||
@file_put_contents($export_dir.'index.htm', '');
|
||||
}
|
||||
|
||||
// Cleanup old files
|
||||
hesk_purge_cache('export', 86400);
|
||||
} else {
|
||||
hesk_error($hesklang['ede']);
|
||||
}
|
||||
|
||||
// Make sure the file can be saved and written to
|
||||
@file_put_contents($save_to, '');
|
||||
if (!file_exists($save_to)) {
|
||||
hesk_error($hesklang['eef']);
|
||||
}
|
||||
|
||||
// Start generating the report message and generating the export
|
||||
$success_msg = '';
|
||||
$flush_me = '<br /><br />';
|
||||
$flush_me .= hesk_date() . " | {$hesklang['inite']} ";
|
||||
|
||||
if ($date_from == $date_to) {
|
||||
$flush_me .= "(" . hesk_dateToString($date_from, 0) . ")<br />\n";
|
||||
} else {
|
||||
$flush_me .= "(" . hesk_dateToString($date_from, 0) . " - " . hesk_dateToString($date_to, 0) . ")<br />\n";
|
||||
}
|
||||
|
||||
// Start generating file contents
|
||||
$tmp = '<?xml version="1.0" encoding="UTF-8"?>
|
||||
<?mso-application progid="Excel.Sheet"?>
|
||||
<Workbook xmlns="urn:schemas-microsoft-com:office:spreadsheet"
|
||||
xmlns:o="urn:schemas-microsoft-com:office:office"
|
||||
xmlns:x="urn:schemas-microsoft-com:office:excel"
|
||||
xmlns:ss="urn:schemas-microsoft-com:office:spreadsheet"
|
||||
xmlns:html="http://www.w3.org/TR/REC-html40">
|
||||
<OfficeDocumentSettings xmlns="urn:schemas-microsoft-com:office:office">
|
||||
<AllowPNG/>
|
||||
</OfficeDocumentSettings>
|
||||
<ExcelWorkbook xmlns="urn:schemas-microsoft-com:office:excel">
|
||||
<WindowHeight>8250</WindowHeight>
|
||||
<WindowWidth>16275</WindowWidth>
|
||||
<WindowTopX>360</WindowTopX>
|
||||
<WindowTopY>90</WindowTopY>
|
||||
<ProtectStructure>False</ProtectStructure>
|
||||
<ProtectWindows>False</ProtectWindows>
|
||||
</ExcelWorkbook>
|
||||
<Styles>
|
||||
<Style ss:ID="Default" ss:Name="Normal">
|
||||
<Alignment ss:Vertical="Bottom"/>
|
||||
<Borders/>
|
||||
<Font ss:FontName="Calibri" x:CharSet="238" x:Family="Swiss" ss:Size="11"
|
||||
ss:Color="#000000"/>
|
||||
<Interior/>
|
||||
<NumberFormat/>
|
||||
<Protection/>
|
||||
</Style>
|
||||
<Style ss:ID="s62">
|
||||
<NumberFormat ss:Format="General Date"/>
|
||||
</Style>
|
||||
<Style ss:ID="s63">
|
||||
<NumberFormat ss:Format="Short Date"/>
|
||||
</Style>
|
||||
<Style ss:ID="s65">
|
||||
<NumberFormat ss:Format="[h]:mm:ss"/>
|
||||
</Style>
|
||||
</Styles>
|
||||
<Worksheet ss:Name="Sheet1">
|
||||
<Table>
|
||||
';
|
||||
|
||||
// Define column width
|
||||
$tmp .= '
|
||||
<Column ss:AutoFitWidth="0" ss:Width="50"/>
|
||||
<Column ss:AutoFitWidth="0" ss:Width="84" ss:Span="1"/>
|
||||
<Column ss:AutoFitWidth="0" ss:Width="110"/>
|
||||
<Column ss:AutoFitWidth="0" ss:Width="110"/>
|
||||
<Column ss:AutoFitWidth="0" ss:Width="90"/>
|
||||
<Column ss:AutoFitWidth="0" ss:Width="90"/>
|
||||
<Column ss:AutoFitWidth="0" ss:Width="87"/>
|
||||
<Column ss:AutoFitWidth="0" ss:Width="57.75"/>
|
||||
<Column ss:AutoFitWidth="0" ss:Width="57.75"/>
|
||||
<Column ss:AutoFitWidth="0" ss:Width="100"/>
|
||||
<Column ss:AutoFitWidth="0" ss:Width="100"/>
|
||||
<Column ss:AutoFitWidth="0" ss:Width="80"/>
|
||||
<Column ss:AutoFitWidth="0" ss:Width="80"/>
|
||||
';
|
||||
|
||||
foreach ($hesk_settings['custom_fields'] as $k => $v) {
|
||||
if ($v['use']) {
|
||||
$tmp .= '<Column ss:AutoFitWidth="0" ss:Width="80"/>' . "\n";
|
||||
}
|
||||
}
|
||||
|
||||
// Define first row (header)
|
||||
$tmp .= '
|
||||
<Row>
|
||||
<Cell><Data ss:Type="String">#</Data></Cell>
|
||||
<Cell><Data ss:Type="String">' . $hesklang['trackID'] . '</Data></Cell>
|
||||
<Cell><Data ss:Type="String">' . $hesklang['date'] . '</Data></Cell>
|
||||
<Cell><Data ss:Type="String">' . $hesklang['last_update'] . '</Data></Cell>
|
||||
<Cell><Data ss:Type="String">' . $hesklang['name'] . '</Data></Cell>
|
||||
<Cell><Data ss:Type="String">' . $hesklang['email'] . '</Data></Cell>
|
||||
<Cell><Data ss:Type="String">' . $hesklang['category'] . '</Data></Cell>
|
||||
<Cell><Data ss:Type="String">' . $hesklang['priority'] . '</Data></Cell>
|
||||
<Cell><Data ss:Type="String">' . $hesklang['status'] . '</Data></Cell>
|
||||
<Cell><Data ss:Type="String">' . $hesklang['subject'] . '</Data></Cell>
|
||||
<Cell><Data ss:Type="String">' . $hesklang['message'] . '</Data></Cell>
|
||||
<Cell><Data ss:Type="String">' . $hesklang['owner'] . '</Data></Cell>
|
||||
<Cell><Data ss:Type="String">' . $hesklang['ts'] . '</Data></Cell>
|
||||
';
|
||||
|
||||
foreach ($hesk_settings['custom_fields'] as $k => $v) {
|
||||
if ($v['use']) {
|
||||
$tmp .= '<Cell><Data ss:Type="String">' . $v['name'] . '</Data></Cell>' . "\n";
|
||||
}
|
||||
}
|
||||
|
||||
$tmp .= "</Row>\n";
|
||||
|
||||
// Write what we have by now into the XML file
|
||||
file_put_contents($save_to, $tmp, FILE_APPEND);
|
||||
$flush_me .= hesk_date() . " | {$hesklang['gXML']}<br />\n";
|
||||
|
||||
// OK, now start dumping data and writing it into the file
|
||||
$tickets_exported = 0;
|
||||
$save_after = 100;
|
||||
$this_round = 0;
|
||||
$tmp = '';
|
||||
|
||||
$result = hesk_dbQuery($sql);
|
||||
while ($ticket = hesk_dbFetchAssoc($result)) {
|
||||
$ticket['status'] = mfh_getDisplayTextForStatusId($ticket['status']);
|
||||
|
||||
switch ($ticket['priority']) {
|
||||
case 0:
|
||||
$ticket['priority'] = $hesklang['critical'];
|
||||
break;
|
||||
case 1:
|
||||
$ticket['priority'] = $hesklang['high'];
|
||||
break;
|
||||
case 2:
|
||||
$ticket['priority'] = $hesklang['medium'];
|
||||
break;
|
||||
default:
|
||||
$ticket['priority'] = $hesklang['low'];
|
||||
}
|
||||
|
||||
$ticket['archive'] = !($ticket['archive']) ? $hesklang['no'] : $hesklang['yes'];
|
||||
$ticket['message'] = hesk_msgToPlain($ticket['message'], 1, 0);
|
||||
$ticket['subject'] = hesk_msgToPlain($ticket['subject'], 1, 0);
|
||||
$ticket['owner'] = isset($admins[$ticket['owner']]) ? $admins[$ticket['owner']] : '';
|
||||
$ticket['category'] = isset($my_cat[$ticket['category']]) ? $my_cat[$ticket['category']] : '';
|
||||
|
||||
// Format for export dates
|
||||
$hesk_settings['timeformat'] = "Y-m-d\TH:i:s\.000";
|
||||
|
||||
// Create row for the XML file
|
||||
$tmp .= '
|
||||
<Row>
|
||||
<Cell><Data ss:Type="Number">' . $ticket['id'] . '</Data></Cell>
|
||||
<Cell><Data ss:Type="String"><![CDATA[' . $ticket['trackid'] . ']]></Data></Cell>
|
||||
<Cell ss:StyleID="s62"><Data ss:Type="DateTime">' . hesk_date($ticket['dt'], true) . '</Data></Cell>
|
||||
<Cell ss:StyleID="s62"><Data ss:Type="DateTime">' . hesk_date($ticket['lastchange'], true) . '</Data></Cell>
|
||||
<Cell><Data ss:Type="String"><![CDATA[' . hesk_msgToPlain($ticket['name'], 1) . ']]></Data></Cell>
|
||||
<Cell><Data ss:Type="String"><![CDATA[' . $ticket['email'] . ']]></Data></Cell>
|
||||
<Cell><Data ss:Type="String"><![CDATA[' . $ticket['category'] . ']]></Data></Cell>
|
||||
<Cell><Data ss:Type="String"><![CDATA[' . $ticket['priority'] . ']]></Data></Cell>
|
||||
<Cell><Data ss:Type="String"><![CDATA[' . $ticket['status'] . ']]></Data></Cell>
|
||||
<Cell><Data ss:Type="String"><![CDATA[' . $ticket['subject'] . ']]></Data></Cell>
|
||||
<Cell><Data ss:Type="String"><![CDATA[' . $ticket['message'] . ']]></Data></Cell>
|
||||
<Cell><Data ss:Type="String"><![CDATA[' . $ticket['owner'] . ']]></Data></Cell>
|
||||
<Cell><Data ss:Type="String"><![CDATA[' . $ticket['time_worked'] . ']]></Data></Cell>
|
||||
';
|
||||
|
||||
// Add custom fields
|
||||
foreach ($hesk_settings['custom_fields'] as $k=>$v) {
|
||||
if ($v['use']) {
|
||||
switch ($v['type']) {
|
||||
case 'date':
|
||||
$tmp_dt = hesk_custom_date_display_format($ticket[$k], 'Y-m-d\T00:00:00.000');
|
||||
$tmp .= strlen($tmp_dt) ? '<Cell ss:StyleID="s63"><Data ss:Type="DateTime">'.$tmp_dt : '<Cell><Data ss:Type="String">';
|
||||
$tmp .= "</Data></Cell> \n";
|
||||
break;
|
||||
default:
|
||||
$tmp .= '<Cell><Data ss:Type="String"><![CDATA['.hesk_msgToPlain($ticket[$k], 1, 0).']]></Data></Cell> ' . "\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$tmp .= "</Row>\n";
|
||||
|
||||
// Write every 100 rows into the file
|
||||
if ($this_round >= $save_after) {
|
||||
file_put_contents($save_to, $tmp, FILE_APPEND);
|
||||
$this_round = 0;
|
||||
$tmp = '';
|
||||
usleep(1);
|
||||
}
|
||||
|
||||
$tickets_exported++;
|
||||
$this_round++;
|
||||
} // End of while loop
|
||||
|
||||
// Go back to the HH:MM:SS format for hesk_date()
|
||||
$hesk_settings['timeformat'] = 'H:i:s';
|
||||
|
||||
// Append any remaining rows into the file
|
||||
if ($this_round > 0) {
|
||||
file_put_contents($save_to, $tmp, FILE_APPEND);
|
||||
}
|
||||
|
||||
// If any tickets were exported, continue, otherwise cleanup
|
||||
if ($tickets_exported > 0) {
|
||||
// Finish the XML file
|
||||
$tmp = '
|
||||
</Table>
|
||||
<WorksheetOptions xmlns="urn:schemas-microsoft-com:office:excel">
|
||||
<PageSetup>
|
||||
<Header x:Margin="0.3"/>
|
||||
<Footer x:Margin="0.3"/>
|
||||
<PageMargins x:Bottom="0.75" x:Left="0.7" x:Right="0.7" x:Top="0.75"/>
|
||||
</PageSetup>
|
||||
<Selected/>
|
||||
<Panes>
|
||||
<Pane>
|
||||
<Number>3</Number>
|
||||
<ActiveRow>4</ActiveRow>
|
||||
</Pane>
|
||||
</Panes>
|
||||
<ProtectObjects>False</ProtectObjects>
|
||||
<ProtectScenarios>False</ProtectScenarios>
|
||||
</WorksheetOptions>
|
||||
</Worksheet>
|
||||
<Worksheet ss:Name="Sheet2">
|
||||
<Table ss:ExpandedColumnCount="1" ss:ExpandedRowCount="1" x:FullColumns="1"
|
||||
x:FullRows="1" ss:DefaultRowHeight="15">
|
||||
</Table>
|
||||
<WorksheetOptions xmlns="urn:schemas-microsoft-com:office:excel">
|
||||
<PageSetup>
|
||||
<Header x:Margin="0.3"/>
|
||||
<Footer x:Margin="0.3"/>
|
||||
<PageMargins x:Bottom="0.75" x:Left="0.7" x:Right="0.7" x:Top="0.75"/>
|
||||
</PageSetup>
|
||||
<ProtectObjects>False</ProtectObjects>
|
||||
<ProtectScenarios>False</ProtectScenarios>
|
||||
</WorksheetOptions>
|
||||
</Worksheet>
|
||||
<Worksheet ss:Name="Sheet3">
|
||||
<Table ss:ExpandedColumnCount="1" ss:ExpandedRowCount="1" x:FullColumns="1"
|
||||
x:FullRows="1" ss:DefaultRowHeight="15">
|
||||
</Table>
|
||||
<WorksheetOptions xmlns="urn:schemas-microsoft-com:office:excel">
|
||||
<PageSetup>
|
||||
<Header x:Margin="0.3"/>
|
||||
<Footer x:Margin="0.3"/>
|
||||
<PageMargins x:Bottom="0.75" x:Left="0.7" x:Right="0.7" x:Top="0.75"/>
|
||||
</PageSetup>
|
||||
<ProtectObjects>False</ProtectObjects>
|
||||
<ProtectScenarios>False</ProtectScenarios>
|
||||
</WorksheetOptions>
|
||||
</Worksheet>
|
||||
</Workbook>
|
||||
';
|
||||
file_put_contents($save_to, $tmp, FILE_APPEND);
|
||||
|
||||
// Log how many rows we exported
|
||||
$flush_me .= hesk_date() . " | " . sprintf($hesklang['nrow'], $tickets_exported) . "<br />\n";
|
||||
|
||||
// We will convert XML to Zip to save a lot of space
|
||||
$save_to_zip = $export_dir . $export_name . '.zip';
|
||||
|
||||
// Log start of Zip creation
|
||||
$flush_me .= hesk_date() . " | {$hesklang['cZIP']}<br />\n";
|
||||
|
||||
// Preferrably use the zip extension
|
||||
if (extension_loaded('zip')) {
|
||||
$save_to_zip = $export_dir . $export_name . '.zip';
|
||||
|
||||
$zip = new ZipArchive;
|
||||
$res = $zip->open($save_to_zip, ZipArchive::CREATE);
|
||||
if ($res === TRUE) {
|
||||
$zip->addFile($save_to, "{$export_name}.xml");
|
||||
$zip->close();
|
||||
} else {
|
||||
die("{$hesklang['eZIP']} <$save_to_zip>\n");
|
||||
}
|
||||
|
||||
} // Some servers have ZipArchive class enabled anyway - can we use it?
|
||||
elseif (class_exists('ZipArchive')) {
|
||||
require(HESK_PATH . 'inc/zip/Zip.php');
|
||||
$zip = new Zip();
|
||||
$zip->addLargeFile($save_to, "{$export_name}.xml");
|
||||
$zip->finalize();
|
||||
$zip->setZipFile($save_to_zip);
|
||||
} // If not available, use a 3rd party Zip class included with HESK
|
||||
else {
|
||||
require(HESK_PATH . 'inc/zip/pclzip.lib.php');
|
||||
$zip = new PclZip($save_to_zip);
|
||||
$zip->add($save_to, PCLZIP_OPT_REMOVE_ALL_PATH);
|
||||
}
|
||||
|
||||
// Delete XML, just leave the Zip archive
|
||||
hesk_unlink($save_to);
|
||||
|
||||
// Echo memory peak usage
|
||||
$flush_me .= hesk_date() . " | " . sprintf($hesklang['pmem'], (@memory_get_peak_usage(true) / 1048576)) . "<br />\r\n";
|
||||
|
||||
// We're done!
|
||||
$flush_me .= hesk_date() . " | {$hesklang['fZIP']}<br /><br />";
|
||||
|
||||
// Success message
|
||||
$success_msg .= $hesk_settings['debug_mode'] ? $flush_me : '<br /><br />';
|
||||
$success_msg .= $hesklang['step1'] . ': <a href="' . $save_to_zip . '">' . $hesklang['ch2d'] . '</a><br /><br />' . $hesklang['step2'] . ': <a href="export.php?delete='.urlencode($export_name).'">' . $hesklang['dffs'] . '</a>';
|
||||
} // No tickets exported, cleanup
|
||||
else {
|
||||
hesk_unlink($save_to);
|
||||
}
|
||||
require_once(HESK_PATH . 'inc/export_functions.inc.php');
|
||||
list($success_msg, $tickets_exported) = hesk_export_to_XML($sql);
|
||||
}
|
||||
|
||||
/* Print header */
|
||||
@ -697,7 +362,7 @@ require_once(HESK_PATH . 'inc/show_admin_nav.inc.php');
|
||||
(<?php echo $hesklang['m' . date('n')]; ?>)
|
||||
</option>
|
||||
<option value="4" <?php echo $selected['time'][4]; ?>><?php echo $hesklang['r4']; ?>
|
||||
(<?php echo $hesklang['m' . date('n', mktime(0, 0, 0, date('m') - 1, date('d'), date('Y')))]; ?>
|
||||
(<?php echo $hesklang['m' . date('n', mktime(0, 0, 0, date('m') - 1, 1, date('Y')))]; ?>
|
||||
)
|
||||
</option>
|
||||
<option value="5" <?php echo $selected['time'][5]; ?>><?php echo $hesklang['r5']; ?></option>
|
||||
@ -894,7 +559,7 @@ require_once(HESK_PATH . 'inc/show_admin_nav.inc.php');
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<input type="submit" value="<?php echo $hesklang['export_btn']; ?>" class="btn btn-default"/>
|
||||
<input type="submit" id="export" value="<?php echo $hesklang['export_btn']; ?>" class="btn btn-default"/>
|
||||
<input type="hidden" name="cot" value="1"/>
|
||||
</div>
|
||||
</form>
|
||||
|
54
admin/export_ticket.php
Normal file
54
admin/export_ticket.php
Normal file
@ -0,0 +1,54 @@
|
||||
<?php
|
||||
/**
|
||||
*
|
||||
* This file is part of HESK - PHP Help Desk Software.
|
||||
*
|
||||
* (c) Copyright Klemen Stirn. All rights reserved.
|
||||
* https://www.hesk.com
|
||||
*
|
||||
* For the full copyright and license agreement information visit
|
||||
* https://www.hesk.com/eula.php
|
||||
*
|
||||
*/
|
||||
|
||||
define('IN_SCRIPT',1);
|
||||
define('HESK_PATH','../');
|
||||
|
||||
/* Get all the required files and functions */
|
||||
require(HESK_PATH . 'hesk_settings.inc.php');
|
||||
require(HESK_PATH . 'inc/common.inc.php');
|
||||
require(HESK_PATH . 'inc/admin_functions.inc.php');
|
||||
require(HESK_PATH . 'inc/privacy_functions.inc.php');
|
||||
hesk_load_database_functions();
|
||||
|
||||
hesk_session_start();
|
||||
hesk_dbConnect();
|
||||
hesk_isLoggedIn();
|
||||
|
||||
// Check permissions for this feature
|
||||
hesk_checkPermission('can_export');
|
||||
|
||||
// A security check
|
||||
hesk_token_check();
|
||||
|
||||
// Tracking ID
|
||||
$trackingID = hesk_cleanID() or die($hesklang['int_error'].': '.$hesklang['no_trackID']);
|
||||
|
||||
// Generate SQL for the ticket, make sure the user has access to it
|
||||
$sql = "SELECT * FROM `".hesk_dbEscape($hesk_settings['db_pfix'])."tickets` WHERE `trackid`='".hesk_dbEscape($trackingID)."' AND ";
|
||||
$sql .= hesk_myCategories();
|
||||
$sql .= " AND " . hesk_myOwnership();
|
||||
$sql .= " LIMIT 1";
|
||||
|
||||
require_once(HESK_PATH . 'inc/custom_fields.inc.php');
|
||||
require_once(HESK_PATH . 'inc/statuses.inc.php');
|
||||
require(HESK_PATH . 'inc/export_functions.inc.php');
|
||||
|
||||
list($success_msg, $tickets_exported) = hesk_export_to_XML($sql, true);
|
||||
|
||||
if ($tickets_exported == 1)
|
||||
{
|
||||
hesk_process_messages($success_msg,'admin_ticket.php?track='.$trackingID.'&Refresh='.mt_rand(10000,99999),'SUCCESS');
|
||||
}
|
||||
|
||||
hesk_error($hesklang['n2ex']);
|
@ -145,21 +145,21 @@ LEFT(`message`, 400) AS `message`,
|
||||
$sql .= " ( `trackid` = '" . hesk_dbEscape($q) . "' OR `merged` LIKE '%#" . hesk_dbEscape($q) . "#%' ) ";
|
||||
break;
|
||||
case 'name':
|
||||
$sql .= "`name` LIKE '%" . hesk_dbEscape($q) . "%' COLLATE '" . hesk_dbEscape($hesklang['_COLLATE']) . "' ";
|
||||
$sql .= "`name` LIKE '%".hesk_dbEscape( hesk_dbLike($q) )."%' COLLATE '" . hesk_dbCollate() . "' ";
|
||||
break;
|
||||
case 'email':
|
||||
$sql .= "`email` LIKE '%" . hesk_dbEscape($q) . "%' ";
|
||||
break;
|
||||
case 'subject':
|
||||
$sql .= "`subject` LIKE '%" . hesk_dbEscape($q) . "%' COLLATE '" . hesk_dbEscape($hesklang['_COLLATE']) . "' ";
|
||||
$sql .= "`subject` LIKE '%".hesk_dbEscape( hesk_dbLike($q) )."%' COLLATE '" . hesk_dbCollate() . "' ";
|
||||
break;
|
||||
case 'message':
|
||||
$sql .= " ( `message` LIKE '%" . hesk_dbEscape($q) . "%' COLLATE '" . hesk_dbEscape($hesklang['_COLLATE']) . "'
|
||||
$sql .= " ( `message` LIKE '%".hesk_dbEscape( hesk_dbLike($q) )."%' COLLATE '" . hesk_dbCollate() . "'
|
||||
OR
|
||||
`id` IN (
|
||||
SELECT DISTINCT `replyto`
|
||||
FROM `" . hesk_dbEscape($hesk_settings['db_pfix']) . "replies`
|
||||
WHERE `message` LIKE '%" . hesk_dbEscape($q) . "%' COLLATE '" . hesk_dbEscape($hesklang['_COLLATE']) . "' )
|
||||
WHERE `message` LIKE '%".hesk_dbEscape( hesk_dbLike($q) )."%' COLLATE '" . hesk_dbCollate() . "' )
|
||||
)
|
||||
";
|
||||
break;
|
||||
@ -170,12 +170,15 @@ LEFT(`message`, 400) AS `message`,
|
||||
$sql .= "`id` IN (
|
||||
SELECT DISTINCT `ticket`
|
||||
FROM `" . hesk_dbEscape($hesk_settings['db_pfix']) . "notes`
|
||||
WHERE `message` LIKE '%" . hesk_dbEscape($q) . "%' COLLATE '" . hesk_dbEscape($hesklang['_COLLATE']) . "' )
|
||||
WHERE `message` LIKE '%".hesk_dbEscape( hesk_dbLike($q) )."%' COLLATE '" . hesk_dbCollate() . "' )
|
||||
";
|
||||
break;
|
||||
case 'ip':
|
||||
$sql .= "`ip` LIKE '".preg_replace('/[^0-9\.\%]/', '', $q)."' ";
|
||||
break;
|
||||
default:
|
||||
if (isset($hesk_settings['custom_fields'][$what]) && $hesk_settings['custom_fields'][$what]['use']) {
|
||||
$sql .= "`" . hesk_dbEscape($what) . "` LIKE '%" . hesk_dbEscape($q) . "%' COLLATE '" . hesk_dbEscape($hesklang['_COLLATE']) . "' ";
|
||||
$sql .= "`" . hesk_dbEscape($what) . "` LIKE '%" . hesk_dbEscape($q) . "%' COLLATE '" . hesk_dbCollate() . "' ";
|
||||
} else {
|
||||
$hesk_error_buffer .= '<br />' . $hesklang['invalid_search'];
|
||||
}
|
||||
@ -220,6 +223,9 @@ LEFT(`message`, 400) AS `message`,
|
||||
$sql_count .= $sql;
|
||||
$sql = $sql_final . $sql;
|
||||
|
||||
// Strip extra slashes
|
||||
$q = stripslashes($q);
|
||||
|
||||
/* Prepare variables used in search and forms */
|
||||
require_once(HESK_PATH . 'inc/prepare_ticket_search.inc.php');
|
||||
?>
|
||||
|
105
admin/index.php
105
admin/index.php
@ -65,22 +65,7 @@ function do_login()
|
||||
|
||||
if ($hesk_settings['secimg_use'] == 2 && !isset($_SESSION['img_a_verified'])) {
|
||||
// Using ReCaptcha?
|
||||
if ($hesk_settings['recaptcha_use'] == 1) {
|
||||
require_once(HESK_PATH . 'inc/recaptcha/recaptchalib.php');
|
||||
|
||||
$resp = recaptcha_check_answer($hesk_settings['recaptcha_private_key'],
|
||||
$_SERVER['REMOTE_ADDR'],
|
||||
hesk_POST('recaptcha_challenge_field', ''),
|
||||
hesk_POST('recaptcha_response_field', '')
|
||||
);
|
||||
|
||||
if ($resp->is_valid) {
|
||||
$_SESSION['img_a_verified'] = true;
|
||||
} else {
|
||||
$hesk_error_buffer['mysecnum'] = $hesklang['recaptcha_error'];
|
||||
}
|
||||
} // Using ReCaptcha API v2?
|
||||
elseif ($hesk_settings['recaptcha_use'] == 2) {
|
||||
if ($hesk_settings['recaptcha_use']) {
|
||||
require(HESK_PATH . 'inc/recaptcha/recaptchalib_v2.php');
|
||||
|
||||
$resp = null;
|
||||
@ -88,7 +73,7 @@ function do_login()
|
||||
|
||||
// Was there a reCAPTCHA response?
|
||||
if (isset($_POST["g-recaptcha-response"])) {
|
||||
$resp = $reCaptcha->verifyResponse($_SERVER["REMOTE_ADDR"], hesk_POST("g-recaptcha-response"));
|
||||
$resp = $reCaptcha->verifyResponse(hesk_getClientIP(), hesk_POST("g-recaptcha-response"));
|
||||
}
|
||||
|
||||
if ($resp != null && $resp->success) {
|
||||
@ -158,7 +143,7 @@ function do_login()
|
||||
exit();
|
||||
}
|
||||
|
||||
$pass_enc = hesk_Pass2Hash($_SESSION['pass'] . strtolower($user) . $_SESSION['pass']);
|
||||
$pass_enc = hesk_Pass2Hash($_SESSION['pass'].hesk_mb_strtolower($user).$_SESSION['pass']);
|
||||
|
||||
/* Check if default password */
|
||||
if ($_SESSION['pass'] == '499d74967b28a841c98bb4baaabaad699ff3c079') {
|
||||
@ -202,7 +187,6 @@ function do_login()
|
||||
|
||||
/* Close any old tickets here so Cron jobs aren't necessary */
|
||||
if ($hesk_settings['autoclose']) {
|
||||
$revision = sprintf($hesklang['thist3'], hesk_date(), $hesklang['auto']);
|
||||
$dt = date('Y-m-d H:i:s', time() - $hesk_settings['autoclose'] * 86400);
|
||||
|
||||
|
||||
@ -210,9 +194,7 @@ function do_login()
|
||||
$closedStatus = hesk_dbFetchAssoc($closedStatusRs);
|
||||
// Are we allowed to close tickets in this status?
|
||||
if ($closedStatus['Closable'] == 'yes' || $closedStatus['Closable'] == 'sonly') {
|
||||
// Notify customer of closed ticket?
|
||||
if ($hesk_settings['notify_closed']) {
|
||||
// Get list of tickets
|
||||
|
||||
$result = hesk_dbQuery("SELECT * FROM `" . $hesk_settings['db_pfix'] . "tickets` WHERE `status` = " . $closedStatus['ID'] . " AND `lastchange` <= '" . hesk_dbEscape($dt) . "' ");
|
||||
if (hesk_dbNumRows($result) > 0) {
|
||||
global $ticket;
|
||||
@ -226,6 +208,11 @@ function do_login()
|
||||
$ticket['dt'] = hesk_date($ticket['dt'], true);
|
||||
$ticket['lastchange'] = hesk_date($ticket['lastchange'], true);
|
||||
$ticket = hesk_ticketToPlain($ticket, 1, 0);
|
||||
mfh_insert_audit_trail_record($ticket['id'], 'TICKET', 'audit_automatically_closed', hesk_date(), array());
|
||||
|
||||
// Notify customer of closed ticket?
|
||||
if ($hesk_settings['notify_closed']) {
|
||||
// Get list of tickets
|
||||
hesk_notifyCustomer($modsForHesk_settings, 'ticket_closed');
|
||||
}
|
||||
}
|
||||
@ -234,7 +221,7 @@ function do_login()
|
||||
// Update ticket statuses and history in database if we're allowed to do so
|
||||
$defaultCloseRs = hesk_dbQuery('SELECT `ID` FROM `' . hesk_dbEscape($hesk_settings['db_pfix']) . 'statuses` WHERE `IsAutocloseOption` = 1');
|
||||
$defaultCloseStatus = hesk_dbFetchAssoc($defaultCloseRs);
|
||||
hesk_dbQuery("UPDATE `" . $hesk_settings['db_pfix'] . "tickets` SET `status`=" . intval($defaultCloseStatus['ID']) . ", `closedat`=NOW(), `closedby`='-1', `history`=CONCAT(`history`,'" . hesk_dbEscape($revision) . "') WHERE `status` = '" . $closedStatus['ID'] . "' AND `lastchange` <= '" . hesk_dbEscape($dt) . "' ");
|
||||
hesk_dbQuery("UPDATE `" . $hesk_settings['db_pfix'] . "tickets` SET `status`=" . intval($defaultCloseStatus['ID']) . ", `closedat`=NOW(), `closedby`='-1' WHERE `status` = " . $closedStatus['ID'] . " AND `lastchange` <= '" . hesk_dbEscape($dt) . "' ");
|
||||
}
|
||||
}
|
||||
|
||||
@ -246,10 +233,10 @@ function do_login()
|
||||
|
||||
function print_login()
|
||||
{
|
||||
global $hesk_settings, $hesklang;
|
||||
global $hesk_settings, $hesklang, $modsForHesk_settings;
|
||||
|
||||
// Tell header to load reCaptcha API if needed
|
||||
if ($hesk_settings['recaptcha_use'] == 2)
|
||||
if ($hesk_settings['recaptcha_use'])
|
||||
{
|
||||
define('RECAPTCHA',1);
|
||||
}
|
||||
@ -269,20 +256,33 @@ function print_login()
|
||||
|
||||
?>
|
||||
<div class="login-box">
|
||||
<div class="login-logo">
|
||||
<?php echo $hesk_settings['hesk_title']; ?>
|
||||
</div>
|
||||
<div class="login-box-container">
|
||||
<div class="login-box-background"></div>
|
||||
<div class="login-box-body">
|
||||
<div class="loginError">
|
||||
<?php
|
||||
/* This will handle error, success and notice messages */
|
||||
hesk_handle_messages();
|
||||
|
||||
// Service messages
|
||||
$service_messages = mfh_get_service_messages('STAFF_LOGIN');
|
||||
foreach ($service_messages as $sm) {
|
||||
hesk_service_message($sm);
|
||||
}
|
||||
?>
|
||||
</div>
|
||||
<div class="login-logo">
|
||||
<?php if ($modsForHesk_settings['login_box_header'] == 'image'): ?>
|
||||
<img src="<?php echo HESK_PATH . $hesk_settings['cache_dir'] . '/lbh_' . $modsForHesk_settings['login_box_header_image']; ?>"
|
||||
style="height: 75px">
|
||||
<?php else:
|
||||
echo $hesk_settings['hesk_title'];
|
||||
endif; ?>
|
||||
</div>
|
||||
<h4 class="login-box-msg">
|
||||
<?php echo $hesklang['staff_login_title']; ?>
|
||||
</h4>
|
||||
<form class="form-horizontal" role="form" action="index.php" method="post" name="form1">
|
||||
<form class="form-horizontal" role="form" action="index.php" method="post" name="form1" id="form1">
|
||||
<?php
|
||||
$has_error = '';
|
||||
if (in_array('pass',$_SESSION['a_iserror'])) {
|
||||
@ -321,7 +321,7 @@ function print_login()
|
||||
<select class="form-control" name="user">
|
||||
<?php
|
||||
while ($row = hesk_dbFetchAssoc($res)):
|
||||
$sel = (strtolower($savedUser) == strtolower($row['user'])) ? 'selected' : '';
|
||||
$sel = (hesk_mb_strtolower($savedUser) == hesk_mb_strtolower($row['user'])) ? 'selected="selected"' : '';
|
||||
?>
|
||||
<option value="<?php echo $row['user']; ?>" <?php echo $sel; ?>>
|
||||
<?php echo $row['user']; ?>
|
||||
@ -350,7 +350,7 @@ function print_login()
|
||||
</div>
|
||||
</div>
|
||||
<?php
|
||||
if ($hesk_settings['secimg_use'] == 2)
|
||||
if ($hesk_settings['secimg_use'] == 2 && $hesk_settings['recaptcha_use'] != 1)
|
||||
{
|
||||
|
||||
// SPAM prevention verified for this session
|
||||
@ -358,34 +358,6 @@ function print_login()
|
||||
{
|
||||
echo '<img src="'.HESK_PATH.'img/success.png" width="16" height="16" border="0" alt="" style="vertical-align:text-bottom" /> '.$hesklang['vrfy'];
|
||||
}
|
||||
// Not verified yet, should we use Recaptcha?
|
||||
elseif ($hesk_settings['recaptcha_use'] == 1)
|
||||
{
|
||||
?>
|
||||
<script type="text/javascript">
|
||||
var RecaptchaOptions = {
|
||||
theme : '<?php echo ( isset($_SESSION['a_iserror']) && in_array('mysecnum',$_SESSION['a_iserror']) ) ? 'red' : 'white'; ?>',
|
||||
custom_translations : {
|
||||
visual_challenge : "<?php echo hesk_slashJS($hesklang['visual_challenge']); ?>",
|
||||
audio_challenge : "<?php echo hesk_slashJS($hesklang['audio_challenge']); ?>",
|
||||
refresh_btn : "<?php echo hesk_slashJS($hesklang['refresh_btn']); ?>",
|
||||
instructions_visual : "<?php echo hesk_slashJS($hesklang['instructions_visual']); ?>",
|
||||
instructions_context : "<?php echo hesk_slashJS($hesklang['instructions_context']); ?>",
|
||||
instructions_audio : "<?php echo hesk_slashJS($hesklang['instructions_audio']); ?>",
|
||||
help_btn : "<?php echo hesk_slashJS($hesklang['help_btn']); ?>",
|
||||
play_again : "<?php echo hesk_slashJS($hesklang['play_again']); ?>",
|
||||
cant_hear_this : "<?php echo hesk_slashJS($hesklang['cant_hear_this']); ?>",
|
||||
incorrect_try_again : "<?php echo hesk_slashJS($hesklang['incorrect_try_again']); ?>",
|
||||
image_alt_text : "<?php echo hesk_slashJS($hesklang['image_alt_text']); ?>"
|
||||
}
|
||||
};
|
||||
</script>
|
||||
<?php
|
||||
require_once(HESK_PATH . 'inc/recaptcha/recaptchalib.php');
|
||||
echo '<div class="form-group"><div class="col-md-8 col-md-offset-4">';
|
||||
echo recaptcha_get_html($hesk_settings['recaptcha_public_key'], null, true);
|
||||
echo '</div></div>';
|
||||
}
|
||||
// Use reCaptcha API v2?
|
||||
elseif ($hesk_settings['recaptcha_use'] == 2)
|
||||
{
|
||||
@ -443,7 +415,7 @@ function print_login()
|
||||
?>
|
||||
<div class="form-group">
|
||||
<div class="col-md-offset-4 col-md-8">
|
||||
<input type="submit" value="<?php echo $hesklang['click_login']; ?>" class="btn btn-default">
|
||||
<input type="submit" value="<?php echo $hesklang['click_login']; ?>" class="btn btn-default" id="recaptcha-submit">
|
||||
<input type="hidden" name="a" value="do_login">
|
||||
<?php
|
||||
if ( hesk_isREQUEST('goto') && $url=hesk_REQUEST('goto') )
|
||||
@ -459,7 +431,20 @@ function print_login()
|
||||
?>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<?php
|
||||
// Use Invisible reCAPTCHA?
|
||||
if ($hesk_settings['secimg_use'] == 2 && $hesk_settings['recaptcha_use'] == 1 && ! isset($_SESSION['img_a_verified'])) {
|
||||
?>
|
||||
<div class="g-recaptcha" data-sitekey="<?php echo $hesk_settings['recaptcha_public_key']; ?>" data-bind="recaptcha-submit" data-callback="recaptcha_submitForm"></div>
|
||||
<?php
|
||||
}
|
||||
?>
|
||||
</form>
|
||||
<a class="btn btn-default" href="<?php echo $hesk_settings['hesk_url']; ?>">
|
||||
<i class="fa fa-chevron-left"></i> <?php echo $hesklang['back']; ?>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<?php
|
||||
|
@ -1,32 +1,15 @@
|
||||
<?php
|
||||
/*******************************************************************************
|
||||
* Title: Help Desk Software HESK
|
||||
* Version: 2.6.8 from 10th August 2016
|
||||
* Author: Klemen Stirn
|
||||
* Website: https://www.hesk.com
|
||||
********************************************************************************
|
||||
* COPYRIGHT AND TRADEMARK NOTICE
|
||||
* Copyright 2005-2015 Klemen Stirn. All Rights Reserved.
|
||||
* HESK is a registered trademark of Klemen Stirn.
|
||||
* The HESK may be used and modified free of charge by anyone
|
||||
* AS LONG AS COPYRIGHT NOTICES AND ALL THE COMMENTS REMAIN INTACT.
|
||||
* By using this code you agree to indemnify Klemen Stirn from any
|
||||
* liability that might arise from it's use.
|
||||
* Selling the code for this program, in part or full, without prior
|
||||
* written consent is expressly forbidden.
|
||||
* Using this code, in part or full, to create derivate work,
|
||||
* new scripts or products is expressly forbidden. Obtain permission
|
||||
* before redistributing this software over the Internet or in
|
||||
* any other medium. In all cases copyright and header must remain intact.
|
||||
* This Copyright is in full effect in any country that has International
|
||||
* Trade Agreements with the United States of America or
|
||||
* with the European Union.
|
||||
* Removing any of the copyright notices without purchasing a license
|
||||
* is expressly forbidden. To remove HESK copyright notice you must purchase
|
||||
* a license for this script. For more information on how to obtain
|
||||
* a license please visit the page below:
|
||||
* https://www.hesk.com/buy.php
|
||||
*******************************************************************************/
|
||||
/**
|
||||
*
|
||||
* This file is part of HESK - PHP Help Desk Software.
|
||||
*
|
||||
* (c) Copyright Klemen Stirn. All rights reserved.
|
||||
* https://www.hesk.com
|
||||
*
|
||||
* For the full copyright and license agreement information visit
|
||||
* https://www.hesk.com/eula.php
|
||||
*
|
||||
*/
|
||||
|
||||
define('IN_SCRIPT',1);
|
||||
define('HESK_PATH','../');
|
||||
@ -41,9 +24,12 @@ require(HESK_PATH . 'inc/knowledgebase_functions.inc.php');
|
||||
require(HESK_PATH . 'inc/mail_functions.inc.php');
|
||||
hesk_load_database_functions();
|
||||
|
||||
|
||||
hesk_session_start();
|
||||
hesk_dbConnect();
|
||||
hesk_isLoggedIn();
|
||||
hesk_kb_preheader();
|
||||
|
||||
|
||||
/* Is Knowledgebase enabled? */
|
||||
if ( ! $hesk_settings['kb_enable'])
|
||||
@ -109,14 +95,17 @@ exit();
|
||||
|
||||
|
||||
/*** START FUNCTIONS ***/
|
||||
|
||||
function hesk_kb_header($kb_link, $catid=1)
|
||||
{
|
||||
function hesk_kb_preheader() {
|
||||
global $hesk_settings, $hesklang, $can_man_kb;
|
||||
|
||||
/* Print admin navigation */
|
||||
require_once(HESK_PATH . 'inc/headerAdmin.inc.php');
|
||||
require_once(HESK_PATH . 'inc/show_admin_nav.inc.php');
|
||||
}
|
||||
|
||||
function hesk_kb_header($kb_link, $catid=1)
|
||||
{
|
||||
global $hesk_settings, $hesklang, $can_man_kb;
|
||||
?>
|
||||
|
||||
<ol class="breadcrumb">
|
||||
@ -130,12 +119,11 @@ function hesk_kb_header($kb_link, $catid=1)
|
||||
?>
|
||||
<li class="active"><?php echo $kb_link; ?></li>
|
||||
</ol>
|
||||
<?php show_subnav('view', $catid); ?>
|
||||
<section style="padding: 15px;">
|
||||
<?php hesk_kbSearchLarge(1); ?>
|
||||
</section>
|
||||
|
||||
<?php
|
||||
show_subnav('view', $catid);
|
||||
echo '<div style="margin-left:40px;margin-right:40px">';
|
||||
hesk_kbSearchLarge(1);
|
||||
echo '</div>';
|
||||
} // END hesk_kb_header()
|
||||
|
||||
|
||||
@ -143,15 +131,12 @@ function hesk_kb_search($query)
|
||||
{
|
||||
global $hesk_settings, $hesklang;
|
||||
|
||||
define('HESK_NO_ROBOTS',1);
|
||||
|
||||
hesk_kb_header($hesk_settings['kb_link']);
|
||||
|
||||
$res = hesk_dbQuery('SELECT t1.`id`, t1.`subject`, LEFT(`t1`.`content`, '.max(200, $hesk_settings['kb_substrart'] * 2).') AS `content`, t1.`rating` FROM `'.hesk_dbEscape($hesk_settings['db_pfix']).'kb_articles` AS t1 LEFT JOIN `'.hesk_dbEscape($hesk_settings['db_pfix']).'kb_categories` AS t2 ON t1.`catid` = t2.`id` '." WHERE t1.`type` IN ('0','1') AND MATCH(`subject`,`content`,`keywords`) AGAINST ('".hesk_dbEscape($query)."') LIMIT ".intval($hesk_settings['kb_search_limit']));
|
||||
$num = hesk_dbNumRows($res);
|
||||
$show_default_category = false;
|
||||
?>
|
||||
<div class="content-wrapper">
|
||||
<?php hesk_kb_header($hesk_settings['kb_link']); ?>
|
||||
<section style="padding: 15px">
|
||||
<div class="box">
|
||||
<div class="box-header with-border">
|
||||
@ -225,13 +210,21 @@ function hesk_show_kb_article($artid)
|
||||
|
||||
// Print header
|
||||
$hesk_settings['tmp_title'] = $article['subject'];
|
||||
hesk_kb_header($hesk_settings['kb_link'], $article['catid']);
|
||||
|
||||
// Update views by 1
|
||||
hesk_dbQuery('UPDATE `'.hesk_dbEscape($hesk_settings['db_pfix'])."kb_articles` SET `views`=`views`+1 WHERE `id`={$artid}");
|
||||
|
||||
?>
|
||||
<div class="content-wrapper">
|
||||
<?php
|
||||
hesk_kb_header($hesk_settings['kb_link'], $article['catid']);
|
||||
echo '<div style="margin-left:40px;margin-right:40px">';
|
||||
$service_messages = mfh_get_service_messages('STAFF_VIEW_KB_ARTICLE');
|
||||
foreach ($service_messages as $sm) {
|
||||
hesk_service_message($sm);
|
||||
}
|
||||
echo '</div>';
|
||||
?>
|
||||
<section class="content">
|
||||
<div class="box">
|
||||
<div class="box-header with-border">
|
||||
@ -404,17 +397,24 @@ function hesk_show_kb_article($artid)
|
||||
function hesk_show_kb_category($catid, $is_search = 0) {
|
||||
global $hesk_settings, $hesklang;
|
||||
|
||||
if ($is_search == 0)
|
||||
{
|
||||
/* Print header */
|
||||
hesk_kb_header($hesk_settings['kb_link'], $catid);
|
||||
}
|
||||
|
||||
$res = hesk_dbQuery("SELECT `name`,`parent` FROM `".hesk_dbEscape($hesk_settings['db_pfix'])."kb_categories` WHERE `id`='".intval($catid)."' LIMIT 1");
|
||||
$thiscat = hesk_dbFetchAssoc($res) or hesk_error($hesklang['kb_cat_inv']);
|
||||
|
||||
?>
|
||||
<div class="content-wrapper">
|
||||
<?php
|
||||
if ($is_search == 0)
|
||||
{
|
||||
/* Print header */
|
||||
hesk_kb_header($hesk_settings['kb_link'], $catid);
|
||||
|
||||
echo '<div style="margin-left:40px;margin-right:40px">';
|
||||
$service_messages = mfh_get_service_messages('STAFF_KB_HOME');
|
||||
foreach ($service_messages as $sm) {
|
||||
hesk_service_message($sm);
|
||||
}
|
||||
echo '</div>';
|
||||
} ?>
|
||||
<section class="content">
|
||||
<?php if ($thiscat['parent']): ?>
|
||||
<h3><?php echo $hesklang['kb_cat'].': '.$thiscat['name']; ?></h3>
|
||||
|
@ -37,27 +37,31 @@ hesk_token_check();
|
||||
/* Ticket ID */
|
||||
$trackingID = hesk_cleanID() or die($hesklang['int_error'] . ': ' . $hesklang['no_trackID']);
|
||||
|
||||
|
||||
// Get ticket info
|
||||
$result = hesk_dbQuery("SELECT * FROM `" . hesk_dbEscape($hesk_settings['db_pfix']) . "tickets` WHERE `trackid`='" . hesk_dbEscape($trackingID) . "' LIMIT 1");
|
||||
if (hesk_dbNumRows($result) != 1) {
|
||||
hesk_error($hesklang['ticket_not_found']);
|
||||
}
|
||||
$ticket = hesk_dbFetchAssoc($result);
|
||||
|
||||
$audit_unlocked = null;
|
||||
$audit_locked = null;
|
||||
|
||||
/* New locked status */
|
||||
if (empty($_GET['locked'])) {
|
||||
$status = 0;
|
||||
$tmp = $hesklang['tunlock'];
|
||||
$revision = sprintf($hesklang['thist6'], hesk_date(), $_SESSION['name'] . ' (' . $_SESSION['user'] . ')');
|
||||
$audit_unlocked = array(0 => $_SESSION['name'] . ' (' . $_SESSION['user'] . ')');
|
||||
$closedby_sql = ' , `closedat`=NULL, `closedby`=NULL ';
|
||||
} else {
|
||||
$status = 1;
|
||||
$tmp = $hesklang['tlock'];
|
||||
$revision = sprintf($hesklang['thist5'], hesk_date(), $_SESSION['name'] . ' (' . $_SESSION['user'] . ')');
|
||||
$audit_locked = array(0 => $_SESSION['name'] . ' (' . $_SESSION['user'] . ')');
|
||||
$closedby_sql = ' , `closedat`=NOW(), `closedby`=' . intval($_SESSION['id']) . ' ';
|
||||
|
||||
// Notify customer of closed ticket?
|
||||
if ($hesk_settings['notify_closed']) {
|
||||
// Get ticket info
|
||||
$result = hesk_dbQuery("SELECT * FROM `" . hesk_dbEscape($hesk_settings['db_pfix']) . "tickets` WHERE `trackid`='" . hesk_dbEscape($trackingID) . "' LIMIT 1");
|
||||
if (hesk_dbNumRows($result) != 1) {
|
||||
hesk_error($hesklang['ticket_not_found']);
|
||||
}
|
||||
$ticket = hesk_dbFetchAssoc($result);
|
||||
|
||||
$closedStatusRS = hesk_dbQuery('SELECT `ID` FROM `' . hesk_dbEscape($hesk_settings['db_pfix']) . 'statuses` WHERE `IsClosed` = 1');
|
||||
$ticketIsOpen = true;
|
||||
while ($row = hesk_dbFetchAssoc($closedStatusRS)) {
|
||||
@ -82,7 +86,17 @@ $statusRs = hesk_dbQuery($statusSql);
|
||||
$statusRow = hesk_dbFetchAssoc($statusRs);
|
||||
$statusId = $statusRow['ID'];
|
||||
|
||||
hesk_dbQuery("UPDATE `" . hesk_dbEscape($hesk_settings['db_pfix']) . "tickets` SET `status`= {$statusId},`locked`='{$status}' $closedby_sql , `history`=CONCAT(`history`,'" . hesk_dbEscape($revision) . "') WHERE `trackid`='" . hesk_dbEscape($trackingID) . "'");
|
||||
hesk_dbQuery("UPDATE `" . hesk_dbEscape($hesk_settings['db_pfix']) . "tickets` SET `status`= {$statusId},`locked`='{$status}' $closedby_sql WHERE `trackid`='" . hesk_dbEscape($trackingID) . "'");
|
||||
|
||||
if ($audit_unlocked) {
|
||||
mfh_insert_audit_trail_record($ticket['id'], 'TICKET', 'audit_unlocked', hesk_date(),
|
||||
$audit_unlocked);
|
||||
}
|
||||
|
||||
if ($audit_locked) {
|
||||
mfh_insert_audit_trail_record($ticket['id'], 'TICKET', 'audit_locked', hesk_date(),
|
||||
$audit_locked);
|
||||
}
|
||||
|
||||
/* Back to ticket page and show a success message */
|
||||
hesk_process_messages($tmp, 'admin_ticket.php?track=' . $trackingID . '&Refresh=' . rand(10000, 99999), 'SUCCESS');
|
@ -32,7 +32,7 @@ $modsForHesk_settings = mfh_getSettings();
|
||||
|
||||
/* List of staff */
|
||||
$admins = array();
|
||||
$res = hesk_dbQuery("SELECT `id`,`name` FROM `" . hesk_dbEscape($hesk_settings['db_pfix']) . "users` ORDER BY `name` ASC");
|
||||
$res = hesk_dbQuery("SELECT `id`,`name` FROM `" . hesk_dbEscape($hesk_settings['db_pfix']) . "users` WHERE `active` = '1' ORDER BY `name` ASC");
|
||||
while ($row = hesk_dbFetchAssoc($res)) {
|
||||
$admins[$row['id']] = $row['name'];
|
||||
}
|
||||
@ -450,10 +450,10 @@ function show_message()
|
||||
$folder = '&folder=outbox';
|
||||
if ($pm['to'] == $_SESSION['id'])
|
||||
{
|
||||
echo '<a class="btn btn-default" href="mail.php?a=mark_unread&id='.$id.'&token='.hesk_token_echo(0).'"><i class="fa fa-envelope-o icon-link"></i> '.$hesklang['mau'].'</a> ';
|
||||
echo '<a name="MAU '.$pm['subject'].'" class="btn btn-default" href="mail.php?a=mark_unread&id='.$id.'&token='.hesk_token_echo(0).'"><i class="fa fa-envelope-o icon-link"></i> '.$hesklang['mau'].'</a> ';
|
||||
$folder = '';
|
||||
}
|
||||
echo '<a class="btn btn-danger" href="mail.php?a=delete&id='.$id.'&token='.hesk_token_echo(0).$folder.'" onclick="return hesk_confirmExecute(\''.hesk_makeJsString($hesklang['delm']).'?\');"><i class="fa fa-times icon-link"></i> '.$hesklang['delm'].'</a>';
|
||||
echo '<a name="Delete '.$pm['subject'].'" class="btn btn-danger" href="mail.php?a=delete&id='.$id.'&token='.hesk_token_echo(0).$folder.'" onclick="return hesk_confirmExecute(\''.hesk_makeJsString($hesklang['delm']).'?\');"><i class="fa fa-times icon-link"></i> '.$hesklang['delm'].'</a>';
|
||||
?>
|
||||
</div>
|
||||
</div>
|
||||
@ -571,7 +571,7 @@ function mail_list_messages()
|
||||
$pm['dt'] = hesk_dateToString($pm['dt'], 0, 0, 0, true)
|
||||
?>
|
||||
<tr>
|
||||
<td><input type="checkbox" name="id[]" value="<?php echo $pm['id']; ?>" /> </td>
|
||||
<td><input type="checkbox" name="id[]" id="<?php echo $pm['id']; ?>" value="<?php echo $pm['id']; ?>" /> </td>
|
||||
<td><?php echo $pm['subject']; ?></td>
|
||||
<td><?php echo $pm['name']; ?></td>
|
||||
<td><?php echo $pm['dt']; ?></td>
|
||||
|
@ -74,9 +74,9 @@ require_once(HESK_PATH . 'inc/show_admin_nav.inc.php');
|
||||
var msg = '';
|
||||
<?php
|
||||
if ($modsForHesk_settings['rich_text_for_tickets']) { ?>
|
||||
msg = tinymce.get("message").getContent();
|
||||
tinymce.get("message").setContent('');
|
||||
tinymce.get("message").execCommand('mceInsertRawHTML', false, msg + text_to_insert);
|
||||
msg = $('#message').val();
|
||||
$("#message").summernote('reset');
|
||||
$("#message").summernote('editor.insertText', msg + text_to_insert));
|
||||
<?php } else { ?>
|
||||
msg = document.getElementById('message').value;
|
||||
document.getElementById('message').value = msg + text_to_insert;
|
||||
@ -190,7 +190,7 @@ $num = hesk_dbNumRows($result);
|
||||
}
|
||||
|
||||
echo '
|
||||
<a href="manage_canned.php?a=remove&id=' . $mysaved['id'] . '&token=' . hesk_token_echo(0) . '" onclick="return confirm_delete();"><i class="fa fa-times icon-link red" data-toggle="tooltip" data-placement="top" title="' . $hesklang['delete'] . '"></i></a> </td>
|
||||
<a name="'.$mysaved['title'].'" href="manage_canned.php?a=remove&id=' . $mysaved['id'] . '&token=' . hesk_token_echo(0) . '" onclick="return confirm_delete();"><i class="fa fa-times icon-link red" data-toggle="tooltip" data-placement="top" title="' . $hesklang['delete'] . '"></i></a> </td>
|
||||
</tr>
|
||||
';
|
||||
} // End while
|
||||
@ -202,21 +202,15 @@ $num = hesk_dbNumRows($result);
|
||||
<?php if ($modsForHesk_settings['rich_text_for_tickets']): ?>
|
||||
<script type="text/javascript">
|
||||
/* <![CDATA[ */
|
||||
tinyMCE.init({
|
||||
mode: "textareas",
|
||||
editor_selector: "htmlEditor",
|
||||
elements: "content",
|
||||
theme: "advanced",
|
||||
convert_urls: false,
|
||||
|
||||
theme_advanced_buttons1: "cut,copy,paste,|,undo,redo,|,formatselect,fontselect,fontsizeselect,|,bold,italic,underline,strikethrough,|,justifyleft,justifycenter,justifyright,justifyfull",
|
||||
theme_advanced_buttons2: "sub,sup,|,charmap,|,bullist,numlist,|,outdent,indent,insertdate,inserttime,preview,|,forecolor,backcolor,|,hr,removeformat,visualaid,|,link,unlink,anchor,image,cleanup,code",
|
||||
theme_advanced_buttons3: "",
|
||||
|
||||
theme_advanced_toolbar_location: "top",
|
||||
theme_advanced_toolbar_align: "left",
|
||||
theme_advanced_statusbar_location: "bottom",
|
||||
theme_advanced_resizing: true
|
||||
$(document).ready(function() {
|
||||
$('.htmlEditor').summernote({
|
||||
height: 200,
|
||||
toolbar: [
|
||||
['style', ['bold', 'italic', 'underline', 'clear']],
|
||||
['font', ['strikethrough', 'superscript', 'subscript']],
|
||||
['para', ['ul', 'ol']]
|
||||
]
|
||||
});
|
||||
});
|
||||
/* ]]> */
|
||||
</script>
|
||||
@ -254,8 +248,7 @@ $num = hesk_dbNumRows($result);
|
||||
|
||||
if (myMsg == '') {
|
||||
if (useHtmlEditor) {
|
||||
tinymce.get("message").setContent('');
|
||||
tinymce.get("message").execCommand('mceInsertRawHTML', false, '');
|
||||
$("#message").summernote("reset");
|
||||
}
|
||||
else {
|
||||
$('#message').val('');
|
||||
@ -265,8 +258,8 @@ $num = hesk_dbNumRows($result);
|
||||
}
|
||||
if (document.getElementById) {
|
||||
if (useHtmlEditor) {
|
||||
tinymce.get("message").setContent('');
|
||||
tinymce.get("message").execCommand('mceInsertRawHTML', false, myMsg);
|
||||
$("#message").summernote('reset');
|
||||
$("#message").summernote('editor.insertText', myMsg));
|
||||
} else {
|
||||
myMsg = $('<textarea />').html(myMsg).text();
|
||||
$('#message').val(myMsg).trigger('input');
|
||||
@ -370,6 +363,8 @@ $num = hesk_dbNumRows($result);
|
||||
onclick="hesk_insertTag('HESK_TRACK_ID')"><?php echo $hesklang['trackID']; ?></a> |
|
||||
<a href="javascript:void(0)"
|
||||
onclick="hesk_insertTag('HESK_NAME')"><?php echo $hesklang['name']; ?></a> |
|
||||
<a href="javascript:void(0)"
|
||||
onclick="hesk_insertTag('HESK_FIRST_NAME')"><?php echo $hesklang['fname']; ?></a> |
|
||||
<a href="javascript:void(0)"
|
||||
onclick="hesk_insertTag('HESK_EMAIL')"><?php echo $hesklang['email']; ?></a> |
|
||||
<a href="javascript:void(0)"
|
||||
|
File diff suppressed because it is too large
Load Diff
275
admin/manage_custom_nav_elements.php
Normal file
275
admin/manage_custom_nav_elements.php
Normal file
@ -0,0 +1,275 @@
|
||||
<?php
|
||||
|
||||
define('IN_SCRIPT', 1);
|
||||
define('HESK_PATH', '../');
|
||||
define('PAGE_TITLE', 'ADMIN_CUSTOM_NAV_ELEMENTS');
|
||||
define('MFH_PAGE_LAYOUT', 'TOP_ONLY');
|
||||
define('EXTRA_JS', '<script src="'.HESK_PATH.'internal-api/js/manage-custom-nav-elements.js"></script>');
|
||||
|
||||
/* Get all the required files and functions */
|
||||
require(HESK_PATH . 'hesk_settings.inc.php');
|
||||
require(HESK_PATH . 'inc/common.inc.php');
|
||||
require(HESK_PATH . 'inc/admin_functions.inc.php');
|
||||
require(HESK_PATH . 'inc/mail_functions.inc.php');
|
||||
hesk_load_database_functions();
|
||||
|
||||
hesk_session_start();
|
||||
hesk_dbConnect();
|
||||
hesk_isLoggedIn();
|
||||
|
||||
//hesk_checkPermission('can_man_custom_nav');
|
||||
|
||||
/* Print header */
|
||||
require_once(HESK_PATH . 'inc/headerAdmin.inc.php');
|
||||
|
||||
/* Print main manage users page */
|
||||
require_once(HESK_PATH . 'inc/show_admin_nav.inc.php');
|
||||
?>
|
||||
<div class="content-wrapper">
|
||||
<section class="content">
|
||||
<div class="box">
|
||||
<div class="box-header with-border">
|
||||
<h1 class="box-title">
|
||||
<?php echo $hesklang['custom_nav_menu_elements']; ?>
|
||||
</h1>
|
||||
<div class="box-tools pull-right">
|
||||
<button type="button" class="btn btn-box-tool" data-widget="collapse">
|
||||
<i class="fa fa-minus"></i>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="box-body">
|
||||
<div class="row">
|
||||
<div class="col-md-12 text-right">
|
||||
<button id="create-button" class="btn btn-success">
|
||||
<i class="fa fa-plus-circle"></i>
|
||||
<?php echo $hesklang['create_new']; ?>
|
||||
</button>
|
||||
</div>
|
||||
<div class="col-md-12">
|
||||
<table class="table table-striped">
|
||||
<thead>
|
||||
<tr>
|
||||
<th><?php echo $hesklang['id']; ?></th>
|
||||
<th><?php echo $hesklang['custom_nav_text']; ?></th>
|
||||
<th><?php echo $hesklang['custom_nav_subtext']; ?></th>
|
||||
<th><?php echo $hesklang['image_url_slash_font_icon']; ?></th>
|
||||
<th><?php echo $hesklang['url']; ?></th>
|
||||
<th><?php echo $hesklang['actions']; ?></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody id="table-body">
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="overlay" id="overlay">
|
||||
<i class="fa fa-spinner fa-spin"></i>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
<div class="modal fade" id="nav-element-modal" tabindex="-1" role="dialog" style="overflow: hidden">
|
||||
<div class="modal-dialog modal-lg" role="document">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header" style="cursor: move">
|
||||
<button type="button" class="close cancel-callback" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button>
|
||||
<h4 class="modal-title" id="edit-label">
|
||||
<?php echo $hesklang['edit_custom_nav_element_title_case']; ?>
|
||||
</h4>
|
||||
<h4 class="modal-title" id="create-label">
|
||||
<?php echo $hesklang['create_custom_nav_element_title_case']; ?>
|
||||
</h4>
|
||||
</div>
|
||||
<form id="manage-nav-element" class="form-horizontal" data-toggle="validator">
|
||||
<input type="hidden" name="id">
|
||||
<div class="modal-body">
|
||||
<div class="row">
|
||||
<div class="col-md-12">
|
||||
<div class="form-group">
|
||||
<label for="place" class="col-md-4 col-sm-12 control-label">
|
||||
<?php echo $hesklang['place']; ?>
|
||||
<i class="fa fa-question-circle settingsquestionmark" data-toggle="htmlpopover"
|
||||
title="<?php echo $hesklang['place']; ?>"
|
||||
data-content="<?php echo $hesklang['place_help']; ?>"></i>
|
||||
</label>
|
||||
<div class="col-md-8 col-sm-12">
|
||||
<select name="place" id="place" class="form-control"
|
||||
data-error="<?php echo htmlspecialchars($hesklang['this_field_is_required']); ?>"
|
||||
required>
|
||||
<option value="1"><?php echo $hesklang['homepage_block']; ?></option>
|
||||
<option value="2"><?php echo $hesklang['customer_navigation']; ?></option>
|
||||
<option value="3"><?php echo $hesklang['staff_navigation']; ?></option>
|
||||
</select>
|
||||
<div class="help-block with-errors"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-md-6 col-sm-12">
|
||||
<h4><?php echo $hesklang['custom_nav_text']; ?></h4>
|
||||
<?php foreach ($hesk_settings['languages'] as $language => $value): ?>
|
||||
<div class="form-group">
|
||||
<label for="text[<?php echo $language; ?>]" class="col-md-4 col-sm-12 control-label">
|
||||
<?php echo $language; ?>
|
||||
</label>
|
||||
<div class="col-md-8 col-sm-12">
|
||||
<input type="text" name="text" class="form-control"
|
||||
data-text-language="<?php echo $language; ?>"
|
||||
id="text[<?php echo $language; ?>" placeholder="<?php echo $hesklang['custom_nav_text']; ?>"
|
||||
data-error="<?php echo htmlspecialchars($hesklang['this_field_is_required']); ?>"
|
||||
required>
|
||||
<div class="help-block with-errors"></div>
|
||||
</div>
|
||||
</div>
|
||||
<?php endforeach; ?>
|
||||
<div id="subtext">
|
||||
<h4><?php echo $hesklang['custom_nav_subtext']; ?></h4>
|
||||
<?php foreach ($hesk_settings['languages'] as $language => $value): ?>
|
||||
<div class="form-group">
|
||||
<label for="subtext[<?php echo $language; ?>]" class="col-md-4 col-sm-12 control-label">
|
||||
<?php echo $language; ?>
|
||||
</label>
|
||||
<div class="col-md-8 col-sm-12">
|
||||
<input type="text" name="subtext" class="form-control"
|
||||
data-subtext-language="<?php echo $language; ?>"
|
||||
id="subtext[<?php echo $language; ?>" placeholder="<?php echo $hesklang['custom_nav_subtext']; ?>"
|
||||
data-error="<?php echo htmlspecialchars($hesklang['this_field_is_required']); ?>"
|
||||
required>
|
||||
<div class="help-block with-errors"></div>
|
||||
</div>
|
||||
</div>
|
||||
<?php endforeach; ?>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-6 col-sm-12">
|
||||
<h4><?php echo $hesklang['url']; ?></h4>
|
||||
<div class="form-group">
|
||||
<label for="image-type" class="col-md-4 col-sm-12 control-label">
|
||||
<?php echo $hesklang['url']; ?>
|
||||
<i class="fa fa-question-circle settingsquestionmark" data-toggle="htmlpopover"
|
||||
title="<?php echo $hesklang['url']; ?>"
|
||||
data-content="<?php echo $hesklang['url_help']; ?>"></i>
|
||||
</label>
|
||||
<div class="col-md-8 col-sm-12">
|
||||
<input type="text" name="url" class="form-control"
|
||||
data-error="<?php echo htmlspecialchars($hesklang['this_field_is_required']); ?>"
|
||||
placeholder="<?php echo $hesklang['url']; ?>" required>
|
||||
<div class="help-block with-errors"></div>
|
||||
</div>
|
||||
</div>
|
||||
<h4><?php echo $hesklang['image']; ?></h4>
|
||||
<div class="form-group">
|
||||
<label for="image-type" class="col-md-4 col-sm-12 control-label"><?php echo $hesklang['image_type']; ?></label>
|
||||
<div class="col-md-8 col-sm-12">
|
||||
<select name="image-type" id="image-type" class="form-control"
|
||||
data-error="<?php echo htmlspecialchars($hesklang['this_field_is_required']); ?>"
|
||||
required>
|
||||
<option value="image-url"><?php echo $hesklang['image_url']; ?></option>
|
||||
<option value="font-icon"><?php echo $hesklang['font_icon']; ?></option>
|
||||
</select>
|
||||
<div class="help-block with-errors"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group" id="image-url-group">
|
||||
<label for="image-url" class="col-md-4 col-sm-12 control-label">
|
||||
<?php echo $hesklang['image_url']; ?>
|
||||
<i class="fa fa-question-circle settingsquestionmark" data-toggle="htmlpopover"
|
||||
title="<?php echo $hesklang['image_url']; ?>"
|
||||
data-content="<?php echo $hesklang['image_url_help']; ?>"></i>
|
||||
</label>
|
||||
<div class="col-md-8 col-sm-12">
|
||||
<input type="text" name="image-url" class="form-control"
|
||||
data-error="<?php echo htmlspecialchars($hesklang['this_field_is_required']); ?>"
|
||||
placeholder="<?php echo $hesklang['image_url']; ?>" required>
|
||||
<div class="help-block with-errors"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group" id="font-icon-group">
|
||||
<p style="display:none" id="no-icon"><?php echo $hesklang['sm_no_icon']; ?></p>
|
||||
|
||||
<p style="display:none" id="search-icon"><?php echo $hesklang['sm_search_icon']; ?></p>
|
||||
|
||||
<p style="display:none"
|
||||
id="footer-icon"><?php echo $hesklang['sm_iconpicker_footer_label']; ?></p>
|
||||
<label for="font-icon" class="col-md-4 col-sm-12 control-label"><?php echo $hesklang['font_icon']; ?></label>
|
||||
<div class="col-md-8 col-sm-12">
|
||||
<div class="btn btn-default iconpicker-container" data-toggle="nav-iconpicker">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<div class="btn-group" id="action-buttons">
|
||||
<button type="button" class="btn btn-default cancel-button" data-dismiss="modal">
|
||||
<i class="fa fa-times-circle"></i>
|
||||
<span><?php echo $hesklang['cancel']; ?></span>
|
||||
</button>
|
||||
<button type="submit" class="btn btn-success save-button">
|
||||
<i class="fa fa-check-circle"></i>
|
||||
<span><?php echo $hesklang['save']; ?></span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<?php
|
||||
echo mfh_get_hidden_fields_for_language(
|
||||
array(
|
||||
'edit',
|
||||
'delete',
|
||||
'no_custom_nav_elements_found',
|
||||
'failed_to_load_custom_nav_elements',
|
||||
'custom_nav_element_deleted',
|
||||
'error_deleting_custom_nav_element',
|
||||
'error_sorting_custom_nav_elements',
|
||||
'custom_nav_element_created',
|
||||
'custom_nav_element_saved',
|
||||
'homepage_block',
|
||||
'customer_navigation',
|
||||
'staff_navigation',
|
||||
'error_saving_custom_nav_element',
|
||||
)
|
||||
);
|
||||
?>
|
||||
<script type="text/html" id="nav-element-template">
|
||||
<tr>
|
||||
<td><span data-property="id" data-value="x"></span></td>
|
||||
<td><span>
|
||||
<ul data-property="text" class="list-unstyled"></ul>
|
||||
</span></td>
|
||||
<td><span>
|
||||
<ul data-property="subtext" class="list-unstyled"></ul>
|
||||
</span></td>
|
||||
<td><span data-property="image-or-font"></span></td>
|
||||
<td><span data-property="url"></span></td>
|
||||
<td>
|
||||
<a href="#" data-action="sort"
|
||||
data-direction="up">
|
||||
<i class="fa fa-fw fa-arrow-up icon-link green"
|
||||
data-toggle="tooltip" title="<?php echo $hesklang['move_up']; ?>"></i>
|
||||
</a>
|
||||
<a href="#" data-action="sort"
|
||||
data-direction="down">
|
||||
<i class="fa fa-fw fa-arrow-down icon-link green"
|
||||
data-toggle="tooltip" title="<?php echo $hesklang['move_dn'] ?>"></i>
|
||||
</a>
|
||||
<a href="#" data-action="edit">
|
||||
<i class="fa fa-fw fa-pencil icon-link orange"
|
||||
data-toggle="tooltip" title="<?php echo $hesklang['edit']; ?>"></i>
|
||||
</a>
|
||||
<a href="#" data-action="delete">
|
||||
<i class="fa fa-fw fa-times icon-link red"
|
||||
data-toggle="tooltip" title="<?php echo $hesklang['delete']; ?>"></i>
|
||||
</a>
|
||||
</td>
|
||||
</tr>
|
||||
</script>
|
||||
<?php
|
||||
require_once(HESK_PATH . 'inc/footer.inc.php');
|
@ -10,6 +10,7 @@ require(HESK_PATH . 'hesk_settings.inc.php');
|
||||
require(HESK_PATH . 'inc/common.inc.php');
|
||||
require(HESK_PATH . 'inc/admin_functions.inc.php');
|
||||
require(HESK_PATH . 'inc/mail_functions.inc.php');
|
||||
require(HESK_PATH . 'inc/custom_fields.inc.php');
|
||||
hesk_load_database_functions();
|
||||
|
||||
hesk_session_start();
|
||||
@ -38,25 +39,22 @@ if (isset($_POST['action'])) {
|
||||
require_once(HESK_PATH . 'inc/headerAdmin.inc.php');
|
||||
|
||||
if ($modsForHesk_settings['html_emails']) {
|
||||
echo '<script type="text/javascript">
|
||||
tinyMCE.init({
|
||||
mode : "textareas",
|
||||
editor_selector : "htmlEditor",
|
||||
elements : "content",
|
||||
theme : "advanced",
|
||||
convert_urls : false,
|
||||
gecko_spellcheck: true,
|
||||
|
||||
theme_advanced_buttons1 : "cut,copy,paste,|,undo,redo,|,formatselect,fontselect,fontsizeselect,|,bold,italic,underline,strikethrough,|,justifyleft,justifycenter,justifyright,justifyfull",
|
||||
theme_advanced_buttons2 : "sub,sup,|,charmap,|,bullist,numlist,|,outdent,indent,insertdate,inserttime,preview,|,forecolor,backcolor,|,hr,removeformat,visualaid,|,link,unlink,anchor,image,cleanup,code",
|
||||
theme_advanced_buttons3 : "",
|
||||
|
||||
theme_advanced_toolbar_location : "top",
|
||||
theme_advanced_toolbar_align : "left",
|
||||
theme_advanced_statusbar_location : "bottom",
|
||||
theme_advanced_resizing : true
|
||||
?>
|
||||
<script type="text/javascript">
|
||||
/* <![CDATA[ */
|
||||
$(document).ready(function() {
|
||||
$('.htmlEditor').summernote({
|
||||
height: 200,
|
||||
toolbar: [
|
||||
['style', ['bold', 'italic', 'underline', 'clear']],
|
||||
['font', ['strikethrough', 'superscript', 'subscript']],
|
||||
['para', ['ul', 'ol']]
|
||||
]
|
||||
});
|
||||
</script>';
|
||||
});
|
||||
/* ]]> */
|
||||
</script>
|
||||
<?php
|
||||
}
|
||||
|
||||
/* Print main manage users page */
|
||||
@ -276,12 +274,12 @@ function getTemplateMarkup($template, $languageCode, $html = false)
|
||||
$templateUrl = urlencode($template);
|
||||
$languageCodeUrl = urlencode($languageCode);
|
||||
if ($html) {
|
||||
$markup = '<a href="manage_email_templates.php?action=edit&template=' . $templateUrl . '&language=' . $languageCodeUrl . '&html=true">';
|
||||
$markup = '<a name="Edit '.$templateUrl.'" href="manage_email_templates.php?action=edit&template=' . $templateUrl . '&language=' . $languageCodeUrl . '&html=true">';
|
||||
$markup .= '<i class="fa fa-html5 font-size-150" data-toggle="tooltip" title="' . $hesklang['edit_html_template'] . '"></i>';
|
||||
$markup .= '</a>';
|
||||
return $markup;
|
||||
} else {
|
||||
$markup = '<a href="manage_email_templates.php?action=edit&template=' . $templateUrl . '&language=' . $languageCodeUrl . '&html=false">';
|
||||
$markup = '<a name="Edit '.$templateUrl.'" href="manage_email_templates.php?action=edit&template=' . $templateUrl . '&language=' . $languageCodeUrl . '&html=false">';
|
||||
$markup .= '<i class="fa fa-file-text-o font-size-150" data-toggle="tooltip" title="' . $hesklang['edit_plain_text_template'] . '"></i>';
|
||||
$markup .= '</a>';
|
||||
return $markup;
|
||||
@ -312,6 +310,7 @@ function getSpecialTagMap()
|
||||
|
||||
$map = array();
|
||||
$map['%%NAME%%'] = $hesklang['customer_name'];
|
||||
$map['%%FIRST_NAME%%'] = $hesklang['fname'];
|
||||
$map['%%EMAIL%%'] = $hesklang['customer_email'];
|
||||
$map['%%SUBJECT%%'] = $hesklang['ticket_subject'];
|
||||
$map['%%MESSAGE%%'] = $hesklang['ticket_message'];
|
||||
@ -326,6 +325,8 @@ function getSpecialTagMap()
|
||||
$map['%%OWNER%%'] = $hesklang['ticket_owner'];
|
||||
$map['%%PRIORITY%%'] = $hesklang['ticket_priority'];
|
||||
$map['%%STATUS%%'] = $hesklang['ticket_status'];
|
||||
$map['%%LAST_REPLY_BY%%'] = $hesklang['last_replier'];
|
||||
$map['%%TIME_WORKED%%'] = $hesklang['ts'];
|
||||
|
||||
$i = 1;
|
||||
foreach ($hesk_settings['custom_fields'] as $key => $value) {
|
||||
|
@ -1,32 +1,15 @@
|
||||
<?php
|
||||
/*******************************************************************************
|
||||
* Title: Help Desk Software HESK
|
||||
* Version: 2.6.8 from 10th August 2016
|
||||
* Author: Klemen Stirn
|
||||
* Website: https://www.hesk.com
|
||||
********************************************************************************
|
||||
* COPYRIGHT AND TRADEMARK NOTICE
|
||||
* Copyright 2005-2015 Klemen Stirn. All Rights Reserved.
|
||||
* HESK is a registered trademark of Klemen Stirn.
|
||||
* The HESK may be used and modified free of charge by anyone
|
||||
* AS LONG AS COPYRIGHT NOTICES AND ALL THE COMMENTS REMAIN INTACT.
|
||||
* By using this code you agree to indemnify Klemen Stirn from any
|
||||
* liability that might arise from it's use.
|
||||
* Selling the code for this program, in part or full, without prior
|
||||
* written consent is expressly forbidden.
|
||||
* Using this code, in part or full, to create derivate work,
|
||||
* new scripts or products is expressly forbidden. Obtain permission
|
||||
* before redistributing this software over the Internet or in
|
||||
* any other medium. In all cases copyright and header must remain intact.
|
||||
* This Copyright is in full effect in any country that has International
|
||||
* Trade Agreements with the United States of America or
|
||||
* with the European Union.
|
||||
* Removing any of the copyright notices without purchasing a license
|
||||
* is expressly forbidden. To remove HESK copyright notice you must purchase
|
||||
* a license for this script. For more information on how to obtain
|
||||
* a license please visit the page below:
|
||||
* https://www.hesk.com/buy.php
|
||||
*******************************************************************************/
|
||||
/**
|
||||
*
|
||||
* This file is part of HESK - PHP Help Desk Software.
|
||||
*
|
||||
* (c) Copyright Klemen Stirn. All rights reserved.
|
||||
* https://www.hesk.com
|
||||
*
|
||||
* For the full copyright and license agreement information visit
|
||||
* https://www.hesk.com/eula.php
|
||||
*
|
||||
*/
|
||||
|
||||
define('IN_SCRIPT',1);
|
||||
define('HESK_PATH','../');
|
||||
@ -202,9 +185,9 @@ while (count($kb_cat) > 0)
|
||||
|
||||
// Generate KB menu icons
|
||||
$menu_icons =
|
||||
'<a href="manage_knowledgebase.php?a=add_article&catid='.$my.'" onclick="document.getElementById(\'option'.$j.'\').selected=true;return true;"><i class="fa fa-plus font-size-16p green" ></i></a> '
|
||||
.'<a href="manage_knowledgebase.php?a=add_category&parent='.$my.'" onclick="document.getElementById(\'option'.$j.'_2\').selected=true;return true;"><i class="fa fa-caret-right font-size-16p blue"></i></a> '
|
||||
.'<a href="manage_knowledgebase.php?a=manage_cat&catid='.$my.'"><i class="fa fa-gear font-size-16p gray"></i></a> '
|
||||
'<a name="Add article to '.$cat['name'].'" href="manage_knowledgebase.php?a=add_article&catid='.$my.'" onclick="document.getElementById(\'option'.$j.'\').selected=true;return true;"><i class="fa fa-plus font-size-16p green" ></i></a> '
|
||||
.'<a name="Add sub to '.$cat['name'].'" href="manage_knowledgebase.php?a=add_category&parent='.$my.'" onclick="document.getElementById(\'option'.$j.'_2\').selected=true;return true;"><i class="fa fa-caret-right font-size-16p blue"></i></a> '
|
||||
.'<a name="Manage '.$cat['name'].'" href="manage_knowledgebase.php?a=manage_cat&catid='.$my.'"><i class="fa fa-gear font-size-16p gray"></i></a> '
|
||||
;
|
||||
|
||||
// Can this category be moved up?
|
||||
@ -229,7 +212,8 @@ while (count($kb_cat) > 0)
|
||||
|
||||
if (isset($node[$up]))
|
||||
{
|
||||
$node[$my] = &$node[$up]->addItem(new HTML_TreeNode(array('hesk_selected' => $selected, 'text' => $text, 'text_short' => $text_short, 'menu_icons' => $menu_icons, 'hesk_catid' => $cat['id'], 'hesk_select' => 'option'.$j, 'icon' => $icon, 'expandedIcon' => $expandedIcon, 'expanded' => true)));
|
||||
$HTML_TreeNode[$my] = new HTML_TreeNode(array('hesk_selected' => $selected, 'text' => $text, 'text_short' => $text_short, 'menu_icons' => $menu_icons, 'hesk_catid' => $cat['id'], 'hesk_select' => 'option'.$j, 'icon' => $icon, 'expandedIcon' => $expandedIcon, 'expanded' => true));
|
||||
$node[$my] = &$node[$up]->addItem($HTML_TreeNode[$my]);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -259,8 +243,11 @@ while (count($kb_cat) > 0)
|
||||
$menu->addItem($node[1]);
|
||||
|
||||
// Create the presentation class
|
||||
$treeMenu = & ref_new(new HTML_TreeMenu_DHTML($menu, array('images' => '../img', 'defaultClass' => 'treeMenuDefault', 'isDynamic' => true)));
|
||||
$listBox = & ref_new(new HTML_TreeMenu_Listbox($menu));
|
||||
$HTML_TreeMenu_DHTML = new HTML_TreeMenu_DHTML($menu, array('images' => '../img', 'defaultClass' => 'treeMenuDefault', 'isDynamic' => true));
|
||||
$treeMenu = & ref_new($HTML_TreeMenu_DHTML);
|
||||
|
||||
$HTML_TreeMenu_Listbox = new HTML_TreeMenu_Listbox($menu);
|
||||
$listBox = & ref_new($HTML_TreeMenu_Listbox);
|
||||
|
||||
/* Hide new article and new category forms by default */
|
||||
if (!isset($_SESSION['hide']))
|
||||
@ -287,6 +274,12 @@ if (!isset($_SESSION['hide']['treemenu']))
|
||||
<?php
|
||||
show_subnav();
|
||||
|
||||
// Service messages
|
||||
$service_messages = mfh_get_service_messages('STAFF_KB_HOME');
|
||||
foreach ($service_messages as $sm) {
|
||||
hesk_service_message($sm);
|
||||
}
|
||||
|
||||
// Show a notice if total public articles is less than 5
|
||||
if ($total_articles < 5)
|
||||
{
|
||||
@ -352,22 +345,18 @@ if (!isset($_SESSION['hide']['new_article']))
|
||||
{
|
||||
?>
|
||||
<script type="text/javascript">
|
||||
tinyMCE.init({
|
||||
mode : "exact",
|
||||
elements : "content",
|
||||
theme : "advanced",
|
||||
convert_urls : false,
|
||||
gecko_spellcheck: true,
|
||||
|
||||
theme_advanced_buttons1 : "cut,copy,paste,|,undo,redo,|,formatselect,fontselect,fontsizeselect,|,bold,italic,underline,strikethrough,|,justifyleft,justifycenter,justifyright,justifyfull",
|
||||
theme_advanced_buttons2 : "sub,sup,|,charmap,|,bullist,numlist,|,outdent,indent,insertdate,inserttime,preview,|,forecolor,backcolor,|,hr,removeformat,visualaid,|,link,unlink,anchor,image,cleanup,code",
|
||||
theme_advanced_buttons3 : "",
|
||||
|
||||
theme_advanced_toolbar_location : "top",
|
||||
theme_advanced_toolbar_align : "left",
|
||||
theme_advanced_statusbar_location : "bottom",
|
||||
theme_advanced_resizing : true
|
||||
/* <![CDATA[ */
|
||||
$(document).ready(function() {
|
||||
$('#content').summernote({
|
||||
height: 200,
|
||||
toolbar: [
|
||||
['style', ['bold', 'italic', 'underline', 'clear']],
|
||||
['font', ['strikethrough', 'superscript', 'subscript']],
|
||||
['para', ['ul', 'ol']]
|
||||
]
|
||||
});
|
||||
});
|
||||
/* ]]> */
|
||||
</script>
|
||||
<?php
|
||||
}
|
||||
@ -475,7 +464,7 @@ if (!isset($_SESSION['hide']['new_article']))
|
||||
<?php build_dropzone_markup(true); ?>
|
||||
</div>
|
||||
<?php
|
||||
display_dropzone_field($hesk_settings['hesk_url'] . '/internal-api/admin/knowledgebase/upload-attachment.php');
|
||||
display_dropzone_field(HESK_PATH . 'internal-api/admin/knowledgebase/upload-attachment.php');
|
||||
endif; // End attachments
|
||||
|
||||
?>
|
||||
@ -916,7 +905,7 @@ function import_article()
|
||||
$_SESSION['new_article'] = array(
|
||||
'html' => 0,
|
||||
'subject' => $ticket['subject'],
|
||||
'content' => hesk_msgToPlain($ticket['message']),
|
||||
'content' => hesk_msgToPlain($ticket['message'], 0, 0),
|
||||
);
|
||||
}
|
||||
|
||||
@ -931,10 +920,14 @@ function import_article()
|
||||
}
|
||||
else
|
||||
{
|
||||
$_SESSION['new_article']['content'] .= "\n\n" . hesk_msgToPlain($reply['message']);
|
||||
$_SESSION['new_article']['content'] .= "\n\n" . hesk_msgToPlain($reply['message'], 0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
// Make sure everything is extra slashed as stripslashes will be called later
|
||||
$_SESSION['new_article']['subject'] = addslashes($_SESSION['new_article']['subject']);
|
||||
$_SESSION['new_article']['content'] = addslashes($_SESSION['new_article']['content']);
|
||||
|
||||
hesk_process_messages($hesklang['import'],'NOREDIRECT','NOTICE');
|
||||
|
||||
} // END add_article()
|
||||
@ -1079,6 +1072,9 @@ function edit_category()
|
||||
// Now delete the category
|
||||
hesk_dbQuery("DELETE FROM `".hesk_dbEscape($hesk_settings['db_pfix'])."kb_categories` WHERE `id`='".intval($catid)."'");
|
||||
|
||||
// Clear KB cache
|
||||
hesk_purge_cache('kb');
|
||||
|
||||
$_SESSION['hide'] = array(
|
||||
//'treemenu' => 1,
|
||||
'new_article' => 1,
|
||||
@ -1251,6 +1247,9 @@ function save_article()
|
||||
// Update article order
|
||||
update_article_order($catid);
|
||||
|
||||
// Clear KB cache
|
||||
hesk_purge_cache('kb');
|
||||
|
||||
// Redirect to the correct page
|
||||
switch ($from) {
|
||||
case 'draft':
|
||||
@ -1353,7 +1352,8 @@ function edit_article()
|
||||
|
||||
if (isset($node[$up]))
|
||||
{
|
||||
$node[$my] = &$node[$up]->addItem(new HTML_TreeNode(array('hesk_parent' => $this_cat['parent'], 'text' => 'Text', 'text_short' => $text_short, 'hesk_catid' => $cat['id'], 'hesk_select' => 'option'.$j, 'icon' => $icon, 'expandedIcon' => $expandedIcon, 'expanded' => true)));
|
||||
$HTML_TreeNode[$my] = new HTML_TreeNode(array('hesk_parent' => $this_cat['parent'], 'text' => 'Text', 'text_short' => $text_short, 'hesk_catid' => $cat['id'], 'hesk_select' => 'option'.$j, 'icon' => $icon, 'expandedIcon' => $expandedIcon, 'expanded' => true));
|
||||
$node[$my] = &$node[$up]->addItem($HTML_TreeNode[$my]);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -1383,7 +1383,8 @@ function edit_article()
|
||||
$menu->addItem($node[1]);
|
||||
|
||||
// Create the presentation class
|
||||
$listBox = & ref_new(new HTML_TreeMenu_Listbox($menu));
|
||||
$HTML_TreeMenu_Listbox = new HTML_TreeMenu_Listbox($menu);
|
||||
$listBox = & ref_new($HTML_TreeMenu_Listbox);
|
||||
|
||||
/* Print header */
|
||||
require_once(HESK_PATH . 'inc/headerAdmin.inc.php');
|
||||
@ -1459,6 +1460,7 @@ function edit_article()
|
||||
theme : "advanced",
|
||||
convert_urls : false,
|
||||
gecko_spellcheck: true,
|
||||
plugins: "autolink",
|
||||
|
||||
theme_advanced_buttons1 : "cut,copy,paste,|,undo,redo,|,formatselect,fontselect,fontsizeselect,|,bold,italic,underline,strikethrough,|,justifyleft,justifycenter,justifyright,justifyfull",
|
||||
theme_advanced_buttons2 : "sub,sup,|,charmap,|,bullist,numlist,|,outdent,indent,insertdate,inserttime,preview,|,forecolor,backcolor,|,hr,removeformat,visualaid,|,link,unlink,anchor,image,cleanup,code",
|
||||
@ -1526,7 +1528,7 @@ function edit_article()
|
||||
|
||||
<?php
|
||||
build_dropzone_markup(true);
|
||||
display_dropzone_field($hesk_settings['hesk_url'] . '/internal-api/admin/knowledgebase/upload-attachment.php');
|
||||
display_dropzone_field(HESK_PATH . 'internal-api/admin/knowledgebase/upload-attachment.php');
|
||||
?>
|
||||
</div>
|
||||
<?php endif; //End attachments ?>
|
||||
@ -1609,6 +1611,9 @@ function manage_category() {
|
||||
|
||||
foreach ($kb_cat as $k=>$cat)
|
||||
{
|
||||
if ($cat['id'] == $catid) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (in_array($cat['parent'],$thislevel))
|
||||
{
|
||||
@ -1621,7 +1626,8 @@ function manage_category() {
|
||||
|
||||
if (isset($node[$up]))
|
||||
{
|
||||
$node[$my] = &$node[$up]->addItem(new HTML_TreeNode(array('hesk_parent' => $this_cat['parent'], 'text' => 'Text', 'text_short' => $text_short, 'hesk_catid' => $cat['id'], 'hesk_select' => 'option'.$j, 'icon' => $icon, 'expandedIcon' => $expandedIcon, 'expanded' => true)));
|
||||
$HTML_TreeNode[$my] = new HTML_TreeNode(array('hesk_parent' => $this_cat['parent'], 'text' => 'Text', 'text_short' => $text_short, 'hesk_catid' => $cat['id'], 'hesk_select' => 'option'.$j, 'icon' => $icon, 'expandedIcon' => $expandedIcon, 'expanded' => true));
|
||||
$node[$my] = &$node[$up]->addItem($HTML_TreeNode[$my]);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -1651,7 +1657,8 @@ function manage_category() {
|
||||
$menu->addItem($node[1]);
|
||||
|
||||
// Create the presentation class
|
||||
$listBox = & ref_new(new HTML_TreeMenu_Listbox($menu));
|
||||
$HTML_TreeMenu_Listbox = new HTML_TreeMenu_Listbox($menu);
|
||||
$listBox = & ref_new($HTML_TreeMenu_Listbox);
|
||||
|
||||
/* Print header */
|
||||
require_once(HESK_PATH . 'inc/headerAdmin.inc.php');
|
||||
@ -1872,10 +1879,10 @@ function manage_category() {
|
||||
echo '<img src="../img/blank.gif" width="16" height="16" alt="" style="padding:3px;border:none;vertical-align:text-bottom;" /> <img src="../img/blank.gif" width="16" height="16" alt="" style="padding:3px;border:none;vertical-align:text-bottom;" />';
|
||||
}
|
||||
?>
|
||||
<a href="manage_knowledgebase.php?a=sticky&s=<?php echo $article['sticky'] ? 0 : 1 ?>&id=<?php echo $article['id']; ?>&catid=<?php echo $catid; ?>&token=<?php hesk_token_echo(); ?>"><i class="glyphicon glyphicon-pushpin icon-link" style="color:<?php if ( ! $article['sticky']) {echo 'gray';} else {echo 'red';} ?>" data-toggle="tooltip" data-placement="top" title="<?php if (!$article['sticky']) {echo $hesklang['stickyon'];} else {echo $hesklang['stickyoff'];} ?>"></i></a>
|
||||
<a name="Sticky <?php echo $article['subject']; ?>" href="manage_knowledgebase.php?a=sticky&s=<?php echo $article['sticky'] ? 0 : 1 ?>&id=<?php echo $article['id']; ?>&catid=<?php echo $catid; ?>&token=<?php hesk_token_echo(); ?>"><i class="glyphicon glyphicon-pushpin icon-link" style="color:<?php if ( ! $article['sticky']) {echo 'gray';} else {echo 'red';} ?>" data-toggle="tooltip" data-placement="top" title="<?php if (!$article['sticky']) {echo $hesklang['stickyon'];} else {echo $hesklang['stickyoff'];} ?>"></i></a>
|
||||
<a href="knowledgebase_private.php?article=<?php echo $article['id']; ?>&back=1<?php if ($article['type'] == 2) {echo '&draft=1';} ?>" target="_blank"><i class="fa fa-file-o icon-link" data-toggle="tooltip" data-placement="top" title="<?php echo $hesklang['viewart'] ?>"></i></a>
|
||||
<a href="manage_knowledgebase.php?a=edit_article&id=<?php echo $article['id']; ?>"><i class="fa fa-pencil" style="color:orange;font-size:16px" data-toggle="tooltip" data-placement="top" title="<?php echo $hesklang['edit'] ?>"></i></a>
|
||||
<a href="manage_knowledgebase.php?a=remove_article&id=<?php echo $article['id']; ?>&token=<?php hesk_token_echo(); ?>" onclick="return hesk_confirmExecute('<?php echo hesk_makeJsString($hesklang['del_art']); ?>');"><i class="fa fa-times icon-link red" data-toggle="tooltip" data-placement="top" title="<?php echo $hesklang['delete'] ?>"></i></a> </td>
|
||||
<a name="Edit <?php echo $article['subject']; ?>" href="manage_knowledgebase.php?a=edit_article&id=<?php echo $article['id']; ?>"><i class="fa fa-pencil" style="color:orange;font-size:16px" data-toggle="tooltip" data-placement="top" title="<?php echo $hesklang['edit'] ?>"></i></a>
|
||||
<a name="Delete <?php echo $article['subject']; ?>" href="manage_knowledgebase.php?a=remove_article&id=<?php echo $article['id']; ?>&token=<?php hesk_token_echo(); ?>" onclick="return hesk_confirmExecute('<?php echo hesk_makeJsString($hesklang['del_art']); ?>');"><i class="fa fa-times icon-link red" data-toggle="tooltip" data-placement="top" title="<?php echo $hesklang['delete'] ?>"></i></a> </td>
|
||||
</tr>
|
||||
<?php
|
||||
$j++;
|
||||
@ -2172,6 +2179,9 @@ function remove_article()
|
||||
hesk_dbQuery("UPDATE `".hesk_dbEscape($hesk_settings['db_pfix'])."kb_categories` SET `articles_draft`=`articles_draft`-1 WHERE `id`='{$catid}'");
|
||||
}
|
||||
|
||||
// Clear KB cache
|
||||
hesk_purge_cache('kb');
|
||||
|
||||
// Redirect to the correct page
|
||||
switch ($from) {
|
||||
case 'draft':
|
||||
|
@ -39,10 +39,6 @@ if ($action = hesk_REQUEST('a')) {
|
||||
create();
|
||||
} elseif ($action == 'delete') {
|
||||
deleteTemplate();
|
||||
} elseif ($action == 'addadmin') {
|
||||
toggleAdmin(true);
|
||||
} elseif ($action == 'deladmin') {
|
||||
toggleAdmin(false);
|
||||
}
|
||||
}
|
||||
|
||||
@ -51,34 +47,20 @@ require_once(HESK_PATH . 'inc/headerAdmin.inc.php');
|
||||
|
||||
/* Print main manage users page */
|
||||
require_once(HESK_PATH . 'inc/show_admin_nav.inc.php');
|
||||
?>
|
||||
|
||||
<script language="Javascript" type="text/javascript"><!--
|
||||
function confirm_delete() {
|
||||
if (confirm('<?php echo hesk_makeJsString($hesklang['confirm_del_cat']); ?>')) {
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
//-->
|
||||
</script>
|
||||
|
||||
<?php
|
||||
$modsForHesk_settings = mfh_getSettings();
|
||||
|
||||
$res = hesk_dbQuery("SELECT * FROM `" . hesk_dbEscape($hesk_settings['db_pfix']) . "permission_templates` ORDER BY `name` ASC");
|
||||
$templates = array();
|
||||
while ($row = hesk_dbFetchAssoc($res)) {
|
||||
array_push($templates, $row);
|
||||
$templates[] = $row;
|
||||
}
|
||||
$featureArray = hesk_getFeatureArray();
|
||||
$orderBy = $modsForHesk_settings['category_order_column'];
|
||||
$res = hesk_dbQuery("SELECT * FROM `" . hesk_dbEscape($hesk_settings['db_pfix']) . "categories` ORDER BY `" . $orderBy . "` ASC");
|
||||
$categories = array();
|
||||
while ($row = hesk_dbFetchAssoc($res)) {
|
||||
array_push($categories, $row);
|
||||
$categories[] = $row;
|
||||
}
|
||||
?>
|
||||
<div class="content-wrapper">
|
||||
@ -87,9 +69,9 @@ while ($row = hesk_dbFetchAssoc($res)) {
|
||||
<div class="box">
|
||||
<div class="box-header with-border">
|
||||
<h1 class="box-title">
|
||||
<?php echo $hesklang['manage_permission_templates']; ?>
|
||||
<?php echo $hesklang['manage_permission_groups']; ?>
|
||||
<i class="fa fa-question-circle settingsquestionmark" data-toggle="tooltip" data-placement="right"
|
||||
title="<?php echo $hesklang['manage_permission_templates_help']; ?>"></i>
|
||||
title="<?php echo $hesklang['manage_permission_groups_help']; ?>"></i>
|
||||
</h1>
|
||||
<div class="box-tools pull-right">
|
||||
<button type="button" class="btn btn-box-tool" data-widget="collapse">
|
||||
@ -98,14 +80,19 @@ while ($row = hesk_dbFetchAssoc($res)) {
|
||||
</div>
|
||||
</div>
|
||||
<div class="box-body">
|
||||
<div class="text-right">
|
||||
<a href="#" data-toggle="modal" data-target="#modal-template-new" class="btn btn-success nu-floatRight">
|
||||
<i class="fa fa-plus-circle"></i> <?php echo $hesklang['create_new_template']; ?>
|
||||
<i class="fa fa-plus-circle"></i> <?php echo $hesklang['create_new']; ?>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<table class="table table-striped">
|
||||
<thead>
|
||||
<tr>
|
||||
<th><?php echo $hesklang['name']; ?></th>
|
||||
<th><?php echo $hesklang['number_of_users']; ?></th>
|
||||
<th><?php echo $hesklang['actions']; ?></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php foreach ($templates as $row): ?>
|
||||
@ -114,30 +101,13 @@ while ($row = hesk_dbFetchAssoc($res)) {
|
||||
<td><?php echo getNumberOfUsersWithPermissionGroup($row['id']); ?></td>
|
||||
<td>
|
||||
<a href="#" data-toggle="modal" data-target="#modal-template-<?php echo $row['id'] ?>">
|
||||
<i class="fa fa-pencil icon-link" data-toggle="tooltip"
|
||||
title="<?php echo $hesklang['view_permissions_for_this_template'] ?>"></i></a>
|
||||
<?php if ($row['id'] == 1) { ?>
|
||||
<i class="fa fa-star icon-link orange" data-toggle="tooltip"
|
||||
title="<?php echo $hesklang['admin_cannot_be_staff']; ?>"></i></a>
|
||||
<?php } elseif ($row['heskprivileges'] == 'ALL' && $row['categories'] == 'ALL'){ ?>
|
||||
<a href="manage_permission_templates.php?a=deladmin&id=<?php echo $row['id']; ?>">
|
||||
<i class="fa fa-star icon-link orange" data-toggle="tooltip"
|
||||
title="<?php echo $hesklang['template_has_admin_privileges']; ?>"></i></a>
|
||||
<?php } elseif ($row['id'] != 2) { ?>
|
||||
<a href="manage_permission_templates.php?a=addadmin&id=<?php echo $row['id']; ?>">
|
||||
<i class="fa fa-star-o icon-link gray" data-toggle="tooltip"
|
||||
title="<?php echo $hesklang['template_has_no_admin_privileges']; ?>"></i></a>
|
||||
<i class="fa fa-fw fa-pencil icon-link orange" data-toggle="tooltip"
|
||||
title="<?php echo $hesklang['view_permissions_for_this_group'] ?>"></i></a>
|
||||
<?php
|
||||
} else {
|
||||
?>
|
||||
<i class="fa fa-star-o icon-link gray" data-toggle="tooltip"
|
||||
title="<?php echo $hesklang['staff_cannot_be_admin']; ?>"></i>
|
||||
<?php
|
||||
}
|
||||
if ($row['id'] != 1 && $row['id'] != 2):
|
||||
?>
|
||||
<a href="manage_permission_templates.php?a=delete&id=<?php echo $row['id']; ?>">
|
||||
<i class="fa fa-times icon-link red" data-toggle="tooltip"
|
||||
<a href="manage_permission_groups.php?a=delete&id=<?php echo $row['id']; ?>">
|
||||
<i class="fa fa-fw fa-times icon-link red" data-toggle="tooltip"
|
||||
title="<?php echo $hesklang['delete']; ?>"></i></a>
|
||||
<?php endif; ?>
|
||||
</td>
|
||||
@ -172,13 +142,9 @@ function createEditModal($template, $features, $categories)
|
||||
{
|
||||
global $hesklang;
|
||||
|
||||
$showNotice = true;
|
||||
$disabled = 'checked="checked" disabled';
|
||||
$enabledFeatures = array();
|
||||
$enabledCategories = array();
|
||||
if ($template['heskprivileges'] != 'ALL') {
|
||||
$showNotice = false;
|
||||
$disabled = '';
|
||||
if ($template['heskprivileges'] !== 'ALL') {
|
||||
$enabledFeatures = explode(',', $template['heskprivileges']);
|
||||
$enabledCategories = explode(',', $template['categories']);
|
||||
}
|
||||
@ -187,30 +153,29 @@ function createEditModal($template, $features, $categories)
|
||||
aria-labelledby="myLargeModalLabel" aria-hidden="true">
|
||||
<div class="modal-dialog modal-lg">
|
||||
<div class="modal-content">
|
||||
<form action="manage_permission_templates.php" role="form" method="post" id="form<?php echo $template['id']; ?>">
|
||||
<form action="manage_permission_groups.php" role="form" method="post" id="form<?php echo $template['id']; ?>">
|
||||
<div class="modal-header">
|
||||
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span
|
||||
aria-hidden="true">×</span></button>
|
||||
<h4 class="modal-title"><?php echo sprintf($hesklang['permissions_for_template'], $template['name']); ?></h4>
|
||||
<h4 class="modal-title"><?php echo sprintf($hesklang['permissions_for_group'], $template['name']); ?></h4>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<div class="row">
|
||||
<?php if ($showNotice): ?>
|
||||
<div class="col-sm-12">
|
||||
<?php if ($template['id'] == 1): ?>
|
||||
<div class="alert alert-info">
|
||||
<i class="fa fa-info-circle"></i> <?php echo $hesklang['template_is_admin_cannot_change']; ?>
|
||||
</div>
|
||||
<i class="fa fa-info-circle"></i>
|
||||
<?php echo $hesklang['protected_group']; ?>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
<div class="row">
|
||||
<div class="form-group">
|
||||
<div class="col-sm-2">
|
||||
<label for="name"
|
||||
class="control-label"><?php echo $hesklang['template_name']; ?></label>
|
||||
class="control-label"><?php echo $hesklang['group_name']; ?></label>
|
||||
</div>
|
||||
<div class="col-sm-10">
|
||||
<input type="text" class="form-control" name="name"
|
||||
value="<?php echo htmlspecialchars($template['name']); ?>"
|
||||
placeholder="<?php echo htmlspecialchars($hesklang['template_name']); ?>"
|
||||
placeholder="<?php echo htmlspecialchars($hesklang['group_name']); ?>"
|
||||
data-error="<?php echo htmlspecialchars($hesklang['this_field_is_required']); ?>"
|
||||
required>
|
||||
<div class="help-block with-errors"></div>
|
||||
@ -223,20 +188,34 @@ function createEditModal($template, $features, $categories)
|
||||
|
||||
<div class="footerWithBorder blankSpace"></div>
|
||||
<div class="form-group">
|
||||
<?php foreach ($categories as $category): ?>
|
||||
<?php
|
||||
foreach ($categories as $category):
|
||||
$can_man_categories = hesk_checkPermission('can_man_cat', 0);
|
||||
|
||||
$checked = '';
|
||||
$disabled = '';
|
||||
if (in_array($category['id'], $enabledCategories) ||
|
||||
$template['categories'] == 'ALL') {
|
||||
$checked = 'checked ';
|
||||
}
|
||||
if ((!hesk_SESSION('isadmin') &&
|
||||
!in_array($category['id'], $_SESSION['categories']) &&
|
||||
!$can_man_categories) ||
|
||||
$template['categories'] === 'ALL') {
|
||||
$disabled = ' disabled';
|
||||
}
|
||||
|
||||
if ($_SESSION['isadmin'] || $can_man_categories || in_array($category['id'], $_SESSION['categories']) || $checked): ?>
|
||||
<div class="checkbox">
|
||||
<label>
|
||||
<?php
|
||||
$checked = '';
|
||||
if (in_array($category['id'], $enabledCategories) && !$showNotice) {
|
||||
$checked = 'checked';
|
||||
} ?>
|
||||
<input type="checkbox" name="categories[]"
|
||||
value="<?php echo $category['id']; ?>" <?php echo $checked . $disabled; ?>>
|
||||
value="<?php echo $category['id']; ?>" <?php echo $checked . ' ' . $disabled; ?>>
|
||||
<?php echo $category['name']; ?>
|
||||
</label>
|
||||
</div>
|
||||
<?php endforeach; ?>
|
||||
<?php
|
||||
endif;
|
||||
endforeach; ?>
|
||||
<div class="help-block with-errors"></div>
|
||||
</div>
|
||||
</div>
|
||||
@ -245,19 +224,30 @@ function createEditModal($template, $features, $categories)
|
||||
|
||||
<div class="footerWithBorder blankSpace"></div>
|
||||
<div class="form-group">
|
||||
<?php foreach ($features as $feature): ?>
|
||||
<div class="checkbox">
|
||||
<label><?php
|
||||
<?php
|
||||
foreach ($features as $feature): ?>
|
||||
<?php
|
||||
$checked = '';
|
||||
if (in_array($feature, $enabledFeatures) && !$showNotice) {
|
||||
$checked = 'checked';
|
||||
} ?>
|
||||
$disabled = '';
|
||||
if (in_array($feature, $enabledFeatures) ||
|
||||
$template['heskprivileges'] === 'ALL') {
|
||||
$checked = 'checked ';
|
||||
}
|
||||
if ((!hesk_SESSION('isadmin') &&
|
||||
strpos($_SESSION['heskprivileges'], $feature) === false) ||
|
||||
$template['heskprivileges'] === 'ALL') {
|
||||
$disabled = ' disabled';
|
||||
}
|
||||
if ($_SESSION['isadmin'] || strpos($_SESSION['heskprivileges'], $feature) !== false || $checked): ?>
|
||||
<div class="checkbox">
|
||||
<label>
|
||||
<input type="checkbox" name="features[]"
|
||||
value="<?php echo $feature; ?>" <?php echo $checked . $disabled; ?>>
|
||||
<?php echo $hesklang[$feature]; ?>
|
||||
</label>
|
||||
</div>
|
||||
<?php endforeach; ?>
|
||||
<?php endif;
|
||||
endforeach; ?>
|
||||
<div class="help-block with-errors"></div>
|
||||
</div>
|
||||
</div>
|
||||
@ -266,9 +256,6 @@ function createEditModal($template, $features, $categories)
|
||||
<div class="modal-footer">
|
||||
<input type="hidden" name="a" value="save">
|
||||
<input type="hidden" name="template_id" value="<?php echo $template['id']; ?>">
|
||||
<?php if ($showNotice): ?>
|
||||
<input type="hidden" name="name_only" value="1">
|
||||
<?php endif; ?>
|
||||
<div class="btn-group">
|
||||
<input type="submit" class="btn btn-success"
|
||||
value="<?php echo $hesklang['save_changes']; ?>">
|
||||
@ -291,22 +278,22 @@ function buildCreateModal($features, $categories)
|
||||
aria-hidden="true">
|
||||
<div class="modal-dialog modal-lg">
|
||||
<div class="modal-content">
|
||||
<form action="manage_permission_templates.php" role="form" method="post" id="createForm">
|
||||
<form action="manage_permission_groups.php" role="form" method="post" id="createForm">
|
||||
<div class="modal-header">
|
||||
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span
|
||||
aria-hidden="true">×</span></button>
|
||||
<h4 class="modal-title"><?php echo $hesklang['create_new_template_title']; ?></h4>
|
||||
<h4 class="modal-title"><?php echo $hesklang['create_new_group_title']; ?></h4>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<div class="row">
|
||||
<div class="form-group">
|
||||
<div class="col-sm-2">
|
||||
<label for="name"
|
||||
class="control-label"><?php echo $hesklang['template_name']; ?></label>
|
||||
class="control-label"><?php echo $hesklang['group_name']; ?></label>
|
||||
</div>
|
||||
<div class="col-sm-10">
|
||||
<input type="text" class="form-control" name="name"
|
||||
placeholder="<?php echo $hesklang['template_name']; ?>" required>
|
||||
placeholder="<?php echo $hesklang['group_name']; ?>" required>
|
||||
<div class="help-block with-errors"></div>
|
||||
</div>
|
||||
</div>
|
||||
@ -317,7 +304,9 @@ function buildCreateModal($features, $categories)
|
||||
|
||||
<div class="footerWithBorder blankSpace"></div>
|
||||
<div class="form-group">
|
||||
<?php foreach ($categories as $category): ?>
|
||||
<?php
|
||||
foreach ($categories as $category):
|
||||
if (hesk_SESSION('isadmin') || in_array($category['id'], $_SESSION['categories'])): ?>
|
||||
<div class="checkbox">
|
||||
<label>
|
||||
<input type="checkbox" name="categories[]"
|
||||
@ -327,7 +316,7 @@ function buildCreateModal($features, $categories)
|
||||
<?php echo $category['name']; ?>
|
||||
</label>
|
||||
</div>
|
||||
<?php endforeach; ?>
|
||||
<?php endif; endforeach; ?>
|
||||
<div class="help-block with-errors"></div>
|
||||
</div>
|
||||
</div>
|
||||
@ -336,7 +325,9 @@ function buildCreateModal($features, $categories)
|
||||
|
||||
<div class="footerWithBorder blankSpace"></div>
|
||||
<div class="form-group">
|
||||
<?php foreach ($features as $feature): ?>
|
||||
<?php foreach ($features as $feature):
|
||||
if (strpos($_SESSION['heskprivileges'], $feature) !== false || hesk_SESSION('isadmin')):
|
||||
?>
|
||||
<div class="checkbox">
|
||||
<label>
|
||||
<input type="checkbox" name="features[]"
|
||||
@ -346,7 +337,7 @@ function buildCreateModal($features, $categories)
|
||||
<?php echo $hesklang[$feature]; ?>
|
||||
</label>
|
||||
</div>
|
||||
<?php endforeach; ?>
|
||||
<?php endif; endforeach; ?>
|
||||
<div class="help-block with-errors"></div>
|
||||
</div>
|
||||
</div>
|
||||
@ -381,13 +372,6 @@ function save()
|
||||
WHERE `id` = " . intval($templateId));
|
||||
$row = hesk_dbFetchAssoc($res);
|
||||
|
||||
if (hesk_POST('name_only', 0)) {
|
||||
// We are only able to update the name
|
||||
$name = hesk_POST('name');
|
||||
|
||||
hesk_dbQuery("UPDATE `" . hesk_dbEscape($hesk_settings['db_pfix']) . "permission_templates`
|
||||
SET `name` = '" . hesk_dbEscape($name) . "' WHERE `id` = " . intval($templateId));
|
||||
} else {
|
||||
// Add 'can ban emails' if 'can unban emails' is set (but not added). Same with 'can ban ips'
|
||||
$catArray = hesk_POST_array('categories');
|
||||
$featArray = hesk_POST_array('features');
|
||||
@ -402,19 +386,54 @@ function save()
|
||||
$features = implode(',', $featArray);
|
||||
$name = hesk_POST('name');
|
||||
|
||||
// Only allow users to add what they are allowed to add
|
||||
// Admins can handle anything
|
||||
if (!$_SESSION['isadmin']) {
|
||||
// Update categories based on user visibility
|
||||
$originalCategories = explode(',', $row['categories']);
|
||||
$newCategories = array();
|
||||
foreach ($originalCategories as $innerCategory) {
|
||||
if (in_array($innerCategory, $catArray) && in_array($innerCategory, $_SESSION['categories'])) {
|
||||
$newCategories[] = $innerCategory;
|
||||
} elseif (!in_array($innerCategory, $catArray) && !in_array($innerCategory, $_SESSION['categories'])) {
|
||||
// The user can't modify this, so keep it in
|
||||
$newCategories[] = $innerCategory;
|
||||
}
|
||||
// If neither, the user removed it.
|
||||
}
|
||||
|
||||
// Update features based on user visibility
|
||||
$originalFeatures = explode(',', $row['heskprivileges']);
|
||||
$newFeatures = array();
|
||||
foreach ($originalFeatures as $innerFeature) {
|
||||
if (in_array($innerFeature, $featArray) && strpos($_SESSION['heskprivileges'], $innerFeature) !== false) {
|
||||
$newFeatures[] = $innerFeature;
|
||||
} elseif (!in_array($innerFeature, $featArray) && strpos($_SESSION['heskprivileges'], $innerFeature) === false) {
|
||||
// The user can't modify this, so keep it in
|
||||
$newFeatures[] = $innerFeature;
|
||||
}
|
||||
// If neither, the user removed it.
|
||||
}
|
||||
|
||||
$categories = implode(',', $newCategories);
|
||||
$features = implode(',', $newFeatures);
|
||||
}
|
||||
|
||||
|
||||
|
||||
hesk_dbQuery("UPDATE `" . hesk_dbEscape($hesk_settings['db_pfix']) . "permission_templates`
|
||||
SET `categories` = '" . hesk_dbEscape($categories) . "', `heskprivileges` = '" . hesk_dbEscape($features) . "',
|
||||
`name` = '" . hesk_dbEscape($name) . "'
|
||||
WHERE `id` = " . intval($templateId));
|
||||
|
||||
if ($row['categories'] != $categories || $row['heskprivileges'] != $features) {
|
||||
// Any users with this template should be switched to "custom"
|
||||
hesk_dbQuery("UPDATE `" . hesk_dbEscape($hesk_settings['db_pfix']) . "users` SET `permission_template` = NULL
|
||||
// Any users with this template should have their permissions updated
|
||||
hesk_dbQuery("UPDATE `" . hesk_dbEscape($hesk_settings['db_pfix']) . "users` SET `heskprivileges` = '" . hesk_dbEscape($features) . "',
|
||||
`categories` = '" . hesk_dbEscape($categories) . "'
|
||||
WHERE `permission_template` = " . intval($templateId));
|
||||
}
|
||||
}
|
||||
|
||||
hesk_process_messages($hesklang['permission_template_updated'], $_SERVER['PHP_SELF'], 'SUCCESS');
|
||||
hesk_process_messages($hesklang['permission_group_updated'], $_SERVER['PHP_SELF'], 'SUCCESS');
|
||||
}
|
||||
|
||||
function create()
|
||||
@ -439,7 +458,7 @@ function create()
|
||||
hesk_dbQuery("INSERT INTO `" . hesk_dbEscape($hesk_settings['db_pfix']) . "permission_templates` (`name`, `heskprivileges`, `categories`)
|
||||
VALUES ('" . hesk_dbEscape($name) . "', '" . hesk_dbEscape($features) . "', '" . hesk_dbEscape($categories) . "')");
|
||||
|
||||
hesk_process_messages($hesklang['template_created'], $_SERVER['PHP_SELF'], 'SUCCESS');
|
||||
hesk_process_messages($hesklang['group_created'], $_SERVER['PHP_SELF'], 'SUCCESS');
|
||||
}
|
||||
|
||||
function validate($features, $categories, $create = false, $name = '')
|
||||
@ -449,7 +468,7 @@ function validate($features, $categories, $create = false, $name = '')
|
||||
$errorMarkup = '<ul>';
|
||||
$isValid = true;
|
||||
if ($create && $name == '') {
|
||||
$errorMarkup .= '<li>' . $hesklang['template_name_required'] . '</li>';
|
||||
$errorMarkup .= '<li>' . $hesklang['group_name_required'] . '</li>';
|
||||
$isValid = false;
|
||||
}
|
||||
if (count($features) == 0) {
|
||||
@ -463,7 +482,7 @@ function validate($features, $categories, $create = false, $name = '')
|
||||
$errorMarkup .= '</ul>';
|
||||
|
||||
if (!$isValid) {
|
||||
$error = sprintf($hesklang['permission_template_error'], $errorMarkup);
|
||||
$error = sprintf($hesklang['permission_group_error'], $errorMarkup);
|
||||
hesk_process_messages($error, $_SERVER['PHP_SELF']);
|
||||
}
|
||||
return true;
|
||||
@ -483,36 +502,14 @@ function deleteTemplate()
|
||||
// Otherwise delete the template
|
||||
hesk_dbQuery("DELETE FROM `" . hesk_dbEscape($hesk_settings['db_pfix']) . "permission_templates` WHERE `id` = " . intval($id));
|
||||
if (hesk_dbAffectedRows() != 1) {
|
||||
hesk_process_messages($hesklang['no_templates_were_deleted'], $_SERVER['PHP_SELF']);
|
||||
}
|
||||
hesk_process_messages($hesklang['permission_template_deleted'], $_SERVER['PHP_SELF'], 'SUCCESS');
|
||||
}
|
||||
|
||||
function toggleAdmin($admin)
|
||||
{
|
||||
global $hesk_settings, $hesklang;
|
||||
|
||||
$id = hesk_GET('id');
|
||||
|
||||
if ($id == 1 || $id == 2) {
|
||||
hesk_process_messages($hesklang['cannot_change_admin_staff'], $_SERVER['PHP_SELF']);
|
||||
hesk_process_messages($hesklang['no_group_were_deleted'], $_SERVER['PHP_SELF']);
|
||||
}
|
||||
|
||||
if ($admin) {
|
||||
hesk_dbQuery("UPDATE `" . hesk_dbEscape($hesk_settings['db_pfix']) . "permission_templates` SET `heskprivileges` = 'ALL',
|
||||
`categories` = 'ALL' WHERE `id` = " . intval($id));
|
||||
hesk_process_messages($hesklang['permission_template_now_admin'], $_SERVER['PHP_SELF'], 'SUCCESS');
|
||||
} else {
|
||||
// Get default privileges
|
||||
$res = hesk_dbQuery("SELECT `heskprivileges`, `categories` FROM `" . hesk_dbEscape($hesk_settings['db_pfix']) . "permission_templates`
|
||||
WHERE `id` = 2");
|
||||
$row = hesk_dbFetchAssoc($res);
|
||||
// Move all users who used to be in this group to "custom"
|
||||
hesk_dbQuery("UPDATE `" . hesk_dbEscape($hesk_settings['db_pfix']) . "users` SET `permission_template` = NULL
|
||||
WHERE `permission_template` = " . intval($id));
|
||||
|
||||
hesk_dbQuery("UPDATE `" . hesk_dbEscape($hesk_settings['db_pfix']) . "permission_templates`
|
||||
SET `heskprivileges` = '" . hesk_dbEscape($row['heskprivileges']) . "',
|
||||
`categories` = '" . hesk_dbEscape($row['categories']) . "' WHERE `id` = " . intval($id));
|
||||
hesk_process_messages($hesklang['permission_template_no_longer_admin'], $_SERVER['PHP_SELF'], 'SUCCESS');
|
||||
}
|
||||
hesk_process_messages($hesklang['permission_group_deleted'], $_SERVER['PHP_SELF'], 'SUCCESS');
|
||||
}
|
||||
|
||||
?>
|
@ -132,7 +132,7 @@ require_once(HESK_PATH . 'inc/show_admin_nav.inc.php');
|
||||
<table class="table table-hover">
|
||||
<thead>
|
||||
<tr>
|
||||
<th><?php echo $hesklang['name']; ?></th>
|
||||
<th><?php echo $hesklang['status_name_title']; ?></th>
|
||||
<th><?php echo $hesklang['closable_question']; ?></th>
|
||||
<th><?php echo $hesklang['closedQuestionMark']; ?></th>
|
||||
<th><?php echo $hesklang['actions']; ?></th>
|
||||
|
@ -159,7 +159,7 @@ $num = hesk_dbNumRows($result);
|
||||
}
|
||||
|
||||
echo '
|
||||
<a href="manage_ticket_templates.php?a=remove&id=' . $mysaved['id'] . '&token=' . hesk_token_echo(0) . '" onclick="return confirm_delete();"><i class="fa fa-times icon-link red" data-toggle="tooltip" data-placement="top" data-original-title="' . $hesklang['delete'] . '"></i></a></td>
|
||||
<a name="'.$mysaved['title'].'" href="manage_ticket_templates.php?a=remove&id=' . $mysaved['id'] . '&token=' . hesk_token_echo(0) . '" onclick="return confirm_delete();"><i class="fa fa-times icon-link red" data-toggle="tooltip" data-placement="top" data-original-title="' . $hesklang['delete'] . '"></i></a></td>
|
||||
</tr>
|
||||
';
|
||||
} // End while
|
||||
@ -286,21 +286,15 @@ $num = hesk_dbNumRows($result);
|
||||
<?php if ($modsForHesk_settings['rich_text_for_tickets']): ?>
|
||||
<script type="text/javascript">
|
||||
/* <![CDATA[ */
|
||||
tinyMCE.init({
|
||||
mode: "textareas",
|
||||
editor_selector: "htmlEditor",
|
||||
elements: "content",
|
||||
theme: "advanced",
|
||||
convert_urls: false,
|
||||
|
||||
theme_advanced_buttons1: "cut,copy,paste,|,undo,redo,|,formatselect,fontselect,fontsizeselect,|,bold,italic,underline,strikethrough,|,justifyleft,justifycenter,justifyright,justifyfull",
|
||||
theme_advanced_buttons2: "sub,sup,|,charmap,|,bullist,numlist,|,outdent,indent,insertdate,inserttime,preview,|,forecolor,backcolor,|,hr,removeformat,visualaid,|,link,unlink,anchor,image,cleanup,code",
|
||||
theme_advanced_buttons3: "",
|
||||
|
||||
theme_advanced_toolbar_location: "top",
|
||||
theme_advanced_toolbar_align: "left",
|
||||
theme_advanced_statusbar_location: "bottom",
|
||||
theme_advanced_resizing: true
|
||||
$(document).ready(function() {
|
||||
$('.htmlEditor').summernote({
|
||||
height: 200,
|
||||
toolbar: [
|
||||
['style', ['bold', 'italic', 'underline', 'clear']],
|
||||
['font', ['strikethrough', 'superscript', 'subscript']],
|
||||
['para', ['ul', 'ol']]
|
||||
]
|
||||
});
|
||||
});
|
||||
/* ]]> */
|
||||
</script>
|
||||
@ -325,8 +319,7 @@ $num = hesk_dbNumRows($result);
|
||||
|
||||
if (myMsg == '') {
|
||||
if (useHtmlEditor) {
|
||||
tinymce.get("message").setContent('');
|
||||
tinymce.get("message").execCommand('mceInsertRawHTML', false, '');
|
||||
$("#message").summernote('reset');
|
||||
}
|
||||
else {
|
||||
$('#message').val('');
|
||||
@ -336,8 +329,8 @@ $num = hesk_dbNumRows($result);
|
||||
}
|
||||
if (document.getElementById) {
|
||||
if (useHtmlEditor) {
|
||||
tinymce.get("message").setContent('');
|
||||
tinymce.get("message").execCommand('mceInsertRawHTML', false, myMsg);
|
||||
$("#message").summernote('reset');
|
||||
$("#message").summernote('editor.insertText', myMsg));
|
||||
} else {
|
||||
myMsg = $('<textarea />').html(myMsg).text();
|
||||
$('#message').val(myMsg).trigger('input');
|
||||
|
@ -42,6 +42,9 @@ $calendar_view_array = array(
|
||||
);
|
||||
$default_view = $calendar_view_array[$modsForHesk_settings['default_calendar_view']];
|
||||
|
||||
$staff_permission_template_rs = hesk_dbQuery("SELECT * FROM `" . hesk_dbEscape($hesk_settings['db_pfix']) . "permission_templates` WHERE `id` = 2");
|
||||
$staff_permission_template = hesk_dbFetchAssoc($staff_permission_template_rs);
|
||||
|
||||
/* Set default values */
|
||||
$default_userdata = array(
|
||||
|
||||
@ -58,12 +61,15 @@ $default_userdata = array(
|
||||
// Permissions
|
||||
'isadmin' => 1,
|
||||
'active' => 1,
|
||||
'categories' => array('1'),
|
||||
'features' => array('can_view_tickets', 'can_reply_tickets', 'can_change_cat', 'can_assign_self', 'can_view_unassigned', 'can_view_online'),
|
||||
'categories' => explode(',', $staff_permission_template['categories']),
|
||||
'features' => explode(',', $staff_permission_template['heskprivileges']),
|
||||
|
||||
// Preferences
|
||||
'afterreply' => 0,
|
||||
|
||||
// Permission template
|
||||
'permission_template' => 2,
|
||||
|
||||
// Defaults
|
||||
'autostart' => 1,
|
||||
'notify_customer_new' => 1,
|
||||
@ -89,7 +95,7 @@ $orderBy = $modsForHesk_settings['category_order_column'];
|
||||
$hesk_settings['categories'] = array();
|
||||
$res = hesk_dbQuery('SELECT `id`,`name` FROM `' . hesk_dbEscape($hesk_settings['db_pfix']) . 'categories` ORDER BY `' . $orderBy . '` ASC');
|
||||
while ($row = hesk_dbFetchAssoc($res)) {
|
||||
if (hesk_okCategory($row['id'], 0)) {
|
||||
if (hesk_checkPermission('can_man_cat', 0) || hesk_okCategory($row['id'], 0)) {
|
||||
$hesk_settings['categories'][$row['id']] = $row['name'];
|
||||
}
|
||||
}
|
||||
@ -161,7 +167,38 @@ if ($action = hesk_REQUEST('a')) {
|
||||
?>
|
||||
<div class="content-wrapper">
|
||||
<section class="content">
|
||||
<?php hesk_handle_messages(); ?>
|
||||
<?php
|
||||
hesk_handle_messages();
|
||||
|
||||
// If POP3 fetching is active, no user should have the same email address
|
||||
if ($hesk_settings['pop3'] && hesk_validateEmail($hesk_settings['pop3_user'], 'ERR', 0)) {
|
||||
$res = hesk_dbQuery("SELECT * FROM `".hesk_dbEscape($hesk_settings['db_pfix'])."users` WHERE `email` LIKE '".hesk_dbEscape($hesk_settings['pop3_user'])."'");
|
||||
|
||||
if (hesk_dbNumRows($res) > 0) {
|
||||
while ($myuser = hesk_dbFetchAssoc($res)) {
|
||||
if (compare_user_permissions($myuser['id'], $myuser['isadmin'], explode(',', $myuser['categories']) , explode(',', $myuser['heskprivileges']))) {
|
||||
hesk_show_notice(sprintf($hesklang['pop3_warning'], $myuser['name'], $hesk_settings['pop3_user']) . "<br /><br />" . $hesklang['fetch_warning'], $hesklang['warn']);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// If IMAP fetching is active, no user should have the same email address
|
||||
if ($hesk_settings['imap'] && hesk_validateEmail($hesk_settings['imap_user'], 'ERR', 0)) {
|
||||
$res = hesk_dbQuery("SELECT * FROM `".hesk_dbEscape($hesk_settings['db_pfix'])."users` WHERE `email` LIKE '".hesk_dbEscape($hesk_settings['imap_user'])."'");
|
||||
|
||||
if (hesk_dbNumRows($res) > 0) {
|
||||
while ($myuser = hesk_dbFetchAssoc($res)) {
|
||||
if (compare_user_permissions($myuser['id'], $myuser['isadmin'], explode(',', $myuser['categories']) , explode(',', $myuser['heskprivileges']))) {
|
||||
hesk_show_notice(sprintf($hesklang['imap_warning'], $myuser['name'], $hesk_settings['imap_user']) . "<br /><br />" . $hesklang['fetch_warning'], $hesklang['warn']);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
<script language="Javascript" type="text/javascript"><!--
|
||||
function confirm_delete() {
|
||||
if (confirm('<?php echo addslashes($hesklang['sure_remove_user']); ?>')) {
|
||||
@ -214,7 +251,7 @@ if ($action = hesk_REQUEST('a')) {
|
||||
<th><b><i><?php echo $hesklang['name']; ?></i></b></th>
|
||||
<th><b><i><?php echo $hesklang['email']; ?></i></b></th>
|
||||
<th><b><i><?php echo $hesklang['username']; ?></i></b></th>
|
||||
<th><b><i><?php echo $hesklang['permission_template']; ?></i></b></th>
|
||||
<th><b><i><?php echo $hesklang['permission_group']; ?></i></b></th>
|
||||
<?php
|
||||
/* Is user rating enabled? */
|
||||
if ($hesk_settings['rating']) {
|
||||
@ -253,19 +290,19 @@ if ($action = hesk_REQUEST('a')) {
|
||||
/* User online? */
|
||||
if ($hesk_settings['online']) {
|
||||
if (isset($hesk_settings['users_online'][$myuser['id']])) {
|
||||
$myuser['name'] = '<i class="fa fa-circle green" data-toggle="tooltip" data-placement="top" title="' . $hesklang['online'] . '"></i> ' . $myuser['name'];
|
||||
$myuser['name'] = '<i class="fa fa-fw fa-circle green" data-toggle="tooltip" data-placement="top" title="' . $hesklang['online'] . '"></i> ' . $myuser['name'];
|
||||
} else {
|
||||
$myuser['name'] = '<i class="fa fa-circle gray" data-toggle="tooltip" data-placement="top" title="' . $hesklang['offline'] . '"></i> ' . $myuser['name'];
|
||||
$myuser['name'] = '<i class="fa fa-fw fa-circle gray" data-toggle="tooltip" data-placement="top" title="' . $hesklang['offline'] . '"></i> ' . $myuser['name'];
|
||||
}
|
||||
}
|
||||
|
||||
/* To edit yourself go to "Profile" page, not here. */
|
||||
if ($myuser['id'] == $_SESSION['id']) {
|
||||
$edit_code = '<a href="profile.php"><i class="fa fa-pencil icon-link orange" data-toggle="tooltip" data-placement="top" title="' . $hesklang['edit'] . '"></i></a>';
|
||||
$edit_code = '<a name="Edit '.$myuser['user'].'" href="profile.php"><i class="fa fa-fw fa-pencil icon-link orange" data-toggle="tooltip" data-placement="top" title="' . $hesklang['edit'] . '"></i></a>';
|
||||
} elseif ($myuser['id'] == 1) {
|
||||
$edit_code = ' <img src="../img/blank.gif" width="16" height="16" alt="" style="padding:3px;border:none;" />';
|
||||
} else {
|
||||
$edit_code = '<a href="manage_users.php?a=edit&id=' . $myuser['id'] . '"><i class="fa fa-pencil icon-link orange" data-toggle="tooltip" data-placement="top" title="' . $hesklang['edit'] . '"></i></a>';
|
||||
$edit_code = '<a name="Edit '.$myuser['user'].'" href="manage_users.php?a=edit&id=' . $myuser['id'] . '"><i class="fa fa-fw fa-pencil icon-link orange" data-toggle="tooltip" data-placement="top" title="' . $hesklang['edit'] . '"></i></a>';
|
||||
}
|
||||
|
||||
if ($myuser['isadmin']) {
|
||||
@ -278,15 +315,15 @@ if ($action = hesk_REQUEST('a')) {
|
||||
if ($myuser['id'] == 1 || $myuser['id'] == $_SESSION['id']) {
|
||||
$remove_code = ' <img src="../img/blank.gif" width="16" height="16" alt="" style="padding:3px;border:none;" />';
|
||||
} else {
|
||||
$remove_code = ' <a href="manage_users.php?a=remove&id=' . $myuser['id'] . '&token=' . hesk_token_echo(0) . '" onclick="return confirm_delete();"><i class="fa fa-times icon-link red" data-toggle="tooltip" data-placement="top" title="' . $hesklang['delete'] . '"></i></a>';
|
||||
$remove_code = ' <a name="Delete '.$myuser['user'].'" href="manage_users.php?a=remove&id=' . $myuser['id'] . '&token=' . hesk_token_echo(0) . '" onclick="return confirm_delete();"><i class="fa fa-fw fa-times icon-link red" data-toggle="tooltip" data-placement="top" title="' . $hesklang['delete'] . '"></i></a>';
|
||||
}
|
||||
|
||||
/* Is auto assign enabled? */
|
||||
if ($hesk_settings['autoassign']) {
|
||||
if ($myuser['autoassign']) {
|
||||
$autoassign_code = '<a href="manage_users.php?a=autoassign&s=0&id=' . $myuser['id'] . '&token=' . hesk_token_echo(0) . '"><i class="fa fa-bolt icon-link orange" data-toggle="tooltip" data-placement="top" title="' . $hesklang['aaon'] . '"></i></a>';
|
||||
$autoassign_code = '<a name="Unassign '.$myuser['user'].'" href="manage_users.php?a=autoassign&s=0&id=' . $myuser['id'] . '&token=' . hesk_token_echo(0) . '"><i class="fa fa-fw fa-bolt icon-link orange" data-toggle="tooltip" data-placement="top" title="' . $hesklang['aaon'] . '"></i></a>';
|
||||
} else {
|
||||
$autoassign_code = '<a href="manage_users.php?a=autoassign&s=1&id=' . $myuser['id'] . '&token=' . hesk_token_echo(0) . '"><i class="fa fa-bolt icon-link gray" data-toggle="tooltip" data-placement="top" title="' . $hesklang['aaoff'] . '"></i></a>';
|
||||
$autoassign_code = '<a name="Assign '.$myuser['user'].'" href="manage_users.php?a=autoassign&s=1&id=' . $myuser['id'] . '&token=' . hesk_token_echo(0) . '"><i class="fa fa-fw fa-bolt icon-link gray" data-toggle="tooltip" data-placement="top" title="' . $hesklang['aaoff'] . '"></i></a>';
|
||||
}
|
||||
} else {
|
||||
$autoassign_code = '';
|
||||
@ -296,9 +333,9 @@ if ($action = hesk_REQUEST('a')) {
|
||||
if ($myuser['id'] != $_SESSION['id'] && $myuser['id'] != 1) {
|
||||
/* Is the user active? */
|
||||
if ($myuser['active']) {
|
||||
$activeMarkup = '<a href="manage_users.php?a=active&s=0&id=' . $myuser['id'] . '&token=' . hesk_token_echo(0) . '"><i class="fa fa-user icon-link green" data-toggle="tooltip" data-placement="top" title="' . $hesklang['disable_user'] . '"></i></a>';
|
||||
$activeMarkup = '<a href="manage_users.php?a=active&s=0&id=' . $myuser['id'] . '&token=' . hesk_token_echo(0) . '"><i class="fa fa-fw fa-user icon-link green" data-toggle="tooltip" data-placement="top" title="' . $hesklang['disable_user'] . '"></i></a>';
|
||||
} else {
|
||||
$activeMarkup = '<a href="manage_users.php?a=active&s=1&id=' . $myuser['id'] . '&token=' . hesk_token_echo(0) . '"><i class="fa fa-user icon-link gray" data-toggle="tooltip" data-placement="top" title="' . $hesklang['enable_user'] . '"></i></a>';
|
||||
$activeMarkup = '<a href="manage_users.php?a=active&s=1&id=' . $myuser['id'] . '&token=' . hesk_token_echo(0) . '"><i class="fa fa-fw fa-user icon-link gray" data-toggle="tooltip" data-placement="top" title="' . $hesklang['enable_user'] . '"></i></a>';
|
||||
}
|
||||
}
|
||||
|
||||
@ -321,7 +358,8 @@ EOC;
|
||||
|
||||
if ($hesk_settings['rating']) {
|
||||
$alt = $myuser['rating'] ? sprintf($hesklang['rated'], sprintf("%01.1f", $myuser['rating']), ($myuser['ratingneg'] + $myuser['ratingpos'])) : $hesklang['not_rated'];
|
||||
echo '<td><img src="../img/star_' . (hesk_round_to_half($myuser['rating']) * 10) . '.png" width="85" height="16" alt="' . $alt . '" data-toggle="tooltip" data-placement="top" title="' . $alt . '" border="0" style="vertical-align:text-bottom" /> </td>';
|
||||
|
||||
echo '<td><span data-toggle="tooltip" title="' . $alt . '">'.mfh_get_stars(hesk_round_to_half($myuser['rating'])).'</span></td>';
|
||||
}
|
||||
|
||||
echo <<<EOC
|
||||
@ -333,7 +371,7 @@ EOC;
|
||||
?>
|
||||
</table>
|
||||
<?php if ($hesk_settings['online']) {
|
||||
echo ' <i class="fa fa-circle green"></i> ' . $hesklang['online'] . ' <i class="fa fa-circle gray"></i> ' . $hesklang['offline'];
|
||||
echo ' <i class="fa fa-fw fa-circle green"></i> ' . $hesklang['online'] . ' <i class="fa fa-fw fa-circle gray"></i> ' . $hesklang['offline'];
|
||||
} ?>
|
||||
</div>
|
||||
</div>
|
||||
@ -369,6 +407,11 @@ function compare_user_permissions($compare_id, $compare_isadmin, $compare_catego
|
||||
return false;
|
||||
}
|
||||
|
||||
// Users who can edit categories can see all of them
|
||||
if (hesk_checkPermission('can_man_cat', 0)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Compare categories */
|
||||
foreach ($compare_categories as $catid) {
|
||||
if (!array_key_exists($catid, $hesk_settings['categories'])) {
|
||||
@ -591,6 +634,7 @@ function update_user()
|
||||
$myuser['notify_overdue_unassigned'] = 0;
|
||||
}
|
||||
|
||||
|
||||
/* Check for duplicate usernames */
|
||||
$res = hesk_dbQuery("SELECT `id`,`isadmin`,`categories`,`heskprivileges` FROM `" . hesk_dbEscape($hesk_settings['db_pfix']) . "users` WHERE `user` = '" . hesk_dbEscape($myuser['user']) . "' LIMIT 1");
|
||||
if (hesk_dbNumRows($res) == 1) {
|
||||
@ -735,7 +779,7 @@ function hesk_validateUserInfo($pass_required = 1, $redirect_to = './manage_user
|
||||
}
|
||||
}
|
||||
|
||||
if (strlen($myuser['signature']) > 1000) {
|
||||
if (hesk_mb_strlen($myuser['signature']) > 1000) {
|
||||
$hesk_error_buffer .= '<li>' . $hesklang['signature_long'] . '</li>';
|
||||
}
|
||||
|
||||
@ -847,6 +891,7 @@ function remove()
|
||||
// Revoke manager rights
|
||||
hesk_dbQuery("UPDATE `" . hesk_dbEscape($hesk_settings['db_pfix']) . "categories` SET `manager` = 0 WHERE `manager` = " . intval($myuser));
|
||||
|
||||
|
||||
/* Un-assign all tickets for this user */
|
||||
$res = hesk_dbQuery("UPDATE `" . hesk_dbEscape($hesk_settings['db_pfix']) . "tickets` SET `owner`=0 WHERE `owner`='" . intval($myuser) . "'");
|
||||
|
||||
|
@ -1,32 +1,15 @@
|
||||
<?php
|
||||
/*******************************************************************************
|
||||
* Title: Help Desk Software HESK
|
||||
* Version: 2.6.1 from 26th February 2015
|
||||
* Author: Klemen Stirn
|
||||
* Website: https://www.hesk.com
|
||||
********************************************************************************
|
||||
* COPYRIGHT AND TRADEMARK NOTICE
|
||||
* Copyright 2005-2015 Klemen Stirn. All Rights Reserved.
|
||||
* HESK is a registered trademark of Klemen Stirn.
|
||||
* The HESK may be used and modified free of charge by anyone
|
||||
* AS LONG AS COPYRIGHT NOTICES AND ALL THE COMMENTS REMAIN INTACT.
|
||||
* By using this code you agree to indemnify Klemen Stirn from any
|
||||
* liability that might arise from it's use.
|
||||
* Selling the code for this program, in part or full, without prior
|
||||
* written consent is expressly forbidden.
|
||||
* Using this code, in part or full, to create derivate work,
|
||||
* new scripts or products is expressly forbidden. Obtain permission
|
||||
* before redistributing this software over the Internet or in
|
||||
* any other medium. In all cases copyright and header must remain intact.
|
||||
* This Copyright is in full effect in any country that has International
|
||||
* Trade Agreements with the United States of America or
|
||||
* with the European Union.
|
||||
* Removing any of the copyright notices without purchasing a license
|
||||
* is expressly forbidden. To remove HESK copyright notice you must purchase
|
||||
* a license for this script. For more information on how to obtain
|
||||
* a license please visit the page below:
|
||||
* https://www.hesk.com/buy.php
|
||||
*******************************************************************************/
|
||||
/**
|
||||
*
|
||||
* This file is part of HESK - PHP Help Desk Software.
|
||||
*
|
||||
* (c) Copyright Klemen Stirn. All rights reserved.
|
||||
* https://www.hesk.com
|
||||
*
|
||||
* For the full copyright and license agreement information visit
|
||||
* https://www.hesk.com/eula.php
|
||||
*
|
||||
*/
|
||||
|
||||
define('IN_SCRIPT', 1);
|
||||
define('HESK_PATH', '../');
|
||||
@ -76,7 +59,7 @@ if (!$row['autoassign']) {
|
||||
$category_ok = hesk_okCategory($category, 0);
|
||||
|
||||
// Is user allowed to move tickets to this category?
|
||||
if (!$category_ok && !hesk_checkPermission('can_submit_any_cat', 0)) {
|
||||
if ( ! $category_ok && ! hesk_checkPermission('can_change_cat', 0) ) {
|
||||
hesk_process_messages($hesklang['noauth_move'],'admin_main.php');
|
||||
}
|
||||
|
||||
@ -87,8 +70,6 @@ if (hesk_dbNumRows($res) != 1) {
|
||||
}
|
||||
$ticket = hesk_dbFetchAssoc($res);
|
||||
|
||||
/* Log that ticket is being moved */
|
||||
$history = sprintf($hesklang['thist1'], hesk_date(), $row['name'], $_SESSION['name'] . ' (' . $_SESSION['user'] . ')');
|
||||
|
||||
/* Is the ticket assigned to someone? If yes, check that the user has access to category or change to unassigned */
|
||||
$need_to_reassign = 0;
|
||||
@ -109,18 +90,30 @@ if ($ticket['owner']) {
|
||||
}
|
||||
|
||||
/* Reassign automatically if possible */
|
||||
$autoassign_owner = null;
|
||||
if ($need_to_reassign || !$ticket['owner']) {
|
||||
$need_to_reassign = 1;
|
||||
$autoassign_owner = hesk_autoAssignTicket($category);
|
||||
if ($autoassign_owner) {
|
||||
$ticket['owner'] = $autoassign_owner['id'];
|
||||
$history .= sprintf($hesklang['thist10'], hesk_date(), $autoassign_owner['name'] . ' (' . $autoassign_owner['user'] . ')');
|
||||
} else {
|
||||
$ticket['owner'] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
hesk_dbQuery("UPDATE `" . hesk_dbEscape($hesk_settings['db_pfix']) . "tickets` SET `category`='" . intval($category) . "', `owner`='" . intval($ticket['owner']) . "' , `history`=CONCAT(`history`,'" . hesk_dbEscape($history) . "') WHERE `trackid`='" . hesk_dbEscape($trackingID) . "'");
|
||||
hesk_dbQuery("UPDATE `" . hesk_dbEscape($hesk_settings['db_pfix']) . "tickets` SET `category`='" . intval($category) . "', `owner`='" . intval($ticket['owner']) . "' WHERE `trackid`='" . hesk_dbEscape($trackingID) . "'");
|
||||
|
||||
/* Log that ticket is being moved */
|
||||
mfh_insert_audit_trail_record($ticket['id'], 'TICKET', 'audit_moved_category', hesk_date(), array(
|
||||
0 => $_SESSION['name'] . ' (' . $_SESSION['user'] . ')',
|
||||
1 => $row['name']
|
||||
));
|
||||
|
||||
if ($autoassign_owner) {
|
||||
mfh_insert_audit_trail_record($ticket['id'], 'TICKET', 'audit_autoassigned', hesk_date(), array(
|
||||
0 => $autoassign_owner['name'] . ' (' . $autoassign_owner['user'] . ')'
|
||||
));
|
||||
}
|
||||
|
||||
$ticket['category'] = $category;
|
||||
|
||||
@ -135,13 +128,13 @@ $info = array(
|
||||
'trackid' => $ticket['trackid'],
|
||||
'status' => $ticket['status'],
|
||||
'name' => $ticket['name'],
|
||||
'lastreplier' => $ticket['lastreplier'],
|
||||
'subject' => $ticket['subject'],
|
||||
'message' => $ticket['message'],
|
||||
'attachments' => $ticket['attachments'],
|
||||
'dt' => hesk_date($ticket['dt'], true),
|
||||
'lastchange' => hesk_date($ticket['lastchange'], true),
|
||||
'id' => $ticket['id'],
|
||||
'id' => $ticket['id'],'time_worked' => $ticket['time_worked'],
|
||||
'last_reply_by' => hesk_getReplierName($ticket),
|
||||
);
|
||||
|
||||
// 2. Add custom fields to the array
|
||||
|
@ -113,13 +113,13 @@ require_once(HESK_PATH . 'inc/show_admin_nav.inc.php');
|
||||
$hesk_settings['categories'] = array();
|
||||
|
||||
if (hesk_checkPermission('can_submit_any_cat', 0)) {
|
||||
$res = hesk_dbQuery("SELECT `id`, `name` FROM `".hesk_dbEscape($hesk_settings['db_pfix'])."categories` ORDER BY `cat_order` ASC");
|
||||
$res = hesk_dbQuery("SELECT `id`, `name`, `mfh_description` FROM `".hesk_dbEscape($hesk_settings['db_pfix'])."categories` ORDER BY `cat_order` ASC");
|
||||
} else {
|
||||
$res = hesk_dbQuery("SELECT `id`, `name` FROM `".hesk_dbEscape($hesk_settings['db_pfix'])."categories` WHERE ".hesk_myCategories('id')." ORDER BY `cat_order` ASC");
|
||||
$res = hesk_dbQuery("SELECT `id`, `name`, `mfh_description` FROM `".hesk_dbEscape($hesk_settings['db_pfix'])."categories` WHERE ".hesk_myCategories('id')." ORDER BY `cat_order` ASC");
|
||||
}
|
||||
|
||||
while ($row = hesk_dbFetchAssoc($res)) {
|
||||
$hesk_settings['categories'][$row['id']] = $row['name'];
|
||||
$hesk_settings['categories'][$row['id']] = $row;
|
||||
}
|
||||
|
||||
$number_of_categories = count($hesk_settings['categories']);
|
||||
@ -147,7 +147,7 @@ $show_quick_help = $show['show'];
|
||||
<li><a href="admin_main.php"><?php echo $hesk_settings['hesk_title']; ?></a></li>
|
||||
<?php if ($number_of_categories > 1): ?>
|
||||
<li><a href="new_ticket.php"><?php echo $hesklang['nti2']; ?></a></li>
|
||||
<li class="active"><?php echo $hesk_settings['categories'][$category]; ?></li>
|
||||
<li class="active"><?php echo $hesk_settings['categories'][$category]['name']; ?></li>
|
||||
<?php else: ?>
|
||||
<li class="active"><?php echo $hesklang['nti2']; ?></li>
|
||||
<?php endif; ?>
|
||||
@ -157,6 +157,11 @@ $show_quick_help = $show['show'];
|
||||
/* This will handle error, success and notice messages */
|
||||
hesk_handle_messages();
|
||||
|
||||
$service_messages = mfh_get_service_messages('STAFF_SUBMIT_TICKET');
|
||||
foreach ($service_messages as $sm) {
|
||||
hesk_service_message($sm);
|
||||
}
|
||||
|
||||
if ($show_quick_help): ?>
|
||||
<div class="box">
|
||||
<div class="box-header with-border">
|
||||
@ -193,21 +198,15 @@ $show_quick_help = $show['show'];
|
||||
<?php if ($modsForHesk_settings['rich_text_for_tickets']): ?>
|
||||
<script type="text/javascript">
|
||||
/* <![CDATA[ */
|
||||
tinyMCE.init({
|
||||
mode: "textareas",
|
||||
editor_selector: "htmlEditor",
|
||||
elements: "content",
|
||||
theme: "advanced",
|
||||
convert_urls: false,
|
||||
|
||||
theme_advanced_buttons1: "cut,copy,paste,|,undo,redo,|,formatselect,fontselect,fontsizeselect,|,bold,italic,underline,strikethrough,|,justifyleft,justifycenter,justifyright,justifyfull",
|
||||
theme_advanced_buttons2: "sub,sup,|,charmap,|,bullist,numlist,|,outdent,indent,insertdate,inserttime,preview,|,forecolor,backcolor,|,hr,removeformat,visualaid,|,link,unlink,anchor,image,cleanup,code",
|
||||
theme_advanced_buttons3: "",
|
||||
|
||||
theme_advanced_toolbar_location: "top",
|
||||
theme_advanced_toolbar_align: "left",
|
||||
theme_advanced_statusbar_location: "bottom",
|
||||
theme_advanced_resizing: true
|
||||
$(document).ready(function() {
|
||||
$('.htmlEditor').summernote({
|
||||
height: 200,
|
||||
toolbar: [
|
||||
['style', ['bold', 'italic', 'underline', 'clear']],
|
||||
['font', ['strikethrough', 'superscript', 'subscript']],
|
||||
['para', ['ul', 'ol']]
|
||||
]
|
||||
});
|
||||
});
|
||||
/* ]]> */
|
||||
</script>
|
||||
@ -243,7 +242,7 @@ $show_quick_help = $show['show'];
|
||||
class="important">*</span></label>
|
||||
|
||||
<div class="col-sm-9">
|
||||
<input type="text" class="form-control" name="name" size="40" maxlength="30"
|
||||
<input type="text" class="form-control" name="name" size="40" maxlength="50"
|
||||
value="<?php if (isset($_SESSION['as_name'])) {
|
||||
echo stripslashes(hesk_input($_SESSION['as_name']));
|
||||
} else if (isset($_GET['name'])) {
|
||||
@ -380,6 +379,10 @@ $show_quick_help = $show['show'];
|
||||
</div>';
|
||||
}
|
||||
|
||||
if (!empty($v['mfh_description'])) {
|
||||
echo '<div class="help-block">' . $v['mfh_description'] . '</div>';
|
||||
}
|
||||
|
||||
echo '
|
||||
<div class="help-block with-errors"></div>
|
||||
</div>
|
||||
@ -388,7 +391,6 @@ $show_quick_help = $show['show'];
|
||||
|
||||
/* Select drop-down box */
|
||||
case 'select':
|
||||
|
||||
$cls = in_array($k, $_SESSION['iserror']) ? ' isError' : '';
|
||||
|
||||
echo '<div class="form-group' . $cls . '"><label for="' . $v['name'] . '" class="col-sm-3 control-label">' . $v['name'] . ' ' . $v['req'] . '</label>
|
||||
@ -410,14 +412,23 @@ $show_quick_help = $show['show'];
|
||||
echo '<option ' . $selected . '>' . $option . '</option>';
|
||||
}
|
||||
|
||||
echo '</select>
|
||||
<div class="help-block with-errors"></div></div></div>';
|
||||
echo '</select>';
|
||||
|
||||
|
||||
if (!empty($v['mfh_description'])) {
|
||||
echo '<div class="help-block">' . $v['mfh_description'] . '</div>';
|
||||
}
|
||||
|
||||
echo '<div class="help-block with-errors"></div></div></div>';
|
||||
break;
|
||||
|
||||
/* Checkbox */
|
||||
case 'checkbox':
|
||||
|
||||
$cls = in_array($k, $_SESSION['iserror']) ? ' isError' : '';
|
||||
|
||||
$validator = $v['req'] == '<span class="important">*</span>' ? 'data-checkbox="' . $k . '"' : '';
|
||||
$required_attribute = $validator == '' ? '' : ' data-error="' . $hesklang['this_field_is_required'] . '"';
|
||||
|
||||
echo '<div class="form-group' . $cls . '"><label class="col-sm-3 control-label">' . $v['name'] . ' ' . $v['req'] . '</label><div align="left" class="col-sm-9">';
|
||||
|
||||
foreach ($v['value']['checkbox_options'] as $option) {
|
||||
@ -427,7 +438,12 @@ $show_quick_help = $show['show'];
|
||||
$checked = '';
|
||||
}
|
||||
|
||||
echo '<div class="checkbox"><label><input type="checkbox" name="' . $k . '[]" value="' . $option . '" ' . $checked . $required_attribute . '> ' . $option . '</label></div>';
|
||||
echo '<div class="checkbox"><label><input ' . $validator . ' type="checkbox" name="' . $k . '[]" value="' . $option . '" ' . $checked . $required_attribute . '> ' . $option . '</label></div>';
|
||||
}
|
||||
|
||||
|
||||
if (!empty($v['mfh_description'])) {
|
||||
echo '<div class="help-block">' . $v['mfh_description'] . '</div>';
|
||||
}
|
||||
echo '
|
||||
<div class="help-block with-errors"></div></div></div>';
|
||||
@ -439,8 +455,13 @@ $show_quick_help = $show['show'];
|
||||
|
||||
echo '<div class="form-group' . $cls . '">
|
||||
<label for="' . $v['name'] . '" class="col-sm-3 control-label">' . $v['name'] . ' ' . $v['req'] . '</label>
|
||||
<div class="col-sm-9"><textarea class="form-control" placeholder="' . $v['name'] . '" name="' . $k . '" rows="' . intval($v['value']['rows']) . '" cols="' . intval($v['value']['cols']) . '" ' . $required_attribute . '>' . $k_value . '</textarea>
|
||||
<div class="help-block with-errors"></div></div></div>';
|
||||
<div class="col-sm-9"><textarea class="form-control" placeholder="' . $v['name'] . '" name="' . $k . '" rows="' . intval($v['value']['rows']) . '" cols="' . intval($v['value']['cols']) . '" ' . $required_attribute . '>' . $k_value . '</textarea>';
|
||||
|
||||
if (!empty($v['mfh_description'])) {
|
||||
echo '<div class="help-block">' . $v['mfh_description'] . '</div>';
|
||||
}
|
||||
|
||||
echo '<div class="help-block with-errors"></div></div></div>';
|
||||
break;
|
||||
|
||||
case 'date':
|
||||
@ -455,8 +476,13 @@ $show_quick_help = $show['show'];
|
||||
<label for="' . $v['name'] . '" class="col-sm-3 control-label">' . $v['name'].' '.$v['req'] . '</label>
|
||||
<div class="col-sm-9">
|
||||
<input type="text" class="datepicker form-control" placeholder="' . $v['name'] . '" name="' . $k . '" size="40"
|
||||
value="' . $k_value . '" ' . $required_attribute . '>
|
||||
<div class="help-block with-errors"></div>
|
||||
value="' . $k_value . '" ' . $required_attribute . '>';
|
||||
|
||||
if (!empty($v['mfh_description'])) {
|
||||
echo '<div class="help-block">' . $v['mfh_description'] . '</div>';
|
||||
}
|
||||
|
||||
echo '<div class="help-block with-errors"></div>
|
||||
</div>
|
||||
</div>';
|
||||
break;
|
||||
@ -468,8 +494,13 @@ $show_quick_help = $show['show'];
|
||||
echo '<div class="form-group' . $cls . '">
|
||||
<label for="' . $v['name'] . '" class="col-sm-3 control-label">' . $v['name'].' '.$v['req'] . '</label>
|
||||
<div class="col-sm-9">
|
||||
<input type="text" class="form-control" placeholder="' . $v['name'] . '" name="' . $k . '" size="40" value="' . $k_value . '" '.$suggest.$required_attribute.'>
|
||||
<div class="help-block with-errors"></div>
|
||||
<input type="text" class="form-control" placeholder="' . $v['name'] . '" name="' . $k . '" size="40" value="' . $k_value . '" '.$suggest.$required_attribute.'>';
|
||||
|
||||
if (!empty($v['mfh_description'])) {
|
||||
echo '<div class="help-block">' . $v['mfh_description'] . '</div>';
|
||||
}
|
||||
|
||||
echo '<div class="help-block with-errors"></div>
|
||||
</div>
|
||||
</div><div id="'.$k.'_suggestions"></div>';
|
||||
|
||||
@ -488,8 +519,13 @@ $show_quick_help = $show['show'];
|
||||
echo '<div class="form-group' . $cls . '">
|
||||
<label for="' . $v['name'] . '" class="col-sm-3 control-label">' . $v['name'].' '.$v['req'] . '</label>
|
||||
<div class="col-sm-9">
|
||||
<input type="text" class="form-control" placeholder="' . $v['name'] . '" name="' . $k . '" size="40" maxlength="' . intval($v['value']['max_length']) . '" value="' . $v['value']['default_value'] . '" ' . $cls . $required_attribute . '>
|
||||
<div class="help-block with-errors"></div>
|
||||
<input type="text" class="form-control" placeholder="' . $v['name'] . '" name="' . $k . '" size="40" maxlength="' . intval($v['value']['max_length']) . '" value="' . $v['value']['default_value'] . '" ' . $cls . $required_attribute . '>';
|
||||
|
||||
if (!empty($v['mfh_description'])) {
|
||||
echo '<div class="help-block">' . $v['mfh_description'] . '</div>';
|
||||
}
|
||||
|
||||
echo '<div class="help-block with-errors"></div>
|
||||
</div>
|
||||
</div>';
|
||||
}
|
||||
@ -536,8 +572,7 @@ $show_quick_help = $show['show'];
|
||||
if (myMsg == '') {
|
||||
if (document.form1.mode[1].checked) {
|
||||
if (useHtmlEditor) {
|
||||
tinymce.get("message").setContent('');
|
||||
tinymce.get("message").execCommand('mceInsertRawHTML', false, '');
|
||||
$("#message").summernote('reset');
|
||||
}
|
||||
else {
|
||||
$('#message').val('');
|
||||
@ -549,8 +584,8 @@ $show_quick_help = $show['show'];
|
||||
if (document.getElementById) {
|
||||
if (document.getElementById('moderep').checked) {
|
||||
if (useHtmlEditor) {
|
||||
tinymce.get("message").setContent('');
|
||||
tinymce.get("message").execCommand('mceInsertRawHTML', false, myMsg);
|
||||
$("#message").summernote('reset');
|
||||
$("#message").summernote('editor.insertText', myMsg));
|
||||
} else {
|
||||
myMsg = $('<textarea />').html(myMsg).text();
|
||||
$('#message').val(myMsg).trigger('input');
|
||||
@ -560,9 +595,9 @@ $show_quick_help = $show['show'];
|
||||
}
|
||||
else {
|
||||
if (useHtmlEditor) {
|
||||
var oldMsg = tinymce.get("message").getContent();
|
||||
tinymce.get("message").setContent('');
|
||||
tinymce.get("message").execCommand('mceInsertRawHTML', false, oldMsg + myMsg);
|
||||
var oldMsg = $("#message").val();
|
||||
$("#message").summernote('reset');
|
||||
$("#message").summernote('editor.insertText', oldMsg + myMsg));
|
||||
} else {
|
||||
var oldMsg = document.getElementById('message').value;
|
||||
var theMsg = $('<textarea />').html(oldMsg + myMsg).text();
|
||||
@ -662,7 +697,7 @@ $show_quick_help = $show['show'];
|
||||
?>
|
||||
</label>
|
||||
<div class="col-sm-9">
|
||||
<span id="HeskSub"><input class="form-control" type="text" name="subject" id="subject" size="40" maxlength="40"
|
||||
<span id="HeskSub"><input class="form-control" type="text" name="subject" id="subject" size="40" maxlength="70"
|
||||
value="<?php if (isset($_SESSION['as_subject']) || isset($_GET['subject'])) {
|
||||
echo stripslashes(hesk_input($_SESSION['as_subject']));
|
||||
} ?>" placeholder="<?php echo htmlspecialchars($hesklang['subject']); ?>"
|
||||
@ -750,7 +785,9 @@ $show_quick_help = $show['show'];
|
||||
|
||||
echo '<div class="radio"><label><input type="radio" name="' . $k . '" value="' . $option . '" ' . $checked . ' ' . $required_attribute . '> ' . $option . '</label></div>';
|
||||
}
|
||||
|
||||
if (!empty($v['mfh_description'])) {
|
||||
echo '<div class="help-block">' . $v['mfh_description'] . '</div>';
|
||||
}
|
||||
echo '<div class="help-block with-errors"></div></div></div>';
|
||||
break;
|
||||
|
||||
@ -777,12 +814,20 @@ $show_quick_help = $show['show'];
|
||||
echo '<option ' . $selected . '>' . $option . '</option>';
|
||||
}
|
||||
|
||||
echo '</select><div class="help-block with-errors"></div></div></div>';
|
||||
echo '</select>';
|
||||
if (!empty($v['mfh_description'])) {
|
||||
echo '<div class="help-block">' . $v['mfh_description'] . '</div>';
|
||||
}
|
||||
echo '<div class="help-block with-errors"></div></div></div>';
|
||||
break;
|
||||
|
||||
/* Checkbox */
|
||||
case 'checkbox':
|
||||
$cls = in_array($k, $_SESSION['iserror']) ? ' isError' : '';
|
||||
|
||||
$validator = $v['req'] == '<span class="important">*</span>' ? 'data-checkbox="' . $k . '"' : '';
|
||||
$required_attribute = $validator == '' ? '' : ' data-error="' . $hesklang['this_field_is_required'] . '"';
|
||||
|
||||
echo '<div class="form-group' . $cls . '"><label class="col-sm-3 control-label">' . $v['name'].' '.$v['req'] . '</label><div align="left" class="col-sm-9">';
|
||||
|
||||
foreach ($v['value']['checkbox_options'] as $option) {
|
||||
@ -792,7 +837,10 @@ $show_quick_help = $show['show'];
|
||||
$checked = '';
|
||||
}
|
||||
|
||||
echo '<div class="checkbox"><label><input type="checkbox" name="' . $k . '[]" value="' . $option . '" ' . $checked . ' ' . $required_attribute . '> ' . $option . '</label></div>';
|
||||
echo '<div class="checkbox"><label><input ' . $validator . ' type="checkbox" name="' . $k . '[]" value="' . $option . '" ' . $checked . $required_attribute .'> ' . $option . '</label></div>';
|
||||
}
|
||||
if (!empty($v['mfh_description'])) {
|
||||
echo '<div class="help-block">' . $v['mfh_description'] . '</div>';
|
||||
}
|
||||
echo '<div class="help-block with-errors"></div></div></div>';
|
||||
break;
|
||||
@ -803,8 +851,11 @@ $show_quick_help = $show['show'];
|
||||
|
||||
echo '<div class="form-group' . $cls . '">
|
||||
<label for="' . $v['name'] . '" class="col-sm-3 control-label">' . $v['name'].' '.$v['req'] . '</label>
|
||||
<div class="col-sm-9"><textarea class="form-control" placeholder="' . $v['name'] . '" name="' . $k . '" rows="' . intval($v['value']['rows']) . '" cols="' . intval($v['value']['cols']) . '" ' . $required_attribute . '>' . $k_value . '</textarea>
|
||||
<div class="help-block with-errors"></div></div>
|
||||
<div class="col-sm-9"><textarea class="form-control" placeholder="' . $v['name'] . '" name="' . $k . '" rows="' . intval($v['value']['rows']) . '" cols="' . intval($v['value']['cols']) . '" ' . $required_attribute . '>' . $k_value . '</textarea>';
|
||||
if (!empty($v['mfh_description'])) {
|
||||
echo '<div class="help-block">' . $v['mfh_description'] . '</div>';
|
||||
}
|
||||
echo '<div class="help-block with-errors"></div></div>
|
||||
</div>';
|
||||
break;
|
||||
|
||||
@ -820,8 +871,11 @@ $show_quick_help = $show['show'];
|
||||
<label for="' . $v['name'] . '" class="col-sm-3 control-label">' . $v['name'].' '.$v['req'] . '</label>
|
||||
<div class="col-sm-9">
|
||||
<input type="text" class="datepicker form-control" placeholder="' . $v['name'] . '" name="' . $k . '" size="40"
|
||||
value="' . $k_value . '" ' . $required_attribute . '>
|
||||
<div class="help-block with-errors"></div>
|
||||
value="' . $k_value . '" ' . $required_attribute . '>';
|
||||
if (!empty($v['mfh_description'])) {
|
||||
echo '<div class="help-block">' . $v['mfh_description'] . '</div>';
|
||||
}
|
||||
echo '<div class="help-block with-errors"></div>
|
||||
</div>
|
||||
</div>';
|
||||
break;
|
||||
@ -833,8 +887,11 @@ $show_quick_help = $show['show'];
|
||||
echo '<div class="form-group">
|
||||
<label for="' . $v['name'] . '" class="col-sm-3 control-label">' . $v['name'].' '.$v['req'] . '</label>
|
||||
<div class="col-sm-9">
|
||||
<input type="text" class="form-control" placeholder="' . $v['name'] . '" name="' . $k . '" size="40" value="' . $k_value . '" '.$suggest.' ' . $required_attribute . '>
|
||||
<div class="help-block with-errors"></div>
|
||||
<input type="text" class="form-control" placeholder="' . $v['name'] . '" name="' . $k . '" size="40" value="' . $k_value . '" '.$suggest.' ' . $required_attribute . '>';
|
||||
if (!empty($v['mfh_description'])) {
|
||||
echo '<div class="help-block">' . $v['mfh_description'] . '</div>';
|
||||
}
|
||||
echo '<div class="help-block with-errors"></div>
|
||||
</div>
|
||||
</div><div id="'.$k.'_suggestions"></div>';
|
||||
|
||||
@ -852,8 +909,11 @@ $show_quick_help = $show['show'];
|
||||
echo '<div class="form-group">
|
||||
<label for="' . $v['name'] . '" class="col-sm-3 control-label">' . $v['name'].' '.$v['req'] . '</label>
|
||||
<div class="col-sm-9">
|
||||
<input type="text" class="form-control" placeholder="' . $v['name'] . '" name="' . $k . '" size="40" maxlength="' . intval($v['value']['max_length']) . '" value="' . $v['value']['default_value'] . '" ' . $required_attribute . '>
|
||||
<div class="help-block with-errors"></div>
|
||||
<input type="text" class="form-control" placeholder="' . $v['name'] . '" name="' . $k . '" size="40" maxlength="' . intval($v['value']['max_length']) . '" value="' . $v['value']['default_value'] . '" ' . $required_attribute . '>';
|
||||
if (!empty($v['mfh_description'])) {
|
||||
echo '<div class="help-block">' . $v['mfh_description'] . '</div>';
|
||||
}
|
||||
echo '<div class="help-block with-errors"></div>
|
||||
</div>
|
||||
</div>';
|
||||
}
|
||||
@ -872,7 +932,7 @@ $show_quick_help = $show['show'];
|
||||
</div>
|
||||
</div>
|
||||
<?php
|
||||
display_dropzone_field($hesk_settings['hesk_url'] . '/internal-api/ticket/upload-attachment.php');
|
||||
display_dropzone_field(HESK_PATH . 'internal-api/ticket/upload-attachment.php');
|
||||
}
|
||||
|
||||
if (!isset($_SESSION['as_notify'])) {
|
||||
@ -991,8 +1051,8 @@ if ($modsForHesk_settings['rich_text_for_tickets']) {
|
||||
$message = hesk_SESSION('as_message', '');
|
||||
echo "
|
||||
<script>
|
||||
tinymce.get('message').setContent('');
|
||||
tinymce.get('message').execCommand('mceInsertRawHTML', false, '".$message."');
|
||||
$(\"#message\").summernote('reset');
|
||||
$(\"#message\").summernote('editor.insertText', '".$message."'));
|
||||
</script>
|
||||
";
|
||||
}
|
||||
@ -1031,9 +1091,10 @@ function print_select_category($number_of_categories) {
|
||||
// Print a select box if number of categories is large
|
||||
if ($number_of_categories > $hesk_settings['cat_show_select'])
|
||||
{
|
||||
$firstDescription = null;
|
||||
?>
|
||||
<form action="new_ticket.php" method="get">
|
||||
<select name="category" id="select_category" class="form-control">
|
||||
<select name="category" id="select_category" class="form-control" onchange="showDescription()">
|
||||
<?php
|
||||
if ($hesk_settings['select_cat'])
|
||||
{
|
||||
@ -1041,23 +1102,45 @@ function print_select_category($number_of_categories) {
|
||||
}
|
||||
foreach ($hesk_settings['categories'] as $k=>$v)
|
||||
{
|
||||
echo '<option value="'.$k.'">'.$v.'</option>';
|
||||
if ($firstDescription === null) {
|
||||
$firstDescription = $v['mfh_description'];
|
||||
}
|
||||
echo '<option value="'.$k.'" data-description="'.$v['mfh_description'].'">'.$v['name'].'</option>';
|
||||
}
|
||||
?>
|
||||
</select>
|
||||
<?php
|
||||
$display = ' style="display: none"';
|
||||
|
||||
<br />
|
||||
|
||||
if (!$hesk_settings['select_cat'] && $firstDescription !== null && trim($firstDescription) !== '') {
|
||||
$display = '';
|
||||
}
|
||||
?>
|
||||
<span id="category-description"<?php echo $display; ?>>
|
||||
<b><?php echo $hesklang['description_colon']; ?></b>
|
||||
<span><?php echo $firstDescription; ?></span>
|
||||
</span>
|
||||
<br>
|
||||
<div style="text-align:center">
|
||||
<input type="submit" value="<?php echo $hesklang['c2c']; ?>" class="btn btn-default">
|
||||
</div>
|
||||
</form>
|
||||
<script>
|
||||
function showDescription() {
|
||||
var $value = $('#select_category').find(':selected');
|
||||
|
||||
if ($value.data('description') !== '') {
|
||||
$('#category-description').show().find('span').text($value.data('description'));
|
||||
} else {
|
||||
$('#category-description').hide();
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<?php
|
||||
}
|
||||
// Otherwise print quick links
|
||||
else
|
||||
{
|
||||
// echo '<li><a href="new_ticket.php?a=add&category='.$k.'">» '.$v.'</a></li>';
|
||||
$new_row = 1;
|
||||
|
||||
foreach ($hesk_settings['categories'] as $k=>$v):
|
||||
@ -1072,7 +1155,14 @@ function print_select_category($number_of_categories) {
|
||||
<div class="panel-body">
|
||||
<div class="row">
|
||||
<div class="col-xs-12">
|
||||
<?php echo $v; ?>
|
||||
<?php
|
||||
echo $v['name'];
|
||||
|
||||
if ($v['mfh_description'] !== null && trim($v['mfh_description']) !== '') {
|
||||
echo ' <i class="fa fa-info-circle" data-toggle="popover"
|
||||
title="'. $hesklang['description'] .'" data-content="' . $v['mfh_description'] . '"></i>';
|
||||
}
|
||||
?>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -47,22 +47,7 @@ if ($_SERVER['REQUEST_METHOD'] == 'POST') {
|
||||
// Verify security image
|
||||
if ($hesk_settings['secimg_use']) {
|
||||
// Using ReCaptcha?
|
||||
if ($hesk_settings['recaptcha_use'] == 1) {
|
||||
require_once(HESK_PATH . 'inc/recaptcha/recaptchalib.php');
|
||||
|
||||
$resp = recaptcha_check_answer($hesk_settings['recaptcha_private_key'],
|
||||
$_SERVER['REMOTE_ADDR'],
|
||||
hesk_POST('recaptcha_challenge_field', ''),
|
||||
hesk_POST('recaptcha_response_field', '')
|
||||
);
|
||||
|
||||
if ($resp->is_valid) {
|
||||
//$_SESSION['img_a_verified']=true;
|
||||
} else {
|
||||
$hesk_error_buffer['mysecnum'] = $hesklang['recaptcha_error'];
|
||||
}
|
||||
} // Using ReCaptcha API v2?
|
||||
elseif ($hesk_settings['recaptcha_use'] == 2) {
|
||||
if ($hesk_settings['recaptcha_use']) {
|
||||
require(HESK_PATH . 'inc/recaptcha/recaptchalib_v2.php');
|
||||
|
||||
$resp = null;
|
||||
@ -70,7 +55,7 @@ if ($_SERVER['REQUEST_METHOD'] == 'POST') {
|
||||
|
||||
// Was there a reCAPTCHA response?
|
||||
if (isset($_POST["g-recaptcha-response"])) {
|
||||
$resp = $reCaptcha->verifyResponse($_SERVER["REMOTE_ADDR"], hesk_POST("g-recaptcha-response"));
|
||||
$resp = $reCaptcha->verifyResponse(hesk_getClientIP(), hesk_POST("g-recaptcha-response"));
|
||||
}
|
||||
|
||||
if ($resp != null && $resp->success) {
|
||||
@ -121,7 +106,7 @@ if ($_SERVER['REQUEST_METHOD'] == 'POST') {
|
||||
hesk_process_messages($hesklang['noace'], 'NOREDIRECT');
|
||||
} else {
|
||||
$row = hesk_dbFetchAssoc($res);
|
||||
$hash = sha1(microtime() . $_SERVER['REMOTE_ADDR'] . mt_rand() . $row['id'] . $row['name'] . $row['pass']);
|
||||
$hash = sha1(microtime() . hesk_getClientIP() . mt_rand() . $row['id'] . $row['name'] . $row['pass']);
|
||||
|
||||
// Insert the verification hash into the database
|
||||
hesk_dbQuery("INSERT INTO `" . hesk_dbEscape($hesk_settings['db_pfix']) . "reset_password` (`user`, `hash`, `ip`) VALUES (" . intval($row['id']) . ", '{$hash}', '" . hesk_dbEscape($_SERVER['REMOTE_ADDR']) . "') ");
|
||||
@ -215,7 +200,7 @@ elseif (isset($_GET['h'])) {
|
||||
}
|
||||
|
||||
// Tell header to load reCaptcha API if needed
|
||||
if ($hesk_settings['recaptcha_use'] == 2) {
|
||||
if ($hesk_settings['recaptcha_use']) {
|
||||
define('RECAPTCHA', 1);
|
||||
}
|
||||
|
||||
@ -230,7 +215,7 @@ require_once(HESK_PATH . 'inc/headerAdmin.inc.php');
|
||||
<h4 class="login-box-msg">
|
||||
<?php echo $hesklang['passr']; ?>
|
||||
</h4>
|
||||
<form action="password.php" method="post" name="form1" class="form-horizontal" role="form">
|
||||
<form action="password.php" method="post" name="form1" id="form1" class="form-horizontal" role="form">
|
||||
<?php
|
||||
/* This will handle error, success and notice messages */
|
||||
hesk_handle_messages();
|
||||
@ -255,38 +240,13 @@ require_once(HESK_PATH . 'inc/headerAdmin.inc.php');
|
||||
</div>
|
||||
</div>
|
||||
<?php
|
||||
if ($hesk_settings['secimg_use']) {
|
||||
if ($hesk_settings['secimg_use'] && $hesk_settings['recaptcha_use'] != 1) {
|
||||
?>
|
||||
<div class="form-group">
|
||||
<div class="col-sm-11 col-sm-offset-1">
|
||||
<?php
|
||||
// Should we use Recaptcha?
|
||||
if ($hesk_settings['recaptcha_use'] == 1) {
|
||||
?>
|
||||
<script type="text/javascript">
|
||||
var RecaptchaOptions = {
|
||||
theme: '<?php echo ( isset($_SESSION['a_iserror']) && in_array('mysecnum',$_SESSION['a_iserror']) ) ? 'red' : 'white'; ?>',
|
||||
custom_translations: {
|
||||
visual_challenge: "<?php echo hesk_slashJS($hesklang['visual_challenge']); ?>",
|
||||
audio_challenge: "<?php echo hesk_slashJS($hesklang['audio_challenge']); ?>",
|
||||
refresh_btn: "<?php echo hesk_slashJS($hesklang['refresh_btn']); ?>",
|
||||
instructions_visual: "<?php echo hesk_slashJS($hesklang['instructions_visual']); ?>",
|
||||
instructions_context: "<?php echo hesk_slashJS($hesklang['instructions_context']); ?>",
|
||||
instructions_audio: "<?php echo hesk_slashJS($hesklang['instructions_audio']); ?>",
|
||||
help_btn: "<?php echo hesk_slashJS($hesklang['help_btn']); ?>",
|
||||
play_again: "<?php echo hesk_slashJS($hesklang['play_again']); ?>",
|
||||
cant_hear_this: "<?php echo hesk_slashJS($hesklang['cant_hear_this']); ?>",
|
||||
incorrect_try_again: "<?php echo hesk_slashJS($hesklang['incorrect_try_again']); ?>",
|
||||
image_alt_text: "<?php echo hesk_slashJS($hesklang['image_alt_text']); ?>"
|
||||
}
|
||||
};
|
||||
</script>
|
||||
<?php
|
||||
require_once(HESK_PATH . 'inc/recaptcha/recaptchalib.php');
|
||||
echo recaptcha_get_html($hesk_settings['recaptcha_public_key'], null, true);
|
||||
}
|
||||
// Use reCaptcha API v2?
|
||||
elseif ($hesk_settings['recaptcha_use'] == 2)
|
||||
if ($hesk_settings['recaptcha_use'] == 2)
|
||||
{
|
||||
?>
|
||||
<div class="g-recaptcha"
|
||||
@ -312,6 +272,14 @@ require_once(HESK_PATH . 'inc/headerAdmin.inc.php');
|
||||
<input type="submit" value="<?php echo $hesklang['passs']; ?>" class="btn btn-default">
|
||||
</div>
|
||||
</div>
|
||||
<?php
|
||||
// Use Invisible reCAPTCHA?
|
||||
if ($hesk_settings['secimg_use'] && $hesk_settings['recaptcha_use'] == 1) {
|
||||
?>
|
||||
<div class="g-recaptcha" data-sitekey="<?php echo $hesk_settings['recaptcha_public_key']; ?>" data-bind="recaptcha-submit" data-callback="recaptcha_submitForm"></div>
|
||||
<?php
|
||||
}
|
||||
?>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
73
admin/priority.php
Normal file
73
admin/priority.php
Normal file
@ -0,0 +1,73 @@
|
||||
<?php
|
||||
/**
|
||||
*
|
||||
* This file is part of HESK - PHP Help Desk Software.
|
||||
*
|
||||
* (c) Copyright Klemen Stirn. All rights reserved.
|
||||
* https://www.hesk.com
|
||||
*
|
||||
* For the full copyright and license agreement information visit
|
||||
* https://www.hesk.com/eula.php
|
||||
*
|
||||
*/
|
||||
|
||||
define('IN_SCRIPT',1);
|
||||
define('HESK_PATH','../');
|
||||
|
||||
/* Get all the required files and functions */
|
||||
require(HESK_PATH . 'hesk_settings.inc.php');
|
||||
require(HESK_PATH . 'inc/common.inc.php');
|
||||
require(HESK_PATH . 'inc/admin_functions.inc.php');
|
||||
hesk_load_database_functions();
|
||||
|
||||
hesk_session_start();
|
||||
hesk_dbConnect();
|
||||
hesk_isLoggedIn();
|
||||
|
||||
/* Check permissions for this feature */
|
||||
hesk_checkPermission('can_view_tickets');
|
||||
hesk_checkPermission('can_reply_tickets');
|
||||
|
||||
/* A security check */
|
||||
hesk_token_check('POST');
|
||||
|
||||
/* Ticket ID */
|
||||
$trackingID = hesk_cleanID() or die($hesklang['int_error'].': '.$hesklang['no_trackID']);
|
||||
|
||||
$priority = intval( hesk_POST('priority') );
|
||||
if ($priority < 0 || $priority > 3)
|
||||
{
|
||||
hesk_process_messages($hesklang['inpr'],'admin_ticket.php?track='.$trackingID.'&Refresh='.mt_rand(10000,99999),'NOTICE');
|
||||
}
|
||||
|
||||
$options = array(
|
||||
0 => '<font class="critical">'.$hesklang['critical'].'</font>',
|
||||
1 => '<font class="important">'.$hesklang['high'].'</font>',
|
||||
2 => '<font class="medium">'.$hesklang['medium'].'</font>',
|
||||
3 => $hesklang['low']
|
||||
);
|
||||
|
||||
$plain_options = array(
|
||||
0 => 'critical',
|
||||
1 => 'high',
|
||||
2 => 'medium',
|
||||
3 => 'low'
|
||||
);
|
||||
|
||||
$ticketRs = hesk_dbQuery("SELECT * FROM `" . hesk_dbEscape($hesk_settings['db_pfix']) . "tickets` WHERE `trackid` = '" . hesk_dbEscape($trackingID) . "'");
|
||||
$ticket = hesk_dbFetchAssoc($ticketRs);
|
||||
|
||||
hesk_dbQuery("UPDATE `".hesk_dbEscape($hesk_settings['db_pfix'])."tickets` SET `priority`='{$priority}' WHERE `trackid`='".hesk_dbEscape($trackingID)."'");
|
||||
|
||||
mfh_insert_audit_trail_record($ticket['id'], 'TICKET', 'audit_priority', hesk_date(), array(
|
||||
0 => $_SESSION['name'].' ('.$_SESSION['user'].')',
|
||||
1 => $plain_options[$priority]
|
||||
));
|
||||
|
||||
if (hesk_dbAffectedRows() != 1)
|
||||
{
|
||||
hesk_process_messages($hesklang['inpr'],'admin_ticket.php?track='.$trackingID.'&Refresh='.mt_rand(10000,99999),'NOTICE');
|
||||
}
|
||||
|
||||
hesk_process_messages(sprintf($hesklang['chpri2'],$options[$priority]),'admin_ticket.php?track='.$trackingID.'&Refresh='.mt_rand(10000,99999),'SUCCESS');
|
||||
?>
|
@ -166,11 +166,11 @@ function update_profile()
|
||||
$hesk_error_buffer = '';
|
||||
|
||||
$_SESSION['new']['name'] = hesk_input(hesk_POST('name')) or $hesk_error_buffer .= '<li>' . $hesklang['enter_your_name'] . '</li>';
|
||||
$_SESSION['new']['email'] = hesk_validateEmail(hesk_POST('email'), 'ERR', 0) or $hesk_error_buffer = '<li>' . $hesklang['enter_valid_email'] . '</li>';
|
||||
$_SESSION['new']['email'] = hesk_validateEmail( hesk_POST('email'), 'ERR', 0) or $hesk_error_buffer .= '<li>' . $hesklang['enter_valid_email'] . '</li>';
|
||||
$_SESSION['new']['signature'] = hesk_input(hesk_POST('signature'));
|
||||
|
||||
/* Signature */
|
||||
if (strlen($_SESSION['new']['signature']) > 1000) {
|
||||
if (hesk_mb_strlen($_SESSION['new']['signature']) > 1000) {
|
||||
$hesk_error_buffer .= '<li>' . $hesklang['signature_long'] . '</li>';
|
||||
}
|
||||
|
||||
|
@ -249,7 +249,7 @@ require_once(HESK_PATH . 'inc/show_admin_nav.inc.php');
|
||||
(<?php echo $hesklang['m' . date('n')]; ?>)
|
||||
</option>
|
||||
<option value="4" <?php echo $selected['time'][4]; ?>><?php echo $hesklang['r4']; ?>
|
||||
(<?php echo $hesklang['m' . date('n', mktime(0, 0, 0, date('m') - 1, date('d'), date('Y')))]; ?>
|
||||
(<?php echo $hesklang['m' . date('n', mktime(0, 0, 0, date('m') - 1, 1, date('Y')))]; ?>
|
||||
)
|
||||
</option>
|
||||
<option
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -89,23 +89,6 @@ require_once(HESK_PATH . 'inc/show_admin_nav.inc.php');
|
||||
</div>
|
||||
</div>
|
||||
<?php
|
||||
$hesk_settings['hesk_license']('HMgPSAxOw0KaWYgKGZpbGVfZXhpc3RzKEhFU0tfUEFUSCAuI
|
||||
CdoZXNrX2xpY2Vuc2UucGhwJykpDQp7DQokaCA9ICghZW1wdHkoJF9TRVJWRVJbJ0hUVFBfSE9TVCddK
|
||||
SkgPyAkX1NFUlZFUlsnSFRUUF9IT1NUJ10gOiAoKCFlbXB0eSgkX1NFUlZFUlsnU0VSVkVSX05BTUUnX
|
||||
SkpID8gJF9TRVJWRVJbJ1NFUlZFUl9OQU1FJ10gOiBnZXRlbnYoJ1NFUlZFUl9OQU1FJykpOw0KJGggP
|
||||
SBzdHJfcmVwbGFjZSgnd3d3LicsJycsc3RydG9sb3dlcigkaCkpOw0KaW5jbHVkZShIRVNLX1BBVEggL
|
||||
iAnaGVza19saWNlbnNlLnBocCcpOw0KaWYgKGlzc2V0KCRoZXNrX3NldHRpbmdzWydsaWNlbnNlJ10pI
|
||||
CYmIHN0cnBvcygkaGVza19zZXR0aW5nc1snbGljZW5zZSddLHNoYTEoJGguJ2gzJkZwMiNMYUEmNTkhd
|
||||
yg4LlpjXSordVI1MTInKSkgIT09IGZhbHNlKQ0Kew0KJHMgPSAwOw0KfQ0KZWxzZQ0Kew0KZWNobyAnP
|
||||
HAgc3R5bGU9InRleHQtYWxpZ246Y2VudGVyO2NvbG9yOnJlZDsiPklOVkFMSUQgTElDRU5TRSAoTk9UI
|
||||
FJFR0lTVEVSRUQgRk9SICcuJGguJykhPC9wPic7DQp9DQp9DQppZiAoJHMpDQp7DQplY2hvICc8aHIgL
|
||||
z48dGFibGUgYm9yZGVyPSIwIiB3aWR0aD0iMTAwJSI+PHRyPjx0ZD48Yj4nLiRoZXNrbGFuZ1sncmVtb
|
||||
3ZlX3N0YXRlbWVudCddLic8L2I+PC90ZD48dGQgc3R5bGU9InRleHQtYWxpZ246cmlnaHQiPjxhIGhyZ
|
||||
WY9IkphdmFzY3JpcHQ6dm9pZCgwKSIgb25jbGljaz0iYWxlcnQoXCcnLiRoZXNrbGFuZ1snc3VwcG9yd
|
||||
F9ub3RpY2UnXS4nXCcpIj4nLiRoZXNrbGFuZ1snc2gnXS4nPC9hPjwvdGQ+PC90cj48L3RhYmxlPjxwP
|
||||
icuJGhlc2tsYW5nWydzdXBwb3J0X3JlbW92ZSddLicuIDxhIGhyZWY9Imh0dHBzOi8vd3d3Lmhlc2suY
|
||||
29tL2J1eS5waHAiIHRhcmdldD0iX2JsYW5rIj4nLiRoZXNrbGFuZ1snY2xpY2tfaW5mbyddLic8L2E+P
|
||||
C9wPic7DQp9DQo=', "\112");
|
||||
|
||||
/* Clean unneeded session variables */
|
||||
hesk_cleanSessionVars('hide');
|
||||
|
@ -97,6 +97,7 @@ require_once(HESK_PATH . 'inc/show_admin_nav.inc.php');
|
||||
<th><?php echo $hesklang['user']; ?></th>
|
||||
<th><?php echo $hesklang['custom_place']; ?></th>
|
||||
<th><?php echo $hesklang['message']; ?></th>
|
||||
<th><?php echo $hesklang['stack_trace_header']; ?></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody></tbody>
|
||||
|
7
api/BaseClass.php
Normal file
7
api/BaseClass.php
Normal file
@ -0,0 +1,7 @@
|
||||
<?php
|
||||
|
||||
class BaseClass {
|
||||
static function clazz() {
|
||||
return get_called_class();
|
||||
}
|
||||
}
|
7
api/BaseException.php
Normal file
7
api/BaseException.php
Normal file
@ -0,0 +1,7 @@
|
||||
<?php
|
||||
|
||||
class BaseException extends Exception {
|
||||
static function clazz() {
|
||||
return get_called_class();
|
||||
}
|
||||
}
|
21
api/BusinessLogic/Attachments/Attachment.php
Normal file
21
api/BusinessLogic/Attachments/Attachment.php
Normal file
@ -0,0 +1,21 @@
|
||||
<?php
|
||||
|
||||
namespace BusinessLogic\Attachments;
|
||||
|
||||
|
||||
class Attachment extends \BaseClass {
|
||||
/* @var $id int */
|
||||
public $id;
|
||||
|
||||
/* @var $savedName string */
|
||||
public $savedName;
|
||||
|
||||
/* @var $displayName string */
|
||||
public $displayName;
|
||||
|
||||
/* @var $id int */
|
||||
public $fileSize;
|
||||
|
||||
/* @var $downloadCount int */
|
||||
public $downloadCount;
|
||||
}
|
479
api/BusinessLogic/Attachments/AttachmentHandler.php
Normal file
479
api/BusinessLogic/Attachments/AttachmentHandler.php
Normal file
@ -0,0 +1,479 @@
|
||||
<?php
|
||||
|
||||
namespace BusinessLogic\Attachments;
|
||||
|
||||
|
||||
use BusinessLogic\Exceptions\AccessViolationException;
|
||||
use BusinessLogic\Exceptions\ApiFriendlyException;
|
||||
use BusinessLogic\Exceptions\ValidationException;
|
||||
use BusinessLogic\Security\UserContext;
|
||||
use BusinessLogic\Security\UserPrivilege;
|
||||
use BusinessLogic\Security\UserToTicketChecker;
|
||||
use BusinessLogic\Tickets\Attachment;
|
||||
use BusinessLogic\Tickets\Ticket;
|
||||
use BusinessLogic\ValidationModel;
|
||||
use DataAccess\Attachments\AttachmentGateway;
|
||||
use DataAccess\Files\FileDeleter;
|
||||
use DataAccess\Files\FileWriter;
|
||||
use DataAccess\Tickets\TicketGateway;
|
||||
|
||||
class AttachmentHandler extends \BaseClass {
|
||||
/* @var $ticketGateway TicketGateway */
|
||||
private $ticketGateway;
|
||||
|
||||
/* @var $attachmentGateway AttachmentGateway */
|
||||
private $attachmentGateway;
|
||||
|
||||
/* @var $fileWriter FileWriter */
|
||||
private $fileWriter;
|
||||
|
||||
/* @var $fileDeleter FileDeleter */
|
||||
private $fileDeleter;
|
||||
|
||||
/* @var $userToTicketChecker UserToTicketChecker */
|
||||
private $userToTicketChecker;
|
||||
|
||||
function __construct(TicketGateway $ticketGateway,
|
||||
AttachmentGateway $attachmentGateway,
|
||||
FileWriter $fileWriter,
|
||||
UserToTicketChecker $userToTicketChecker,
|
||||
FileDeleter $fileDeleter) {
|
||||
$this->ticketGateway = $ticketGateway;
|
||||
$this->attachmentGateway = $attachmentGateway;
|
||||
$this->fileWriter = $fileWriter;
|
||||
$this->userToTicketChecker = $userToTicketChecker;
|
||||
$this->fileDeleter = $fileDeleter;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param $createAttachmentModel CreateAttachmentForTicketModel
|
||||
* @param $userContext UserContext
|
||||
* @param $heskSettings array
|
||||
* @return TicketAttachment the newly created attachment
|
||||
* @throws \Exception
|
||||
*/
|
||||
function createAttachmentForTicket($createAttachmentModel, $userContext, $heskSettings) {
|
||||
$this->validate($createAttachmentModel, $heskSettings);
|
||||
|
||||
$decodedAttachment = base64_decode($createAttachmentModel->attachmentContents);
|
||||
|
||||
$ticket = $this->ticketGateway->getTicketById($createAttachmentModel->ticketId, $heskSettings);
|
||||
|
||||
if ($ticket === null) {
|
||||
throw new ApiFriendlyException("Ticket {$createAttachmentModel->ticketId} not found", "Ticket Not Found", 404);
|
||||
}
|
||||
|
||||
$extraPermissions = $createAttachmentModel->isEditing
|
||||
? array(UserPrivilege::CAN_EDIT_TICKETS)
|
||||
: array();
|
||||
|
||||
if (!$this->userToTicketChecker->isTicketAccessibleToUser($userContext, $ticket, $heskSettings, $extraPermissions)) {
|
||||
throw new AccessViolationException("User does not have access to ticket {$ticket->id} being created / edited!");
|
||||
}
|
||||
|
||||
$cleanedFileName = $this->cleanFileName($createAttachmentModel->displayName);
|
||||
$fileParts = pathinfo($cleanedFileName);
|
||||
|
||||
$ticketAttachment = new TicketAttachment();
|
||||
$ticketAttachment->savedName = $this->generateSavedName($ticket->trackingId,
|
||||
$cleanedFileName, $fileParts['extension']);
|
||||
$ticketAttachment->displayName = $cleanedFileName;
|
||||
$ticketAttachment->ticketTrackingId = $ticket->trackingId;
|
||||
$ticketAttachment->type = 0;
|
||||
$ticketAttachment->downloadCount = 0;
|
||||
|
||||
$ticketAttachment->fileSize =
|
||||
$this->fileWriter->writeToFile($ticketAttachment->savedName, $heskSettings['attach_dir'], $decodedAttachment);
|
||||
|
||||
$attachmentId = $this->attachmentGateway->createAttachmentForTicket($ticketAttachment, $heskSettings);
|
||||
|
||||
$this->updateAttachmentsOnTicket($ticket, $ticketAttachment, $attachmentId, $heskSettings);
|
||||
|
||||
$ticketAttachment->id = $attachmentId;
|
||||
|
||||
return $ticketAttachment;
|
||||
}
|
||||
|
||||
/**
|
||||
* Supports deleting attachments from both ticket messages AND replies
|
||||
*
|
||||
* @param $ticketId int The ticket ID
|
||||
* @param $attachmentId int The attachment ID
|
||||
* @param $userContext UserContext
|
||||
* @param $heskSettings array
|
||||
* @throws ApiFriendlyException
|
||||
* @throws \Exception
|
||||
*/
|
||||
function deleteAttachmentFromTicket($ticketId, $attachmentId, $userContext, $heskSettings) {
|
||||
$ticket = $this->ticketGateway->getTicketById($ticketId, $heskSettings);
|
||||
|
||||
if ($ticket === null) {
|
||||
throw new ApiFriendlyException("Ticket {$ticketId} not found!", "Ticket Not Found", 404);
|
||||
}
|
||||
|
||||
if (!$this->userToTicketChecker->isTicketAccessibleToUser($userContext, $ticket, $heskSettings, array(UserPrivilege::CAN_EDIT_TICKETS))) {
|
||||
throw new AccessViolationException("User does not have access to ticket {$ticketId} being created / edited!");
|
||||
}
|
||||
|
||||
$indexToRemove = -1;
|
||||
$attachmentType = AttachmentType::MESSAGE;
|
||||
$replyId = -1;
|
||||
for ($i = 0; $i < count($ticket->attachments); $i++) {
|
||||
$attachment = $ticket->attachments[$i];
|
||||
if ($attachment->id === $attachmentId) {
|
||||
$indexToRemove = $i;
|
||||
$this->fileDeleter->deleteFile($attachment->savedName, $heskSettings['attach_dir']);
|
||||
$this->attachmentGateway->deleteAttachment($attachment->id, $heskSettings);
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($ticket->replies as $reply) {
|
||||
for ($i = 0; $i < count($reply->attachments); $i++) {
|
||||
$attachment = $reply->attachments[$i];
|
||||
if ($attachment->id === $attachmentId) {
|
||||
$indexToRemove = $i;
|
||||
$replyId = $reply->id;
|
||||
$attachmentType = AttachmentType::REPLY;
|
||||
$this->fileDeleter->deleteFile($attachment->savedName, $heskSettings['attach_dir']);
|
||||
$this->attachmentGateway->deleteAttachment($attachment->id, $heskSettings);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ($indexToRemove === -1) {
|
||||
throw new ApiFriendlyException("Attachment not found for ticket or reply! ID: {$attachmentId}", "Attachment not found", 404);
|
||||
}
|
||||
|
||||
if ($attachmentType == AttachmentType::MESSAGE) {
|
||||
$attachments = $ticket->attachments;
|
||||
unset($attachments[$indexToRemove]);
|
||||
$this->ticketGateway->updateAttachmentsForTicket($ticketId, $attachments, $heskSettings);
|
||||
} else {
|
||||
$attachments = $ticket->replies[$replyId]->attachments;
|
||||
unset($attachments[$indexToRemove]);
|
||||
$this->ticketGateway->updateAttachmentsForReply($replyId, $attachments, $heskSettings);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $createAttachmentModel CreateAttachmentForTicketModel
|
||||
* @param $heskSettings array
|
||||
* @throws ValidationException
|
||||
*/
|
||||
private function validate($createAttachmentModel, $heskSettings) {
|
||||
$errorKeys = array();
|
||||
if ($createAttachmentModel->attachmentContents === null ||
|
||||
trim($createAttachmentModel->attachmentContents) === '') {
|
||||
$errorKeys[] = 'CONTENTS_EMPTY';
|
||||
}
|
||||
|
||||
if (base64_decode($createAttachmentModel->attachmentContents, true) === false) {
|
||||
$errorKeys[] = 'CONTENTS_NOT_BASE_64';
|
||||
}
|
||||
|
||||
if ($createAttachmentModel->displayName === null ||
|
||||
trim($createAttachmentModel->displayName === '')) {
|
||||
$errorKeys[] = 'DISPLAY_NAME_EMPTY';
|
||||
}
|
||||
|
||||
if ($createAttachmentModel->ticketId === null ||
|
||||
$createAttachmentModel->ticketId < 1) {
|
||||
$errorKeys[] = 'TICKET_ID_MISSING';
|
||||
}
|
||||
|
||||
$fileParts = pathinfo($createAttachmentModel->displayName);
|
||||
if (!isset($fileParts['extension']) || !in_array(".{$fileParts['extension']}", $heskSettings['attachments']['allowed_types'])) {
|
||||
$errorKeys[] = 'EXTENSION_NOT_PERMITTED';
|
||||
}
|
||||
|
||||
$fileContents = base64_decode($createAttachmentModel->attachmentContents);
|
||||
if (function_exists('mb_strlen')) {
|
||||
$fileSize = mb_strlen($fileContents, '8bit');
|
||||
} else {
|
||||
$fileSize = strlen($fileContents);
|
||||
}
|
||||
|
||||
if ($fileSize > $heskSettings['attachments']['max_size']) {
|
||||
$errorKeys[] = 'FILE_SIZE_TOO_LARGE';
|
||||
}
|
||||
|
||||
if (count($errorKeys) > 0) {
|
||||
$validationModel = new ValidationModel();
|
||||
$validationModel->errorKeys = $errorKeys;
|
||||
throw new ValidationException($validationModel);
|
||||
}
|
||||
}
|
||||
|
||||
private function generateSavedName($trackingId, $displayName, $fileExtension) {
|
||||
$fileExtension = ".{$fileExtension}";
|
||||
$useChars = 'AEUYBDGHJLMNPQRSTVWXZ123456789';
|
||||
$tmp = uniqid();
|
||||
for ($j = 1; $j < 10; $j++) {
|
||||
$tmp .= $useChars{mt_rand(0, 29)};
|
||||
}
|
||||
|
||||
|
||||
return substr($trackingId . '_' . md5($tmp . $displayName), 0, 200) . $fileExtension;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $displayName string original file name
|
||||
* @return string The cleaned file name
|
||||
*/
|
||||
private function cleanFileName($displayName) {
|
||||
$filename = str_replace(array('%20', '+'), '-', $displayName);
|
||||
$filename = preg_replace('/[\s-]+/', '-', $filename);
|
||||
$filename = $this->removeAccents($filename);
|
||||
$filename = preg_replace('/[^A-Za-z0-9\.\-_]/', '', $filename);
|
||||
$filename = trim($filename, '-_');
|
||||
|
||||
return $filename;
|
||||
}
|
||||
|
||||
// The following code has been borrowed from Wordpress, and also from posting_functions.inc.php :P
|
||||
// Credits: http://wordpress.org
|
||||
private function removeAccents($string)
|
||||
{
|
||||
if (!preg_match('/[\x80-\xff]/', $string)) {
|
||||
return $string;
|
||||
}
|
||||
|
||||
if ($this->seemsUtf8($string)) {
|
||||
$chars = array(
|
||||
// Decompositions for Latin-1 Supplement
|
||||
chr(194) . chr(170) => 'a', chr(194) . chr(186) => 'o',
|
||||
chr(195) . chr(128) => 'A', chr(195) . chr(129) => 'A',
|
||||
chr(195) . chr(130) => 'A', chr(195) . chr(131) => 'A',
|
||||
chr(195) . chr(132) => 'A', chr(195) . chr(133) => 'A',
|
||||
chr(195) . chr(134) => 'AE', chr(195) . chr(135) => 'C',
|
||||
chr(195) . chr(136) => 'E', chr(195) . chr(137) => 'E',
|
||||
chr(195) . chr(138) => 'E', chr(195) . chr(139) => 'E',
|
||||
chr(195) . chr(140) => 'I', chr(195) . chr(141) => 'I',
|
||||
chr(195) . chr(142) => 'I', chr(195) . chr(143) => 'I',
|
||||
chr(195) . chr(144) => 'D', chr(195) . chr(145) => 'N',
|
||||
chr(195) . chr(146) => 'O', chr(195) . chr(147) => 'O',
|
||||
chr(195) . chr(148) => 'O', chr(195) . chr(149) => 'O',
|
||||
chr(195) . chr(150) => 'O', chr(195) . chr(153) => 'U',
|
||||
chr(195) . chr(154) => 'U', chr(195) . chr(155) => 'U',
|
||||
chr(195) . chr(156) => 'U', chr(195) . chr(157) => 'Y',
|
||||
chr(195) . chr(158) => 'TH', chr(195) . chr(159) => 's',
|
||||
chr(195) . chr(160) => 'a', chr(195) . chr(161) => 'a',
|
||||
chr(195) . chr(162) => 'a', chr(195) . chr(163) => 'a',
|
||||
chr(195) . chr(164) => 'a', chr(195) . chr(165) => 'a',
|
||||
chr(195) . chr(166) => 'ae', chr(195) . chr(167) => 'c',
|
||||
chr(195) . chr(168) => 'e', chr(195) . chr(169) => 'e',
|
||||
chr(195) . chr(170) => 'e', chr(195) . chr(171) => 'e',
|
||||
chr(195) . chr(172) => 'i', chr(195) . chr(173) => 'i',
|
||||
chr(195) . chr(174) => 'i', chr(195) . chr(175) => 'i',
|
||||
chr(195) . chr(176) => 'd', chr(195) . chr(177) => 'n',
|
||||
chr(195) . chr(178) => 'o', chr(195) . chr(179) => 'o',
|
||||
chr(195) . chr(180) => 'o', chr(195) . chr(181) => 'o',
|
||||
chr(195) . chr(182) => 'o', chr(195) . chr(184) => 'o',
|
||||
chr(195) . chr(185) => 'u', chr(195) . chr(186) => 'u',
|
||||
chr(195) . chr(187) => 'u', chr(195) . chr(188) => 'u',
|
||||
chr(195) . chr(189) => 'y', chr(195) . chr(190) => 'th',
|
||||
chr(195) . chr(191) => 'y', chr(195) . chr(152) => 'O',
|
||||
// Decompositions for Latin Extended-A
|
||||
chr(196) . chr(128) => 'A', chr(196) . chr(129) => 'a',
|
||||
chr(196) . chr(130) => 'A', chr(196) . chr(131) => 'a',
|
||||
chr(196) . chr(132) => 'A', chr(196) . chr(133) => 'a',
|
||||
chr(196) . chr(134) => 'C', chr(196) . chr(135) => 'c',
|
||||
chr(196) . chr(136) => 'C', chr(196) . chr(137) => 'c',
|
||||
chr(196) . chr(138) => 'C', chr(196) . chr(139) => 'c',
|
||||
chr(196) . chr(140) => 'C', chr(196) . chr(141) => 'c',
|
||||
chr(196) . chr(142) => 'D', chr(196) . chr(143) => 'd',
|
||||
chr(196) . chr(144) => 'D', chr(196) . chr(145) => 'd',
|
||||
chr(196) . chr(146) => 'E', chr(196) . chr(147) => 'e',
|
||||
chr(196) . chr(148) => 'E', chr(196) . chr(149) => 'e',
|
||||
chr(196) . chr(150) => 'E', chr(196) . chr(151) => 'e',
|
||||
chr(196) . chr(152) => 'E', chr(196) . chr(153) => 'e',
|
||||
chr(196) . chr(154) => 'E', chr(196) . chr(155) => 'e',
|
||||
chr(196) . chr(156) => 'G', chr(196) . chr(157) => 'g',
|
||||
chr(196) . chr(158) => 'G', chr(196) . chr(159) => 'g',
|
||||
chr(196) . chr(160) => 'G', chr(196) . chr(161) => 'g',
|
||||
chr(196) . chr(162) => 'G', chr(196) . chr(163) => 'g',
|
||||
chr(196) . chr(164) => 'H', chr(196) . chr(165) => 'h',
|
||||
chr(196) . chr(166) => 'H', chr(196) . chr(167) => 'h',
|
||||
chr(196) . chr(168) => 'I', chr(196) . chr(169) => 'i',
|
||||
chr(196) . chr(170) => 'I', chr(196) . chr(171) => 'i',
|
||||
chr(196) . chr(172) => 'I', chr(196) . chr(173) => 'i',
|
||||
chr(196) . chr(174) => 'I', chr(196) . chr(175) => 'i',
|
||||
chr(196) . chr(176) => 'I', chr(196) . chr(177) => 'i',
|
||||
chr(196) . chr(178) => 'IJ', chr(196) . chr(179) => 'ij',
|
||||
chr(196) . chr(180) => 'J', chr(196) . chr(181) => 'j',
|
||||
chr(196) . chr(182) => 'K', chr(196) . chr(183) => 'k',
|
||||
chr(196) . chr(184) => 'k', chr(196) . chr(185) => 'L',
|
||||
chr(196) . chr(186) => 'l', chr(196) . chr(187) => 'L',
|
||||
chr(196) . chr(188) => 'l', chr(196) . chr(189) => 'L',
|
||||
chr(196) . chr(190) => 'l', chr(196) . chr(191) => 'L',
|
||||
chr(197) . chr(128) => 'l', chr(197) . chr(129) => 'L',
|
||||
chr(197) . chr(130) => 'l', chr(197) . chr(131) => 'N',
|
||||
chr(197) . chr(132) => 'n', chr(197) . chr(133) => 'N',
|
||||
chr(197) . chr(134) => 'n', chr(197) . chr(135) => 'N',
|
||||
chr(197) . chr(136) => 'n', chr(197) . chr(137) => 'N',
|
||||
chr(197) . chr(138) => 'n', chr(197) . chr(139) => 'N',
|
||||
chr(197) . chr(140) => 'O', chr(197) . chr(141) => 'o',
|
||||
chr(197) . chr(142) => 'O', chr(197) . chr(143) => 'o',
|
||||
chr(197) . chr(144) => 'O', chr(197) . chr(145) => 'o',
|
||||
chr(197) . chr(146) => 'OE', chr(197) . chr(147) => 'oe',
|
||||
chr(197) . chr(148) => 'R', chr(197) . chr(149) => 'r',
|
||||
chr(197) . chr(150) => 'R', chr(197) . chr(151) => 'r',
|
||||
chr(197) . chr(152) => 'R', chr(197) . chr(153) => 'r',
|
||||
chr(197) . chr(154) => 'S', chr(197) . chr(155) => 's',
|
||||
chr(197) . chr(156) => 'S', chr(197) . chr(157) => 's',
|
||||
chr(197) . chr(158) => 'S', chr(197) . chr(159) => 's',
|
||||
chr(197) . chr(160) => 'S', chr(197) . chr(161) => 's',
|
||||
chr(197) . chr(162) => 'T', chr(197) . chr(163) => 't',
|
||||
chr(197) . chr(164) => 'T', chr(197) . chr(165) => 't',
|
||||
chr(197) . chr(166) => 'T', chr(197) . chr(167) => 't',
|
||||
chr(197) . chr(168) => 'U', chr(197) . chr(169) => 'u',
|
||||
chr(197) . chr(170) => 'U', chr(197) . chr(171) => 'u',
|
||||
chr(197) . chr(172) => 'U', chr(197) . chr(173) => 'u',
|
||||
chr(197) . chr(174) => 'U', chr(197) . chr(175) => 'u',
|
||||
chr(197) . chr(176) => 'U', chr(197) . chr(177) => 'u',
|
||||
chr(197) . chr(178) => 'U', chr(197) . chr(179) => 'u',
|
||||
chr(197) . chr(180) => 'W', chr(197) . chr(181) => 'w',
|
||||
chr(197) . chr(182) => 'Y', chr(197) . chr(183) => 'y',
|
||||
chr(197) . chr(184) => 'Y', chr(197) . chr(185) => 'Z',
|
||||
chr(197) . chr(186) => 'z', chr(197) . chr(187) => 'Z',
|
||||
chr(197) . chr(188) => 'z', chr(197) . chr(189) => 'Z',
|
||||
chr(197) . chr(190) => 'z', chr(197) . chr(191) => 's',
|
||||
// Decompositions for Latin Extended-B
|
||||
chr(200) . chr(152) => 'S', chr(200) . chr(153) => 's',
|
||||
chr(200) . chr(154) => 'T', chr(200) . chr(155) => 't',
|
||||
// Euro Sign
|
||||
chr(226) . chr(130) . chr(172) => 'E',
|
||||
// GBP (Pound) Sign
|
||||
chr(194) . chr(163) => '',
|
||||
// Vowels with diacritic (Vietnamese)
|
||||
// unmarked
|
||||
chr(198) . chr(160) => 'O', chr(198) . chr(161) => 'o',
|
||||
chr(198) . chr(175) => 'U', chr(198) . chr(176) => 'u',
|
||||
// grave accent
|
||||
chr(225) . chr(186) . chr(166) => 'A', chr(225) . chr(186) . chr(167) => 'a',
|
||||
chr(225) . chr(186) . chr(176) => 'A', chr(225) . chr(186) . chr(177) => 'a',
|
||||
chr(225) . chr(187) . chr(128) => 'E', chr(225) . chr(187) . chr(129) => 'e',
|
||||
chr(225) . chr(187) . chr(146) => 'O', chr(225) . chr(187) . chr(147) => 'o',
|
||||
chr(225) . chr(187) . chr(156) => 'O', chr(225) . chr(187) . chr(157) => 'o',
|
||||
chr(225) . chr(187) . chr(170) => 'U', chr(225) . chr(187) . chr(171) => 'u',
|
||||
chr(225) . chr(187) . chr(178) => 'Y', chr(225) . chr(187) . chr(179) => 'y',
|
||||
// hook
|
||||
chr(225) . chr(186) . chr(162) => 'A', chr(225) . chr(186) . chr(163) => 'a',
|
||||
chr(225) . chr(186) . chr(168) => 'A', chr(225) . chr(186) . chr(169) => 'a',
|
||||
chr(225) . chr(186) . chr(178) => 'A', chr(225) . chr(186) . chr(179) => 'a',
|
||||
chr(225) . chr(186) . chr(186) => 'E', chr(225) . chr(186) . chr(187) => 'e',
|
||||
chr(225) . chr(187) . chr(130) => 'E', chr(225) . chr(187) . chr(131) => 'e',
|
||||
chr(225) . chr(187) . chr(136) => 'I', chr(225) . chr(187) . chr(137) => 'i',
|
||||
chr(225) . chr(187) . chr(142) => 'O', chr(225) . chr(187) . chr(143) => 'o',
|
||||
chr(225) . chr(187) . chr(148) => 'O', chr(225) . chr(187) . chr(149) => 'o',
|
||||
chr(225) . chr(187) . chr(158) => 'O', chr(225) . chr(187) . chr(159) => 'o',
|
||||
chr(225) . chr(187) . chr(166) => 'U', chr(225) . chr(187) . chr(167) => 'u',
|
||||
chr(225) . chr(187) . chr(172) => 'U', chr(225) . chr(187) . chr(173) => 'u',
|
||||
chr(225) . chr(187) . chr(182) => 'Y', chr(225) . chr(187) . chr(183) => 'y',
|
||||
// tilde
|
||||
chr(225) . chr(186) . chr(170) => 'A', chr(225) . chr(186) . chr(171) => 'a',
|
||||
chr(225) . chr(186) . chr(180) => 'A', chr(225) . chr(186) . chr(181) => 'a',
|
||||
chr(225) . chr(186) . chr(188) => 'E', chr(225) . chr(186) . chr(189) => 'e',
|
||||
chr(225) . chr(187) . chr(132) => 'E', chr(225) . chr(187) . chr(133) => 'e',
|
||||
chr(225) . chr(187) . chr(150) => 'O', chr(225) . chr(187) . chr(151) => 'o',
|
||||
chr(225) . chr(187) . chr(160) => 'O', chr(225) . chr(187) . chr(161) => 'o',
|
||||
chr(225) . chr(187) . chr(174) => 'U', chr(225) . chr(187) . chr(175) => 'u',
|
||||
chr(225) . chr(187) . chr(184) => 'Y', chr(225) . chr(187) . chr(185) => 'y',
|
||||
// acute accent
|
||||
chr(225) . chr(186) . chr(164) => 'A', chr(225) . chr(186) . chr(165) => 'a',
|
||||
chr(225) . chr(186) . chr(174) => 'A', chr(225) . chr(186) . chr(175) => 'a',
|
||||
chr(225) . chr(186) . chr(190) => 'E', chr(225) . chr(186) . chr(191) => 'e',
|
||||
chr(225) . chr(187) . chr(144) => 'O', chr(225) . chr(187) . chr(145) => 'o',
|
||||
chr(225) . chr(187) . chr(154) => 'O', chr(225) . chr(187) . chr(155) => 'o',
|
||||
chr(225) . chr(187) . chr(168) => 'U', chr(225) . chr(187) . chr(169) => 'u',
|
||||
// dot below
|
||||
chr(225) . chr(186) . chr(160) => 'A', chr(225) . chr(186) . chr(161) => 'a',
|
||||
chr(225) . chr(186) . chr(172) => 'A', chr(225) . chr(186) . chr(173) => 'a',
|
||||
chr(225) . chr(186) . chr(182) => 'A', chr(225) . chr(186) . chr(183) => 'a',
|
||||
chr(225) . chr(186) . chr(184) => 'E', chr(225) . chr(186) . chr(185) => 'e',
|
||||
chr(225) . chr(187) . chr(134) => 'E', chr(225) . chr(187) . chr(135) => 'e',
|
||||
chr(225) . chr(187) . chr(138) => 'I', chr(225) . chr(187) . chr(139) => 'i',
|
||||
chr(225) . chr(187) . chr(140) => 'O', chr(225) . chr(187) . chr(141) => 'o',
|
||||
chr(225) . chr(187) . chr(152) => 'O', chr(225) . chr(187) . chr(153) => 'o',
|
||||
chr(225) . chr(187) . chr(162) => 'O', chr(225) . chr(187) . chr(163) => 'o',
|
||||
chr(225) . chr(187) . chr(164) => 'U', chr(225) . chr(187) . chr(165) => 'u',
|
||||
chr(225) . chr(187) . chr(176) => 'U', chr(225) . chr(187) . chr(177) => 'u',
|
||||
chr(225) . chr(187) . chr(180) => 'Y', chr(225) . chr(187) . chr(181) => 'y',
|
||||
// Vowels with diacritic (Chinese, Hanyu Pinyin)
|
||||
chr(201) . chr(145) => 'a',
|
||||
// macron
|
||||
chr(199) . chr(149) => 'U', chr(199) . chr(150) => 'u',
|
||||
// acute accent
|
||||
chr(199) . chr(151) => 'U', chr(199) . chr(152) => 'u',
|
||||
// caron
|
||||
chr(199) . chr(141) => 'A', chr(199) . chr(142) => 'a',
|
||||
chr(199) . chr(143) => 'I', chr(199) . chr(144) => 'i',
|
||||
chr(199) . chr(145) => 'O', chr(199) . chr(146) => 'o',
|
||||
chr(199) . chr(147) => 'U', chr(199) . chr(148) => 'u',
|
||||
chr(199) . chr(153) => 'U', chr(199) . chr(154) => 'u',
|
||||
// grave accent
|
||||
chr(199) . chr(155) => 'U', chr(199) . chr(156) => 'u',
|
||||
);
|
||||
|
||||
$string = strtr($string, $chars);
|
||||
} else {
|
||||
// Assume ISO-8859-1 if not UTF-8
|
||||
$chars['in'] = chr(128) . chr(131) . chr(138) . chr(142) . chr(154) . chr(158)
|
||||
. chr(159) . chr(162) . chr(165) . chr(181) . chr(192) . chr(193) . chr(194)
|
||||
. chr(195) . chr(196) . chr(197) . chr(199) . chr(200) . chr(201) . chr(202)
|
||||
. chr(203) . chr(204) . chr(205) . chr(206) . chr(207) . chr(209) . chr(210)
|
||||
. chr(211) . chr(212) . chr(213) . chr(214) . chr(216) . chr(217) . chr(218)
|
||||
. chr(219) . chr(220) . chr(221) . chr(224) . chr(225) . chr(226) . chr(227)
|
||||
. chr(228) . chr(229) . chr(231) . chr(232) . chr(233) . chr(234) . chr(235)
|
||||
. chr(236) . chr(237) . chr(238) . chr(239) . chr(241) . chr(242) . chr(243)
|
||||
. chr(244) . chr(245) . chr(246) . chr(248) . chr(249) . chr(250) . chr(251)
|
||||
. chr(252) . chr(253) . chr(255);
|
||||
|
||||
$chars['out'] = "EfSZszYcYuAAAAAACEEEEIIIINOOOOOOUUUUYaaaaaaceeeeiiiinoooooouuuuyy";
|
||||
|
||||
$string = strtr($string, $chars['in'], $chars['out']);
|
||||
$double_chars['in'] = array(chr(140), chr(156), chr(198), chr(208), chr(222), chr(223), chr(230), chr(240), chr(254));
|
||||
$double_chars['out'] = array('OE', 'oe', 'AE', 'DH', 'TH', 'ss', 'ae', 'dh', 'th');
|
||||
$string = str_replace($double_chars['in'], $double_chars['out'], $string);
|
||||
}
|
||||
|
||||
return $string;
|
||||
}
|
||||
|
||||
private function seemsUtf8($str)
|
||||
{
|
||||
$length = strlen($str);
|
||||
for ($i = 0; $i < $length; $i++) {
|
||||
$c = ord($str[$i]);
|
||||
if ($c < 0x80) $n = 0; # 0bbbbbbb
|
||||
elseif (($c & 0xE0) == 0xC0) $n = 1; # 110bbbbb
|
||||
elseif (($c & 0xF0) == 0xE0) $n = 2; # 1110bbbb
|
||||
elseif (($c & 0xF8) == 0xF0) $n = 3; # 11110bbb
|
||||
elseif (($c & 0xFC) == 0xF8) $n = 4; # 111110bb
|
||||
elseif (($c & 0xFE) == 0xFC) $n = 5; # 1111110b
|
||||
else return false; # Does not match any model
|
||||
for ($j = 0; $j < $n; $j++) { # n bytes matching 10bbbbbb follow ?
|
||||
if ((++$i == $length) || ((ord($str[$i]) & 0xC0) != 0x80))
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $ticket Ticket
|
||||
* @param $ticketAttachment TicketAttachment
|
||||
* @param $attachmentId int
|
||||
* @param $heskSettings array
|
||||
*/
|
||||
private function updateAttachmentsOnTicket($ticket, $ticketAttachment, $attachmentId, $heskSettings) {
|
||||
$attachments = $ticket->attachments === null ? array() : $ticket->attachments;
|
||||
$newAttachment = new Attachment();
|
||||
$newAttachment->savedName = $ticketAttachment->savedName;
|
||||
$newAttachment->fileName = $ticketAttachment->displayName;
|
||||
$newAttachment->id = $attachmentId;
|
||||
$attachments[] = $newAttachment;
|
||||
$this->ticketGateway->updateAttachmentsForTicket($ticket->id, $attachments, $heskSettings);
|
||||
}
|
||||
}
|
64
api/BusinessLogic/Attachments/AttachmentRetriever.php
Normal file
64
api/BusinessLogic/Attachments/AttachmentRetriever.php
Normal file
@ -0,0 +1,64 @@
|
||||
<?php
|
||||
|
||||
namespace BusinessLogic\Attachments;
|
||||
|
||||
|
||||
use BusinessLogic\Exceptions\AccessViolationException;
|
||||
use BusinessLogic\Exceptions\ApiFriendlyException;
|
||||
use BusinessLogic\Security\UserToTicketChecker;
|
||||
use DataAccess\Attachments\AttachmentGateway;
|
||||
use DataAccess\Files\FileReader;
|
||||
use DataAccess\Tickets\TicketGateway;
|
||||
|
||||
class AttachmentRetriever extends \BaseClass {
|
||||
/* @var $attachmentGateway AttachmentGateway */
|
||||
private $attachmentGateway;
|
||||
|
||||
/* @var $fileReader FileReader */
|
||||
private $fileReader;
|
||||
|
||||
/* @var $ticketGateway TicketGateway */
|
||||
private $ticketGateway;
|
||||
|
||||
/* @var $userToTicketChecker UserToTicketChecker */
|
||||
private $userToTicketChecker;
|
||||
|
||||
function __construct($attachmentGateway, $fileReader, $ticketGateway, $userToTicketChecker) {
|
||||
$this->attachmentGateway = $attachmentGateway;
|
||||
$this->fileReader = $fileReader;
|
||||
$this->ticketGateway = $ticketGateway;
|
||||
$this->userToTicketChecker = $userToTicketChecker;
|
||||
}
|
||||
|
||||
//-- TODO Test
|
||||
function getAttachmentContentsForTrackingId($trackingId, $attachmentId, $userContext, $heskSettings) {
|
||||
$ticket = $this->ticketGateway->getTicketByTrackingId($trackingId, $heskSettings);
|
||||
|
||||
if ($ticket === null) {
|
||||
throw new ApiFriendlyException("Ticket {$trackingId} not found!", "Ticket Not Found", 404);
|
||||
}
|
||||
|
||||
$attachment = $this->attachmentGateway->getAttachmentById($attachmentId, $heskSettings);
|
||||
|
||||
return array('meta' => $attachment,
|
||||
'contents' => $this->fileReader->readFromFile($attachment->savedName, $heskSettings['attach_dir']));
|
||||
}
|
||||
|
||||
function getAttachmentContentsForTicket($ticketId, $attachmentId, $userContext, $heskSettings) {
|
||||
$ticket = $this->ticketGateway->getTicketById($ticketId, $heskSettings);
|
||||
|
||||
if ($ticket === null) {
|
||||
throw new ApiFriendlyException("Ticket {$ticketId} not found!", "Ticket Not Found", 404);
|
||||
}
|
||||
|
||||
if (!$this->userToTicketChecker->isTicketAccessibleToUser($userContext, $ticket, $heskSettings)) {
|
||||
throw new AccessViolationException("User does not have access to attachment {$attachmentId}!");
|
||||
}
|
||||
|
||||
$attachment = $this->attachmentGateway->getAttachmentById($attachmentId, $heskSettings);
|
||||
$contents = base64_encode($this->fileReader->readFromFile(
|
||||
$attachment->savedName, $heskSettings['attach_dir']));
|
||||
|
||||
return $contents;
|
||||
}
|
||||
}
|
9
api/BusinessLogic/Attachments/AttachmentType.php
Normal file
9
api/BusinessLogic/Attachments/AttachmentType.php
Normal file
@ -0,0 +1,9 @@
|
||||
<?php
|
||||
|
||||
namespace BusinessLogic\Attachments;
|
||||
|
||||
|
||||
class AttachmentType extends \BaseClass {
|
||||
const MESSAGE = 0;
|
||||
const REPLY = 1;
|
||||
}
|
@ -0,0 +1,9 @@
|
||||
<?php
|
||||
|
||||
namespace BusinessLogic\Attachments;
|
||||
|
||||
|
||||
class CreateAttachmentForTicketModel extends CreateAttachmentModel {
|
||||
/* @var $ticketId int */
|
||||
public $ticketId;
|
||||
}
|
21
api/BusinessLogic/Attachments/CreateAttachmentModel.php
Normal file
21
api/BusinessLogic/Attachments/CreateAttachmentModel.php
Normal file
@ -0,0 +1,21 @@
|
||||
<?php
|
||||
|
||||
namespace BusinessLogic\Attachments;
|
||||
|
||||
|
||||
class CreateAttachmentModel extends \BaseClass {
|
||||
/* @var $savedName string */
|
||||
public $savedName;
|
||||
|
||||
/* @var $displayName string */
|
||||
public $displayName;
|
||||
|
||||
/* @var $id int */
|
||||
public $fileSize;
|
||||
|
||||
/* @var $attachmentContents string */
|
||||
public $attachmentContents;
|
||||
|
||||
/* @var $isEditing bool */
|
||||
public $isEditing;
|
||||
}
|
12
api/BusinessLogic/Attachments/TicketAttachment.php
Normal file
12
api/BusinessLogic/Attachments/TicketAttachment.php
Normal file
@ -0,0 +1,12 @@
|
||||
<?php
|
||||
|
||||
namespace BusinessLogic\Attachments;
|
||||
|
||||
|
||||
class TicketAttachment extends Attachment {
|
||||
/* @var $ticketTrackingId string */
|
||||
public $ticketTrackingId;
|
||||
|
||||
/* @var $type int [use <code>AttachmentType</code>] */
|
||||
public $type;
|
||||
}
|
22
api/BusinessLogic/Calendar/AbstractEvent.php
Normal file
22
api/BusinessLogic/Calendar/AbstractEvent.php
Normal file
@ -0,0 +1,22 @@
|
||||
<?php
|
||||
|
||||
namespace BusinessLogic\Calendar;
|
||||
|
||||
|
||||
class AbstractEvent {
|
||||
public $id;
|
||||
|
||||
public $startTime;
|
||||
|
||||
public $title;
|
||||
|
||||
public $categoryId;
|
||||
|
||||
public $categoryName;
|
||||
|
||||
public $backgroundColor;
|
||||
|
||||
public $foregroundColor;
|
||||
|
||||
public $displayBorder;
|
||||
}
|
15
api/BusinessLogic/Calendar/BusinessHours.php
Normal file
15
api/BusinessLogic/Calendar/BusinessHours.php
Normal file
@ -0,0 +1,15 @@
|
||||
<?php
|
||||
|
||||
namespace BusinessLogic\Calendar;
|
||||
|
||||
|
||||
class BusinessHours {
|
||||
/* @var $dayOfWeek int */
|
||||
public $dayOfWeek;
|
||||
|
||||
/* @var $startTime string */
|
||||
public $startTime;
|
||||
|
||||
/* @var $endTime string */
|
||||
public $endTime;
|
||||
}
|
26
api/BusinessLogic/Calendar/CalendarEvent.php
Normal file
26
api/BusinessLogic/Calendar/CalendarEvent.php
Normal file
@ -0,0 +1,26 @@
|
||||
<?php
|
||||
|
||||
namespace BusinessLogic\Calendar;
|
||||
|
||||
|
||||
use BusinessLogic\Tickets\AuditTrail;
|
||||
|
||||
class CalendarEvent extends AbstractEvent {
|
||||
public $type = 'CALENDAR';
|
||||
|
||||
public $endTime;
|
||||
|
||||
/* @var $allDay bool */
|
||||
public $allDay;
|
||||
|
||||
public $location;
|
||||
|
||||
public $comments;
|
||||
|
||||
public $reminderValue;
|
||||
|
||||
public $reminderUnits;
|
||||
|
||||
/* @var $auditTrail AuditTrail[] */
|
||||
public $auditTrail = array();
|
||||
}
|
96
api/BusinessLogic/Calendar/CalendarHandler.php
Normal file
96
api/BusinessLogic/Calendar/CalendarHandler.php
Normal file
@ -0,0 +1,96 @@
|
||||
<?php
|
||||
|
||||
namespace BusinessLogic\Calendar;
|
||||
|
||||
|
||||
use BusinessLogic\DateTimeHelpers;
|
||||
use BusinessLogic\Security\UserContext;
|
||||
use BusinessLogic\Tickets\AuditTrailEntityType;
|
||||
use DataAccess\AuditTrail\AuditTrailGateway;
|
||||
use DataAccess\Calendar\CalendarGateway;
|
||||
|
||||
class CalendarHandler extends \BaseClass {
|
||||
private $calendarGateway;
|
||||
private $auditTrailGateway;
|
||||
|
||||
public function __construct(CalendarGateway $calendarGateway,
|
||||
AuditTrailGateway $auditTrailGateway) {
|
||||
$this->calendarGateway = $calendarGateway;
|
||||
$this->auditTrailGateway = $auditTrailGateway;
|
||||
}
|
||||
|
||||
public function getEventsForStaff($searchEventsFilter, $heskSettings) {
|
||||
return $this->calendarGateway->getEventsForStaff($searchEventsFilter, $heskSettings);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $calendarEvent CalendarEvent
|
||||
* @param $userContext UserContext
|
||||
* @param $heskSettings array
|
||||
* @return CalendarEvent
|
||||
* @throws \Exception If more than one event is returned for the given ID
|
||||
*/
|
||||
public function updateEvent($calendarEvent, $userContext, $heskSettings) {
|
||||
$this->calendarGateway->updateEvent($calendarEvent, $userContext, $heskSettings);
|
||||
|
||||
$this->auditTrailGateway->insertAuditTrailRecord($calendarEvent->id,
|
||||
AuditTrailEntityType::CALENDAR_EVENT,
|
||||
'audit_event_updated',
|
||||
DateTimeHelpers::heskDate($heskSettings),
|
||||
array(0 => $userContext->name . ' (' . $userContext->username . ')'), $heskSettings);
|
||||
|
||||
$eventFilter = new SearchEventsFilter();
|
||||
$eventFilter->eventId = $calendarEvent->id;
|
||||
$eventFilter->reminderUserId = $userContext->id;
|
||||
|
||||
$events = $this->calendarGateway->getEventsForStaff($eventFilter, $heskSettings);
|
||||
|
||||
if (count($events) !== 1) {
|
||||
throw new \Exception("Expected exactly 1 event, found: " . count($events));
|
||||
}
|
||||
|
||||
$event = $events[0];
|
||||
|
||||
return $event;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param $calendarEvent CalendarEvent
|
||||
* @param $userContext UserContext
|
||||
* @param $heskSettings array
|
||||
* @return AbstractEvent
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function createEvent($calendarEvent, $userContext, $heskSettings) {
|
||||
$this->calendarGateway->createEvent($calendarEvent, $userContext, $heskSettings);
|
||||
|
||||
$eventFilter = new SearchEventsFilter();
|
||||
$eventFilter->eventId = $calendarEvent->id;
|
||||
$eventFilter->reminderUserId = $userContext->id;
|
||||
|
||||
$events = $this->calendarGateway->getEventsForStaff($eventFilter, $heskSettings);
|
||||
|
||||
if (count($events) !== 1) {
|
||||
throw new \Exception("Expected exactly 1 event, found: " . count($events));
|
||||
}
|
||||
|
||||
$event = $events[0];
|
||||
|
||||
$this->auditTrailGateway->insertAuditTrailRecord($event->id,
|
||||
AuditTrailEntityType::CALENDAR_EVENT,
|
||||
'audit_event_created',
|
||||
DateTimeHelpers::heskDate($heskSettings),
|
||||
array(0 => $userContext->name . ' (' . $userContext->username . ')'), $heskSettings);
|
||||
|
||||
return $event;
|
||||
}
|
||||
|
||||
public function deleteEvent($id, $userContext, $heskSettings) {
|
||||
$this->calendarGateway->deleteEvent($id, $userContext, $heskSettings);
|
||||
}
|
||||
|
||||
public function getBusinessHours($heskSettings) {
|
||||
return $this->calendarGateway->getBusinessHours($heskSettings);
|
||||
}
|
||||
}
|
41
api/BusinessLogic/Calendar/ReminderUnit.php
Normal file
41
api/BusinessLogic/Calendar/ReminderUnit.php
Normal file
@ -0,0 +1,41 @@
|
||||
<?php
|
||||
|
||||
namespace BusinessLogic\Calendar;
|
||||
|
||||
|
||||
class ReminderUnit {
|
||||
const MINUTE = 0;
|
||||
const HOUR = 1;
|
||||
const DAY = 2;
|
||||
const WEEK = 3;
|
||||
|
||||
static function getByValue($value) {
|
||||
switch ($value) {
|
||||
case 0:
|
||||
return 'MINUTE';
|
||||
case 1:
|
||||
return 'HOUR';
|
||||
case 2:
|
||||
return 'DAY';
|
||||
case 3:
|
||||
return 'WEEK';
|
||||
default:
|
||||
return 'UNKNOWN';
|
||||
}
|
||||
}
|
||||
|
||||
static function getByName($name) {
|
||||
switch ($name) {
|
||||
case 'MINUTE':
|
||||
return self::MINUTE;
|
||||
case 'HOUR':
|
||||
return self::HOUR;
|
||||
case 'DAY':
|
||||
return self::DAY;
|
||||
case 'WEEK':
|
||||
return self::WEEK;
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
33
api/BusinessLogic/Calendar/SearchEventsFilter.php
Normal file
33
api/BusinessLogic/Calendar/SearchEventsFilter.php
Normal file
@ -0,0 +1,33 @@
|
||||
<?php
|
||||
|
||||
namespace BusinessLogic\Calendar;
|
||||
|
||||
|
||||
class SearchEventsFilter {
|
||||
/* @var $startTime int|null */
|
||||
public $startTime;
|
||||
|
||||
/* @var $endTime int|null */
|
||||
public $endTime;
|
||||
|
||||
/* @var $id int|null */
|
||||
public $eventId;
|
||||
|
||||
/* @var $categories int[]|null */
|
||||
public $categories;
|
||||
|
||||
/* @var $reminderUserId int|null */
|
||||
public $reminderUserId;
|
||||
|
||||
/* @var $includeTickets bool */
|
||||
public $includeTickets;
|
||||
|
||||
/* @var $includeUnassignedTickets bool */
|
||||
public $includeUnassignedTickets;
|
||||
|
||||
/* @var $includeTicketsAssignedToOthers bool */
|
||||
public $includeTicketsAssignedToOthers;
|
||||
|
||||
/* @var $includeTicketsAssignedToMe bool */
|
||||
public $includeTicketsAssignedToMe;
|
||||
}
|
20
api/BusinessLogic/Calendar/TicketEvent.php
Normal file
20
api/BusinessLogic/Calendar/TicketEvent.php
Normal file
@ -0,0 +1,20 @@
|
||||
<?php
|
||||
|
||||
namespace BusinessLogic\Calendar;
|
||||
|
||||
|
||||
class TicketEvent extends AbstractEvent {
|
||||
public $type = 'TICKET';
|
||||
|
||||
public $trackingId;
|
||||
|
||||
public $subject;
|
||||
|
||||
public $url;
|
||||
|
||||
public $owner;
|
||||
|
||||
public $priority;
|
||||
|
||||
public $status;
|
||||
}
|
73
api/BusinessLogic/Categories/Category.php
Normal file
73
api/BusinessLogic/Categories/Category.php
Normal file
@ -0,0 +1,73 @@
|
||||
<?php
|
||||
|
||||
namespace BusinessLogic\Categories;
|
||||
|
||||
class Category extends \BaseClass {
|
||||
/**
|
||||
* @var int The Categories ID
|
||||
*/
|
||||
public $id;
|
||||
|
||||
/* @var $name string */
|
||||
public $name;
|
||||
|
||||
/**
|
||||
* @var int Categories order number
|
||||
*/
|
||||
public $catOrder;
|
||||
|
||||
/**
|
||||
* @var bool Tickets autoassigned in this Categories
|
||||
*/
|
||||
public $autoAssign;
|
||||
|
||||
/**
|
||||
* @var int The type of Categories (1 = Private, 0 = Public)
|
||||
*/
|
||||
public $type;
|
||||
|
||||
/**
|
||||
* @var int The Categories's usage (0 = Tickets and Events, 1 = Tickets, 2 = Events)
|
||||
*/
|
||||
public $usage;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
public $backgroundColor;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
public $foregroundColor;
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
public $displayBorder;
|
||||
|
||||
/**
|
||||
* @var int The default Tickets priority
|
||||
*/
|
||||
public $priority;
|
||||
|
||||
/**
|
||||
* @var int|null The manager for the Categories, if applicable
|
||||
*/
|
||||
public $manager;
|
||||
|
||||
/**
|
||||
* @var bool Indication if the user has access to the Categories
|
||||
*/
|
||||
public $accessible;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
public $description;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
public $numberOfTickets;
|
||||
}
|
203
api/BusinessLogic/Categories/CategoryHandler.php
Normal file
203
api/BusinessLogic/Categories/CategoryHandler.php
Normal file
@ -0,0 +1,203 @@
|
||||
<?php
|
||||
|
||||
namespace BusinessLogic\Categories;
|
||||
|
||||
|
||||
use BusinessLogic\Exceptions\AccessViolationException;
|
||||
use BusinessLogic\Exceptions\ValidationException;
|
||||
use BusinessLogic\Navigation\Direction;
|
||||
use BusinessLogic\Security\PermissionChecker;
|
||||
use BusinessLogic\Security\UserPrivilege;
|
||||
use BusinessLogic\ValidationModel;
|
||||
use DataAccess\Categories\CategoryGateway;
|
||||
use DataAccess\Settings\ModsForHeskSettingsGateway;
|
||||
use DataAccess\Tickets\TicketGateway;
|
||||
|
||||
class CategoryHandler extends \BaseClass {
|
||||
/* @var $categoryGateway CategoryGateway */
|
||||
private $categoryGateway;
|
||||
|
||||
/* @var $ticketGateway TicketGateway */
|
||||
private $ticketGateway;
|
||||
|
||||
/* @var $permissionChecker PermissionChecker */
|
||||
private $permissionChecker;
|
||||
|
||||
/* @var $modsForHeskSettingsGateway ModsForHeskSettingsGateway */
|
||||
private $modsForHeskSettingsGateway;
|
||||
|
||||
function __construct(CategoryGateway $categoryGateway,
|
||||
TicketGateway $ticketGateway,
|
||||
PermissionChecker $permissionChecker,
|
||||
ModsForHeskSettingsGateway $modsForHeskSettingsGateway) {
|
||||
$this->categoryGateway = $categoryGateway;
|
||||
$this->ticketGateway = $ticketGateway;
|
||||
$this->permissionChecker = $permissionChecker;
|
||||
$this->modsForHeskSettingsGateway = $modsForHeskSettingsGateway;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $category Category
|
||||
* @param $userContext
|
||||
* @param $heskSettings array
|
||||
* @return Category The newly created category with ID
|
||||
* @throws ValidationException When validation fails
|
||||
* @throws \Exception When the newly created category was not retrieved
|
||||
*/
|
||||
//TODO Test
|
||||
function createCategory($category, $userContext, $heskSettings) {
|
||||
$modsForHeskSettings = $this->modsForHeskSettingsGateway->getAllSettings($heskSettings);
|
||||
|
||||
$validationModel = $this->validate($category, $userContext);
|
||||
|
||||
if (count($validationModel->errorKeys) > 0) {
|
||||
throw new ValidationException($validationModel);
|
||||
}
|
||||
|
||||
$id = $this->categoryGateway->createCategory($category, $heskSettings);
|
||||
|
||||
$allCategories = $this->categoryGateway->getAllCategories($heskSettings, $modsForHeskSettings);
|
||||
|
||||
foreach ($allCategories as $innerCategory) {
|
||||
if ($innerCategory->id === $id) {
|
||||
return $innerCategory;
|
||||
}
|
||||
}
|
||||
|
||||
throw new \BaseException("Newly created category {$id} lost! :O");
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $category Category
|
||||
* @param $userContext
|
||||
* @param $creating bool
|
||||
* @return ValidationModel
|
||||
* @throws AccessViolationException
|
||||
*/
|
||||
//TODO Test
|
||||
private function validate($category, $userContext, $creating = true) {
|
||||
$validationModel = new ValidationModel();
|
||||
|
||||
if (!$this->permissionChecker->doesUserHavePermission($userContext, UserPrivilege::CAN_MANAGE_CATEGORIES)) {
|
||||
throw new AccessViolationException('User cannot manage categories!');
|
||||
}
|
||||
|
||||
if (!$creating && $category->id < 1) {
|
||||
$validationModel->errorKeys[] = 'ID_MISSING';
|
||||
}
|
||||
|
||||
if ($category->backgroundColor === null || trim($category->backgroundColor) === '') {
|
||||
$validationModel->errorKeys[] = 'BACKGROUND_COLOR_MISSING';
|
||||
}
|
||||
|
||||
if ($category->foregroundColor === null || trim($category->foregroundColor) === '') {
|
||||
$validationModel->errorKeys[] = 'FOREGROUND_COLOR_MISSING';
|
||||
}
|
||||
|
||||
if ($category->name === null || trim($category->name) === '') {
|
||||
$validationModel->errorKeys[] = 'NAME_MISSING';
|
||||
}
|
||||
|
||||
if ($category->priority === null || intval($category->priority) < 0 || intval($category->priority) > 3) {
|
||||
$validationModel->errorKeys[] = 'INVALID_PRIORITY';
|
||||
}
|
||||
|
||||
if ($category->autoAssign === null || !is_bool($category->autoAssign)) {
|
||||
$validationModel->errorKeys[] = 'INVALID_AUTOASSIGN';
|
||||
}
|
||||
|
||||
if ($category->displayBorder === null || !is_bool($category->displayBorder)) {
|
||||
$validationModel->errorKeys[] = 'INVALID_DISPLAY_BORDER';
|
||||
}
|
||||
|
||||
if ($category->type === null || (intval($category->type) !== 0 && intval($category->type) !== 1)) {
|
||||
$validationModel->errorKeys[] = 'INVALID_TYPE';
|
||||
}
|
||||
|
||||
return $validationModel;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $category Category
|
||||
* @param $userContext
|
||||
* @param $heskSettings array
|
||||
* @return Category
|
||||
* @throws ValidationException
|
||||
* @throws \Exception When the category is missing
|
||||
*/
|
||||
function editCategory($category, $userContext, $heskSettings) {
|
||||
$modsForHeskSettings = $this->modsForHeskSettingsGateway->getAllSettings($heskSettings);
|
||||
|
||||
$validationModel = $this->validate($category, $userContext, false);
|
||||
|
||||
if (count($validationModel->errorKeys) > 0) {
|
||||
throw new ValidationException($validationModel);
|
||||
}
|
||||
|
||||
$this->categoryGateway->updateCategory($category, $heskSettings);
|
||||
$this->categoryGateway->resortAllCategories($heskSettings);
|
||||
|
||||
$allCategories = $this->categoryGateway->getAllCategories($heskSettings, $modsForHeskSettings);
|
||||
|
||||
foreach ($allCategories as $innerCategory) {
|
||||
if ($innerCategory->id === $category->id) {
|
||||
return $innerCategory;
|
||||
}
|
||||
}
|
||||
|
||||
throw new \BaseException("Category {$category->id} vanished! :O");
|
||||
}
|
||||
|
||||
function deleteCategory($id, $userContext, $heskSettings) {
|
||||
if (!$this->permissionChecker->doesUserHavePermission($userContext, UserPrivilege::CAN_MANAGE_CATEGORIES)) {
|
||||
throw new AccessViolationException('User cannot manage categories!');
|
||||
}
|
||||
|
||||
if ($id === 1) {
|
||||
throw new \BaseException("Category 1 cannot be deleted!");
|
||||
}
|
||||
|
||||
$this->ticketGateway->moveTicketsToDefaultCategory($id, $heskSettings);
|
||||
$this->categoryGateway->deleteCategory($id, $heskSettings);
|
||||
$this->categoryGateway->resortAllCategories($heskSettings);
|
||||
}
|
||||
|
||||
function sortCategory($id, $direction, $heskSettings) {
|
||||
$modsForHeskSettings = $this->modsForHeskSettingsGateway->getAllSettings($heskSettings);
|
||||
|
||||
$categories = $this->categoryGateway->getAllCategories($heskSettings, $modsForHeskSettings);
|
||||
$category = null;
|
||||
foreach ($categories as $innerCategory) {
|
||||
if ($innerCategory->id === intval($id)) {
|
||||
$category = $innerCategory;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ($category === null) {
|
||||
throw new \BaseException("Could not find category with ID {$id}!");
|
||||
}
|
||||
|
||||
if ($direction === Direction::UP) {
|
||||
$category->catOrder -= 15;
|
||||
} else {
|
||||
$category->catOrder += 15;
|
||||
}
|
||||
|
||||
$this->categoryGateway->updateCategory($category, $heskSettings);
|
||||
$this->categoryGateway->resortAllCategories($heskSettings);
|
||||
}
|
||||
|
||||
function getPublicCategories($heskSettings) {
|
||||
$allCategories = $this->categoryGateway->getAllCategories($heskSettings, $this->modsForHeskSettingsGateway->getAllSettings($heskSettings));
|
||||
|
||||
$publicCategories = array();
|
||||
foreach ($allCategories as $category) {
|
||||
if ($category->type === 0) {
|
||||
$publicCategories[] = $category;
|
||||
}
|
||||
}
|
||||
|
||||
return $publicCategories;
|
||||
}
|
||||
}
|
43
api/BusinessLogic/Categories/CategoryRetriever.php
Normal file
43
api/BusinessLogic/Categories/CategoryRetriever.php
Normal file
@ -0,0 +1,43 @@
|
||||
<?php
|
||||
|
||||
namespace BusinessLogic\Categories;
|
||||
|
||||
use BusinessLogic\Security\UserContext;
|
||||
use DataAccess\Categories\CategoryGateway;
|
||||
use DataAccess\Settings\ModsForHeskSettingsGateway;
|
||||
|
||||
class CategoryRetriever extends \BaseClass {
|
||||
/**
|
||||
* @var CategoryGateway
|
||||
*/
|
||||
private $categoryGateway;
|
||||
|
||||
/**
|
||||
* @var ModsForHeskSettingsGateway
|
||||
*/
|
||||
private $modsForHeskSettingsGateway;
|
||||
|
||||
function __construct(CategoryGateway $categoryGateway,
|
||||
ModsForHeskSettingsGateway $modsForHeskSettingsGateway) {
|
||||
$this->categoryGateway = $categoryGateway;
|
||||
$this->modsForHeskSettingsGateway = $modsForHeskSettingsGateway;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $heskSettings array
|
||||
* @param $userContext UserContext
|
||||
* @return array
|
||||
*/
|
||||
function getAllCategories($heskSettings, $userContext) {
|
||||
$modsForHeskSettings = $this->modsForHeskSettingsGateway->getAllSettings($heskSettings);
|
||||
|
||||
$categories = $this->categoryGateway->getAllCategories($heskSettings, $modsForHeskSettings);
|
||||
|
||||
foreach ($categories as $category) {
|
||||
$category->accessible = $userContext->admin ||
|
||||
in_array($category->id, $userContext->categories);
|
||||
}
|
||||
|
||||
return $categories;
|
||||
}
|
||||
}
|
19
api/BusinessLogic/DateTimeHelpers.php
Normal file
19
api/BusinessLogic/DateTimeHelpers.php
Normal file
@ -0,0 +1,19 @@
|
||||
<?php
|
||||
|
||||
namespace BusinessLogic;
|
||||
|
||||
|
||||
class DateTimeHelpers {
|
||||
static function heskDate($heskSettings, $dt = '', $isStr = true, $return_str = true) {
|
||||
|
||||
if (!$dt) {
|
||||
$dt = time();
|
||||
} elseif ($isStr) {
|
||||
$dt = strtotime($dt);
|
||||
}
|
||||
|
||||
// Return formatted date
|
||||
return $return_str ? date($heskSettings['timeformat'], $dt) : $dt;
|
||||
|
||||
}
|
||||
}
|
21
api/BusinessLogic/Emails/Addressees.php
Normal file
21
api/BusinessLogic/Emails/Addressees.php
Normal file
@ -0,0 +1,21 @@
|
||||
<?php
|
||||
|
||||
namespace BusinessLogic\Emails;
|
||||
|
||||
|
||||
class Addressees extends \BaseClass {
|
||||
/**
|
||||
* @var $to string[]
|
||||
*/
|
||||
public $to;
|
||||
|
||||
/**
|
||||
* @var $cc string[]|null
|
||||
*/
|
||||
public $cc = array();
|
||||
|
||||
/**
|
||||
* @var $bcc string[]|null
|
||||
*/
|
||||
public $bcc = array();
|
||||
}
|
84
api/BusinessLogic/Emails/BasicEmailSender.php
Normal file
84
api/BusinessLogic/Emails/BasicEmailSender.php
Normal file
@ -0,0 +1,84 @@
|
||||
<?php
|
||||
|
||||
namespace BusinessLogic\Emails;
|
||||
|
||||
|
||||
use BusinessLogic\Tickets\Attachment;
|
||||
use BusinessLogic\Tickets\Ticket;
|
||||
use PHPMailer;
|
||||
|
||||
class BasicEmailSender extends \BaseClass implements EmailSender {
|
||||
|
||||
function sendEmail($emailBuilder, $heskSettings, $modsForHeskSettings, $sendAsHtml) {
|
||||
$toEmails = implode(',', $emailBuilder->to);
|
||||
if (preg_match("/\n|\r|\t|%0A|%0D|%08|%09/", $toEmails . $emailBuilder->subject)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$mailer = new PHPMailer();
|
||||
|
||||
if ($heskSettings['smtp']) {
|
||||
$mailer->isSMTP();
|
||||
$mailer->SMTPAuth = true;
|
||||
|
||||
//-- We'll set this explicitly below if the user has it enabled.
|
||||
$mailer->SMTPAutoTLS = false;
|
||||
|
||||
if ($heskSettings['smtp_ssl']) {
|
||||
$mailer->SMTPSecure = "ssl";
|
||||
} elseif ($heskSettings['smtp_tls']) {
|
||||
$mailer->SMTPSecure = "tls";
|
||||
}
|
||||
$mailer->Host = $heskSettings['smtp_host_name'];
|
||||
$mailer->Port = $heskSettings['smtp_host_port'];
|
||||
$mailer->Username = $heskSettings['smtp_user'];
|
||||
$mailer->Password = $heskSettings['smtp_password'];
|
||||
}
|
||||
|
||||
$mailer->FromName = $heskSettings['noreply_name'] !== null &&
|
||||
$heskSettings['noreply_name'] !== '' ? $heskSettings['noreply_name'] : '';
|
||||
$mailer->From = $heskSettings['noreply_mail'];
|
||||
|
||||
if ($emailBuilder->to !== null) {
|
||||
foreach ($emailBuilder->to as $to) {
|
||||
$mailer->addAddress($to);
|
||||
}
|
||||
}
|
||||
|
||||
if ($emailBuilder->cc !== null) {
|
||||
foreach ($emailBuilder->cc as $cc) {
|
||||
$mailer->addCC($cc);
|
||||
}
|
||||
}
|
||||
|
||||
if ($emailBuilder->bcc !== null) {
|
||||
foreach ($emailBuilder->bcc as $bcc) {
|
||||
$mailer->addBCC($bcc);
|
||||
}
|
||||
}
|
||||
|
||||
$mailer->Subject = $emailBuilder->subject;
|
||||
|
||||
if ($sendAsHtml) {
|
||||
$mailer->Body = $emailBuilder->htmlMessage;
|
||||
$mailer->AltBody = $emailBuilder->message;
|
||||
} else {
|
||||
$mailer->Body = $emailBuilder->message;
|
||||
$mailer->isHTML(false);
|
||||
}
|
||||
$mailer->Timeout = $heskSettings['smtp_timeout'];
|
||||
|
||||
if ($emailBuilder->attachments !== null) {
|
||||
foreach ($emailBuilder->attachments as $attachment) {
|
||||
$mailer->addAttachment(__DIR__ . '/../../../' . $heskSettings['attach_dir'] . '/' . $attachment->savedName,
|
||||
$attachment->fileName);
|
||||
}
|
||||
}
|
||||
|
||||
if ($mailer->send()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return $mailer->ErrorInfo;
|
||||
}
|
||||
}
|
43
api/BusinessLogic/Emails/EmailBuilder.php
Normal file
43
api/BusinessLogic/Emails/EmailBuilder.php
Normal file
@ -0,0 +1,43 @@
|
||||
<?php
|
||||
|
||||
namespace BusinessLogic\Emails;
|
||||
|
||||
|
||||
use BusinessLogic\Tickets\Attachment;
|
||||
|
||||
class EmailBuilder extends \BaseClass {
|
||||
/**
|
||||
* @var $to string[]
|
||||
*/
|
||||
public $to;
|
||||
|
||||
/**
|
||||
* @var $cc string[]
|
||||
*/
|
||||
public $cc;
|
||||
|
||||
/**
|
||||
* @var $bcc string[]
|
||||
*/
|
||||
public $bcc;
|
||||
|
||||
/**
|
||||
* @var $subject string
|
||||
*/
|
||||
public $subject;
|
||||
|
||||
/**
|
||||
* @var $message string
|
||||
*/
|
||||
public $message;
|
||||
|
||||
/**
|
||||
* @var $htmlMessage string
|
||||
*/
|
||||
public $htmlMessage;
|
||||
|
||||
/**
|
||||
* @var $attachments Attachment[]
|
||||
*/
|
||||
public $attachments;
|
||||
}
|
21
api/BusinessLogic/Emails/EmailSender.php
Normal file
21
api/BusinessLogic/Emails/EmailSender.php
Normal file
@ -0,0 +1,21 @@
|
||||
<?php
|
||||
|
||||
namespace BusinessLogic\Emails;
|
||||
|
||||
|
||||
use BusinessLogic\Tickets\Attachment;
|
||||
use BusinessLogic\Tickets\Ticket;
|
||||
use PHPMailer;
|
||||
|
||||
interface EmailSender {
|
||||
/**
|
||||
* Use to send emails
|
||||
*
|
||||
* @param $emailBuilder EmailBuilder
|
||||
* @param $heskSettings array
|
||||
* @param $modsForHeskSettings array
|
||||
* @param $sendAsHtml bool
|
||||
* @return bool|string|\stdClass true if message sent successfully, string for PHPMail/Smtp error, stdClass for Mailgun error
|
||||
*/
|
||||
function sendEmail($emailBuilder, $heskSettings, $modsForHeskSettings, $sendAsHtml);
|
||||
}
|
76
api/BusinessLogic/Emails/EmailSenderHelper.php
Normal file
76
api/BusinessLogic/Emails/EmailSenderHelper.php
Normal file
@ -0,0 +1,76 @@
|
||||
<?php
|
||||
|
||||
namespace BusinessLogic\Emails;
|
||||
|
||||
|
||||
use BusinessLogic\Tickets\Ticket;
|
||||
|
||||
class EmailSenderHelper extends \BaseClass {
|
||||
/**
|
||||
* @var $emailTemplateParser EmailTemplateParser
|
||||
*/
|
||||
private $emailTemplateParser;
|
||||
|
||||
/**
|
||||
* @var $basicEmailSender BasicEmailSender
|
||||
*/
|
||||
private $basicEmailSender;
|
||||
|
||||
/**
|
||||
* @var $mailgunEmailSender MailgunEmailSender
|
||||
*/
|
||||
private $mailgunEmailSender;
|
||||
|
||||
function __construct(EmailTemplateParser $emailTemplateParser,
|
||||
BasicEmailSender $basicEmailSender,
|
||||
MailgunEmailSender $mailgunEmailSender) {
|
||||
$this->emailTemplateParser = $emailTemplateParser;
|
||||
$this->basicEmailSender = $basicEmailSender;
|
||||
$this->mailgunEmailSender = $mailgunEmailSender;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $templateId int the EmailTemplateRetriever::TEMPLATE_NAME
|
||||
* @param $language string the language name
|
||||
* @param $addressees Addressees the addressees. **cc and bcc addresses from custom fields will be added here!**
|
||||
* @param $ticket Ticket
|
||||
* @param $heskSettings array
|
||||
* @param $modsForHeskSettings array
|
||||
*/
|
||||
function sendEmailForTicket($templateId, $language, $addressees, $ticket, $heskSettings, $modsForHeskSettings) {
|
||||
$languageCode = $heskSettings['languages'][$language]['folder'];
|
||||
|
||||
$parsedTemplate = $this->emailTemplateParser->getFormattedEmailForLanguage($templateId, $languageCode,
|
||||
$ticket, $heskSettings, $modsForHeskSettings);
|
||||
|
||||
$emailBuilder = new EmailBuilder();
|
||||
$emailBuilder->subject = $parsedTemplate->subject;
|
||||
$emailBuilder->message = $parsedTemplate->message;
|
||||
$emailBuilder->htmlMessage = $parsedTemplate->htmlMessage;
|
||||
$emailBuilder->to = $addressees->to;
|
||||
$emailBuilder->cc = $addressees->cc;
|
||||
$emailBuilder->bcc = $addressees->bcc;
|
||||
|
||||
foreach ($heskSettings['custom_fields'] as $k => $v) {
|
||||
$number = intval(str_replace('custom', '', $k));
|
||||
if ($v['use'] && $v['type'] == 'email' && !empty($ticket->customFields[$number])) {
|
||||
if ($v['value']['email_type'] == 'cc') {
|
||||
$emailBuilder->cc[] = $ticket->customFields[$number];
|
||||
} elseif ($v['value']['email_type'] == 'bcc') {
|
||||
$emailBuilder->bcc[] = $ticket->customFields[$number];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ($modsForHeskSettings['attachments']) {
|
||||
$emailBuilder->attachments = $ticket->attachments;
|
||||
}
|
||||
|
||||
if ($modsForHeskSettings['use_mailgun']) {
|
||||
$this->mailgunEmailSender->sendEmail($emailBuilder, $heskSettings, $modsForHeskSettings, $modsForHeskSettings['html_emails']);
|
||||
} else {
|
||||
$this->basicEmailSender->sendEmail($emailBuilder, $heskSettings, $modsForHeskSettings, $modsForHeskSettings['html_emails']);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
27
api/BusinessLogic/Emails/EmailTemplate.php
Normal file
27
api/BusinessLogic/Emails/EmailTemplate.php
Normal file
@ -0,0 +1,27 @@
|
||||
<?php
|
||||
|
||||
namespace BusinessLogic\Emails;
|
||||
|
||||
|
||||
class EmailTemplate extends \BaseClass {
|
||||
/**
|
||||
* @var $languageKey string
|
||||
*/
|
||||
public $languageKey;
|
||||
|
||||
/**
|
||||
* @var $fileName string
|
||||
*/
|
||||
public $fileName;
|
||||
|
||||
/**
|
||||
* @var $forStaff bool
|
||||
*/
|
||||
public $forStaff;
|
||||
|
||||
function __construct($forStaff, $fileName, $languageKey = null) {
|
||||
$this->languageKey = $languageKey === null ? $fileName : $languageKey;
|
||||
$this->fileName = $fileName;
|
||||
$this->forStaff = $forStaff;
|
||||
}
|
||||
}
|
385
api/BusinessLogic/Emails/EmailTemplateParser.php
Normal file
385
api/BusinessLogic/Emails/EmailTemplateParser.php
Normal file
@ -0,0 +1,385 @@
|
||||
<?php
|
||||
|
||||
namespace BusinessLogic\Emails;
|
||||
|
||||
|
||||
use BusinessLogic\Exceptions\EmailTemplateNotFoundException;
|
||||
use BusinessLogic\Exceptions\InvalidEmailTemplateException;
|
||||
use BusinessLogic\Helpers;
|
||||
use BusinessLogic\Security\UserContext;
|
||||
use BusinessLogic\Statuses\DefaultStatusForAction;
|
||||
use BusinessLogic\Tickets\Ticket;
|
||||
use Core\Constants\Priority;
|
||||
use DataAccess\Categories\CategoryGateway;
|
||||
use DataAccess\Logging\LoggingGateway;
|
||||
use DataAccess\Security\UserGateway;
|
||||
use DataAccess\Statuses\StatusGateway;
|
||||
|
||||
class EmailTemplateParser extends \BaseClass {
|
||||
|
||||
/**
|
||||
* @var $statusGateway StatusGateway
|
||||
*/
|
||||
private $statusGateway;
|
||||
|
||||
/**
|
||||
* @var $categoryGateway CategoryGateway
|
||||
*/
|
||||
private $categoryGateway;
|
||||
|
||||
/**
|
||||
* @var $userGateway UserGateway
|
||||
*/
|
||||
private $userGateway;
|
||||
|
||||
/**
|
||||
* @var $emailTemplateRetriever EmailTemplateRetriever
|
||||
*/
|
||||
private $emailTemplateRetriever;
|
||||
|
||||
/**
|
||||
* @var $logger LoggingGateway
|
||||
*/
|
||||
private $logger;
|
||||
|
||||
function __construct(StatusGateway $statusGateway,
|
||||
CategoryGateway $categoryGateway,
|
||||
UserGateway $userGateway,
|
||||
EmailTemplateRetriever $emailTemplateRetriever,
|
||||
LoggingGateway $loggingGateway) {
|
||||
$this->statusGateway = $statusGateway;
|
||||
$this->categoryGateway = $categoryGateway;
|
||||
$this->userGateway = $userGateway;
|
||||
$this->emailTemplateRetriever = $emailTemplateRetriever;
|
||||
$this->logger = $loggingGateway;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $templateId int
|
||||
* @param $languageCode string
|
||||
* @param $ticket Ticket
|
||||
* @param $heskSettings array
|
||||
* @param $modsForHeskSettings array
|
||||
* @return ParsedEmailProperties
|
||||
* @throws InvalidEmailTemplateException
|
||||
* @throws \Exception
|
||||
*/
|
||||
function getFormattedEmailForLanguage($templateId, $languageCode, $ticket, $heskSettings, $modsForHeskSettings) {
|
||||
global $hesklang;
|
||||
|
||||
$emailTemplate = $this->emailTemplateRetriever->getTemplate($templateId);
|
||||
|
||||
if ($emailTemplate === null) {
|
||||
throw new InvalidEmailTemplateException($templateId);
|
||||
}
|
||||
|
||||
$template = self::getFromFileSystem($emailTemplate->fileName, $languageCode, false);
|
||||
$htmlTemplate = self::getFromFileSystem($emailTemplate->fileName, $languageCode, true);
|
||||
$subject = $hesklang[$emailTemplate->languageKey];
|
||||
|
||||
$fullLanguageName = null;
|
||||
foreach ($heskSettings['languages'] as $key => $value) {
|
||||
if ($value['folder'] === $languageCode) {
|
||||
$fullLanguageName = $key;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ($fullLanguageName === null) {
|
||||
throw new \BaseException("Language code {$languageCode} did not return any valid HESK languages!");
|
||||
}
|
||||
|
||||
$subject = $this->parseSubject($subject, $ticket, $fullLanguageName, $heskSettings, $modsForHeskSettings);
|
||||
$message = $this->parseMessage($template, $ticket, $fullLanguageName, $emailTemplate->forStaff, $heskSettings, $modsForHeskSettings, false);
|
||||
$htmlMessage = $this->parseMessage($htmlTemplate, $ticket, $fullLanguageName, $emailTemplate->forStaff, $heskSettings, $modsForHeskSettings, true);
|
||||
|
||||
return new ParsedEmailProperties($subject, $message, $htmlMessage);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $template string
|
||||
* @param $language string
|
||||
* @param $html bool
|
||||
* @return string The template
|
||||
* @throws EmailTemplateNotFoundException If the template was not found in the filesystem for the provided language
|
||||
*/
|
||||
private function getFromFileSystem($template, $language, $html)
|
||||
{
|
||||
$htmlFolder = $html ? 'html/' : '';
|
||||
|
||||
/* Get email template */
|
||||
$file = "language/{$language}/emails/{$htmlFolder}{$template}.txt";
|
||||
$absoluteFilePath = __DIR__ . '/../../../' . $file;
|
||||
|
||||
if (file_exists($absoluteFilePath)) {
|
||||
return file_get_contents($absoluteFilePath);
|
||||
} else {
|
||||
throw new EmailTemplateNotFoundException($template, $language);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $subjectTemplate string
|
||||
* @param $ticket Ticket
|
||||
* @param $language string
|
||||
* @param $heskSettings array
|
||||
* @return string
|
||||
* @throws \Exception if common.inc.php isn't loaded
|
||||
*/
|
||||
private function parseSubject($subjectTemplate, $ticket, $language, $heskSettings, $modsForHeskSettings) {
|
||||
global $hesklang;
|
||||
|
||||
if (!function_exists('hesk_msgToPlain')) {
|
||||
throw new \BaseException("common.inc.php not loaded!");
|
||||
}
|
||||
|
||||
if ($ticket === null) {
|
||||
return $subjectTemplate;
|
||||
}
|
||||
|
||||
// Status name and category name
|
||||
$defaultStatus = $this->statusGateway->getStatusForDefaultAction(DefaultStatusForAction::NEW_TICKET, $heskSettings);
|
||||
|
||||
if (key_exists($language, $defaultStatus->localizedNames)) {
|
||||
$statusName = $defaultStatus->localizedNames[$language];
|
||||
} elseif (key_exists('English', $defaultStatus->localizedNames)) {
|
||||
$statusName = $defaultStatus->localizedNames['English'];
|
||||
$this->logger->logWarning('EmailTemplateParser', "No localized status found for status '{$defaultStatus->id}' and language '{$language}'. Defaulted to English.", "", new UserContext(), $heskSettings);
|
||||
} else {
|
||||
$statusName = "[ERROR: No localized status found for status '{$defaultStatus->id}']";
|
||||
$this->logger->logError('EmailTemplateParser', "No localized status found for status '{$defaultStatus->id}'", "", new UserContext(), $heskSettings);
|
||||
}
|
||||
|
||||
$categories = $this->categoryGateway->getAllCategories($heskSettings, $modsForHeskSettings);
|
||||
$category = null;
|
||||
foreach ($categories as $innerCategory) {
|
||||
if ($innerCategory->id === $ticket->categoryId) {
|
||||
$category = $innerCategory;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
switch ($ticket->priorityId) {
|
||||
case Priority::CRITICAL:
|
||||
$priority = $hesklang['critical'];
|
||||
break;
|
||||
case Priority::HIGH:
|
||||
$priority = $hesklang['high'];
|
||||
break;
|
||||
case Priority::MEDIUM:
|
||||
$priority = $hesklang['medium'];
|
||||
break;
|
||||
case Priority::LOW:
|
||||
$priority = $hesklang['low'];
|
||||
break;
|
||||
default:
|
||||
$priority = 'PRIORITY NOT FOUND';
|
||||
break;
|
||||
}
|
||||
|
||||
// Special tags
|
||||
$subject = str_replace('%%SUBJECT%%', $ticket->subject, $subjectTemplate);
|
||||
$subject = str_replace('%%TRACK_ID%%', $ticket->trackingId, $subject);
|
||||
$subject = str_replace('%%CATEGORY%%', $category->id, $subject);
|
||||
$subject = str_replace('%%PRIORITY%%', $priority, $subject);
|
||||
$subject = str_replace('%%STATUS%%', $statusName, $subject);
|
||||
|
||||
return $subject;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $messageTemplate string
|
||||
* @param $ticket Ticket
|
||||
* @param $language string
|
||||
* @param $heskSettings array
|
||||
* @return string
|
||||
* @throws \Exception if common.inc.php isn't loaded
|
||||
*/
|
||||
private function parseMessage($messageTemplate, $ticket, $language, $admin, $heskSettings, $modsForHeskSettings, $html) {
|
||||
global $hesklang;
|
||||
|
||||
if (!function_exists('hesk_msgToPlain')) {
|
||||
throw new \BaseException("common.inc.php not loaded!");
|
||||
}
|
||||
|
||||
if ($ticket === null) {
|
||||
return $messageTemplate;
|
||||
}
|
||||
|
||||
$heskSettings['site_title'] = hesk_msgToPlain($heskSettings['site_title'], 1);
|
||||
|
||||
// Is email required to view ticket (for customers only)?
|
||||
$heskSettings['e_param'] = $heskSettings['email_view_ticket'] ? '&e=' . rawurlencode(implode(';', $ticket->email)) : '';
|
||||
|
||||
/* Generate the ticket URLs */
|
||||
$trackingURL = $heskSettings['hesk_url'];
|
||||
$trackingURL .= $admin ? '/' . $heskSettings['admin_dir'] . '/admin_ticket.php' : '/ticket.php';
|
||||
$trackingURL .= '?track=' . $ticket->trackingId . ($admin ? '' : $heskSettings['e_param']) . '&Refresh=' . rand(10000, 99999);
|
||||
|
||||
// Status name and category name
|
||||
$defaultStatus = $this->statusGateway->getStatusForDefaultAction(DefaultStatusForAction::NEW_TICKET, $heskSettings);
|
||||
$statusName = hesk_msgToPlain($defaultStatus->localizedNames[$language]);
|
||||
|
||||
$categories = $this->categoryGateway->getAllCategories($heskSettings, $modsForHeskSettings);
|
||||
$category = null;
|
||||
foreach ($categories as $innerCategory) {
|
||||
if ($innerCategory->id === $ticket->categoryId) {
|
||||
$category = $innerCategory;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
$category = hesk_msgToPlain($category->name);
|
||||
$owner = $this->userGateway->getUserById($ticket->ownerId, $heskSettings);
|
||||
|
||||
$ownerName = $owner === null ? $hesklang['unas'] : hesk_msgToPlain($owner->name);
|
||||
|
||||
switch ($ticket->priorityId) {
|
||||
case Priority::CRITICAL:
|
||||
$priority = $hesklang['critical'];
|
||||
break;
|
||||
case Priority::HIGH:
|
||||
$priority = $hesklang['high'];
|
||||
break;
|
||||
case Priority::MEDIUM:
|
||||
$priority = $hesklang['medium'];
|
||||
break;
|
||||
case Priority::LOW:
|
||||
$priority = $hesklang['low'];
|
||||
break;
|
||||
default:
|
||||
$priority = 'PRIORITY NOT FOUND';
|
||||
break;
|
||||
}
|
||||
|
||||
// Special tags
|
||||
$msg = str_replace('%%NAME%%', $ticket->name, $messageTemplate);
|
||||
$msg = str_replace('%%SUBJECT%%', $ticket->subject, $msg);
|
||||
$msg = str_replace('%%TRACK_ID%%', $ticket->trackingId, $msg);
|
||||
$msg = str_replace('%%TRACK_URL%%', $trackingURL, $msg);
|
||||
$msg = str_replace('%%SITE_TITLE%%', $heskSettings['site_title'], $msg);
|
||||
$msg = str_replace('%%SITE_URL%%', $heskSettings['site_url'], $msg);
|
||||
$msg = str_replace('%%FIRST_NAME%%', Helpers::fullNameToFirstName($ticket->name), $msg);
|
||||
$msg = str_replace('%%CATEGORY%%', $category, $msg);
|
||||
$msg = str_replace('%%PRIORITY%%', $priority, $msg);
|
||||
$msg = str_replace('%%OWNER%%', $ownerName, $msg);
|
||||
$msg = str_replace('%%STATUS%%', $statusName, $msg);
|
||||
$msg = str_replace('%%EMAIL%%', implode(';', $ticket->email), $msg);
|
||||
$msg = str_replace('%%CREATED%%', $ticket->dateCreated, $msg);
|
||||
$msg = str_replace('%%UPDATED%%', $ticket->lastChanged, $msg);
|
||||
$msg = str_replace('%%ID%%', $ticket->id, $msg);
|
||||
$msg = str_replace('%%TIME_WORKED%%', $ticket->timeWorked, $msg);
|
||||
|
||||
$lastReplyBy = '';
|
||||
// Get the last reply by
|
||||
if (!empty($ticket->lastReplier)) {
|
||||
$lastReplyBy = $ticket->lastReplier;
|
||||
} else {
|
||||
$lastReplyBy = $ticket->name;
|
||||
}
|
||||
|
||||
$msg = str_replace('%%LAST_REPLY_BY%%', $lastReplyBy, $msg);
|
||||
|
||||
/* All custom fields */
|
||||
for ($i=1; $i<=50; $i++) {
|
||||
$k = 'custom'.$i;
|
||||
|
||||
if (isset($heskSettings['custom_fields'][$k]) && isset($ticket->customFields[$i])) {
|
||||
$v = $heskSettings['custom_fields'][$k];
|
||||
|
||||
switch ($v['type']) {
|
||||
case 'checkbox':
|
||||
$ticket->customFields[$i] = str_replace("<br>","\n",$ticket->customFields[$i]);
|
||||
break;
|
||||
case 'date':
|
||||
$ticket->customFields[$i] = hesk_custom_date_display_format($ticket->customFields[$i], $v['value']['date_format']);
|
||||
break;
|
||||
}
|
||||
|
||||
$msg = str_replace('%%'.strtoupper($k).'%%',stripslashes($ticket->customFields[$i]),$msg);
|
||||
} else {
|
||||
$msg = str_replace('%%'.strtoupper($k).'%%','',$msg);
|
||||
}
|
||||
}
|
||||
|
||||
// Is message tag in email template?
|
||||
if (strpos($msg, '%%MESSAGE%%') !== false) {
|
||||
// Replace message
|
||||
if ($html) {
|
||||
$htmlMessage = html_entity_decode($ticket->message);
|
||||
$htmlMessage = nl2br($htmlMessage);
|
||||
$msg = str_replace('%%MESSAGE%%', $htmlMessage, $msg);
|
||||
} else {
|
||||
$plainTextMessage = $ticket->message;
|
||||
|
||||
$messageHtml = $ticket->usesHtml;
|
||||
|
||||
if (count($ticket->replies) > 0) {
|
||||
$lastReply = end($ticket->replies);
|
||||
$messageHtml = $lastReply->usesHtml;
|
||||
}
|
||||
|
||||
if ($messageHtml) {
|
||||
if (!function_exists('convert_html_to_text')) {
|
||||
require(__DIR__ . '/../../../inc/html2text/html2text.php');
|
||||
}
|
||||
$plainTextMessage = convert_html_to_text($plainTextMessage);
|
||||
$plainTextMessage = fix_newlines($plainTextMessage);
|
||||
}
|
||||
$msg = str_replace('%%MESSAGE%%', $plainTextMessage, $msg);
|
||||
}
|
||||
|
||||
// Add direct links to any attachments at the bottom of the email message
|
||||
if ($heskSettings['attachments']['use'] && isset($ticket->attachments) && count($ticket->attachments) > 0) {
|
||||
if (!$modsForHeskSettings['attachments']) {
|
||||
if ($html) {
|
||||
$msg .= "<br><br><br>" . $hesklang['fatt'];
|
||||
} else {
|
||||
$msg .= "\n\n\n" . $hesklang['fatt'];
|
||||
}
|
||||
|
||||
foreach ($ticket->attachments as $attachment) {
|
||||
if ($html) {
|
||||
$msg .= "<br><br>{$attachment->fileName}<br>";
|
||||
} else {
|
||||
$msg .= "\n\n{$attachment->fileName}\n";
|
||||
}
|
||||
|
||||
$msg .= "{$heskSettings['hesk_url']}/download_attachment.php?att_id={$attachment->id}&track={$ticket->trackingId}{$heskSettings['e_param']}";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// For customer notifications: if we allow email piping/pop 3 fetching and
|
||||
// stripping quoted replies add an "reply above this line" tag
|
||||
if (!$admin && ($heskSettings['email_piping'] || $heskSettings['pop3']) && $heskSettings['strip_quoted']) {
|
||||
$msg = $hesklang['EMAIL_HR'] . "\n\n" . $msg;
|
||||
}
|
||||
} elseif (strpos($msg, '%%MESSAGE_NO_ATTACHMENTS%%') !== false) {
|
||||
if ($html) {
|
||||
$htmlMessage = nl2br($ticket->message);
|
||||
$msg = str_replace('%%MESSAGE_NO_ATTACHMENTS%%', $htmlMessage, $msg);
|
||||
} else {
|
||||
$plainTextMessage = $ticket->message;
|
||||
|
||||
$messageHtml = $ticket->usesHtml;
|
||||
|
||||
if (count($ticket->replies) > 0) {
|
||||
$lastReply = end($ticket->replies);
|
||||
$messageHtml = $lastReply->usesHtml;
|
||||
}
|
||||
|
||||
if ($messageHtml) {
|
||||
if (!function_exists('convert_html_to_text')) {
|
||||
require(__DIR__ . '/../../../inc/html2text/html2text.php');
|
||||
}
|
||||
$plainTextMessage = convert_html_to_text($plainTextMessage);
|
||||
$plainTextMessage = fix_newlines($plainTextMessage);
|
||||
}
|
||||
$msg = str_replace('%%MESSAGE_NO_ATTACHMENTS%%', $plainTextMessage, $msg);
|
||||
}
|
||||
}
|
||||
|
||||
return $msg;
|
||||
}
|
||||
}
|
65
api/BusinessLogic/Emails/EmailTemplateRetriever.php
Normal file
65
api/BusinessLogic/Emails/EmailTemplateRetriever.php
Normal file
@ -0,0 +1,65 @@
|
||||
<?php
|
||||
|
||||
namespace BusinessLogic\Emails;
|
||||
|
||||
|
||||
class EmailTemplateRetriever extends \BaseClass {
|
||||
/**
|
||||
* @var $validTemplates EmailTemplate[]
|
||||
*/
|
||||
private $validTemplates;
|
||||
|
||||
function __construct() {
|
||||
$this->validTemplates = array();
|
||||
$this->initializeArray();
|
||||
}
|
||||
|
||||
const FORGOT_TICKET_ID = 0;
|
||||
const NEW_REPLY_BY_STAFF = 1;
|
||||
const NEW_TICKET = 2;
|
||||
const VERIFY_EMAIL = 3;
|
||||
const TICKET_CLOSED = 4;
|
||||
const CATEGORY_MOVED = 5;
|
||||
const NEW_REPLY_BY_CUSTOMER = 6;
|
||||
const NEW_TICKET_STAFF = 7;
|
||||
const TICKET_ASSIGNED_TO_YOU = 8;
|
||||
const NEW_PM = 9;
|
||||
const NEW_NOTE = 10;
|
||||
const RESET_PASSWORD = 11;
|
||||
const CALENDAR_REMINDER = 12;
|
||||
const OVERDUE_TICKET = 13;
|
||||
|
||||
function initializeArray() {
|
||||
if (count($this->validTemplates) > 0) {
|
||||
//-- Map already built
|
||||
return;
|
||||
}
|
||||
|
||||
$this->validTemplates[self::FORGOT_TICKET_ID] = new EmailTemplate(false, 'forgot_ticket_id');
|
||||
$this->validTemplates[self::NEW_REPLY_BY_STAFF] = new EmailTemplate(false, 'new_reply_by_staff');
|
||||
$this->validTemplates[self::NEW_TICKET] = new EmailTemplate(false, 'new_ticket', 'ticket_received');
|
||||
$this->validTemplates[self::VERIFY_EMAIL] = new EmailTemplate(false, 'verify_email');
|
||||
$this->validTemplates[self::TICKET_CLOSED] = new EmailTemplate(false, 'ticket_closed');
|
||||
$this->validTemplates[self::CATEGORY_MOVED] = new EmailTemplate(true, 'category_moved');
|
||||
$this->validTemplates[self::NEW_REPLY_BY_CUSTOMER] = new EmailTemplate(true, 'new_reply_by_customer');
|
||||
$this->validTemplates[self::NEW_TICKET_STAFF] = new EmailTemplate(true, 'new_ticket_staff');
|
||||
$this->validTemplates[self::TICKET_ASSIGNED_TO_YOU] = new EmailTemplate(true, 'ticket_assigned_to_you');
|
||||
$this->validTemplates[self::NEW_PM] = new EmailTemplate(true, 'new_pm');
|
||||
$this->validTemplates[self::NEW_NOTE] = new EmailTemplate(true, 'new_note');
|
||||
$this->validTemplates[self::RESET_PASSWORD] = new EmailTemplate(true, 'reset_password');
|
||||
$this->validTemplates[self::CALENDAR_REMINDER] = new EmailTemplate(true, 'reset_password');
|
||||
$this->validTemplates[self::OVERDUE_TICKET] = new EmailTemplate(true, 'overdue_ticket');
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $templateId
|
||||
* @return EmailTemplate|null
|
||||
*/
|
||||
function getTemplate($templateId) {
|
||||
if (isset($this->validTemplates[$templateId])) {
|
||||
return $this->validTemplates[$templateId];
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
73
api/BusinessLogic/Emails/MailgunEmailSender.php
Normal file
73
api/BusinessLogic/Emails/MailgunEmailSender.php
Normal file
@ -0,0 +1,73 @@
|
||||
<?php
|
||||
|
||||
namespace BusinessLogic\Emails;
|
||||
|
||||
|
||||
use BusinessLogic\Tickets\Attachment;
|
||||
use BusinessLogic\Tickets\Ticket;
|
||||
use Mailgun\Mailgun;
|
||||
|
||||
class MailgunEmailSender extends \BaseClass implements EmailSender {
|
||||
function sendEmail($emailBuilder, $heskSettings, $modsForHeskSettings, $sendAsHtml) {
|
||||
$mailgunArray = array();
|
||||
|
||||
$mailgunArray['from'] = $heskSettings['noreply_mail']; // Email Address
|
||||
if ($heskSettings['noreply_name'] !== null && $heskSettings['noreply_name'] !== '') {
|
||||
$mailgunArray['from'] = "{$heskSettings['noreply_name']} <{$heskSettings['noreply_mail']}>"; // Name and address
|
||||
}
|
||||
|
||||
$mailgunArray['to'] = implode(',', $emailBuilder->to);
|
||||
|
||||
if ($emailBuilder->cc !== null && count($emailBuilder->cc) > 0) {
|
||||
$mailgunArray['cc'] = implode(',', $emailBuilder->cc);
|
||||
}
|
||||
|
||||
if ($emailBuilder->bcc !== null && count($emailBuilder->bcc) > 0) {
|
||||
$mailgunArray['bcc'] = implode(',', $emailBuilder->bcc);
|
||||
}
|
||||
|
||||
$mailgunArray['subject'] = $emailBuilder->subject;
|
||||
$mailgunArray['text'] = $emailBuilder->message;
|
||||
|
||||
if ($sendAsHtml) {
|
||||
$mailgunArray['html'] = $emailBuilder->htmlMessage;
|
||||
}
|
||||
|
||||
$mailgunAttachments = array();
|
||||
if ($emailBuilder->attachments !== null) {
|
||||
foreach ($emailBuilder->attachments as $attachment) {
|
||||
$mailgunAttachments[] = array(
|
||||
'remoteName' => $attachment->fileName,
|
||||
'filePath' => __DIR__ . '/../../../' . $heskSettings['attach_dir'] . '/' . $attachment->savedName
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
$result = $this->sendMessage($mailgunArray, $mailgunAttachments, $modsForHeskSettings);
|
||||
|
||||
|
||||
if (isset($result->http_response_code)
|
||||
&& $result->http_response_code === 200) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
private function sendMessage($mailgunArray, $attachments, $modsForHeskSettings) {
|
||||
$ssl = !defined('NO_MAILGUN_SSL');
|
||||
|
||||
$messageClient = new Mailgun($modsForHeskSettings['mailgun_api_key'], 'api.mailgun.net', 'v2', $ssl);
|
||||
|
||||
$mailgunAttachments = array();
|
||||
if (count($attachments) > 0) {
|
||||
$mailgunAttachments = array(
|
||||
'attachment' => $attachments
|
||||
);
|
||||
}
|
||||
|
||||
$result = $messageClient->sendMessage($modsForHeskSettings['mailgun_domain'], $mailgunArray, $mailgunAttachments);
|
||||
|
||||
return $result;
|
||||
}
|
||||
}
|
27
api/BusinessLogic/Emails/ParsedEmailProperties.php
Normal file
27
api/BusinessLogic/Emails/ParsedEmailProperties.php
Normal file
@ -0,0 +1,27 @@
|
||||
<?php
|
||||
|
||||
namespace BusinessLogic\Emails;
|
||||
|
||||
|
||||
class ParsedEmailProperties extends \BaseClass {
|
||||
function __construct($subject, $message, $htmlMessage) {
|
||||
$this->subject = $subject;
|
||||
$this->message = $message;
|
||||
$this->htmlMessage = $htmlMessage;
|
||||
}
|
||||
|
||||
/**
|
||||
* @var $subject string
|
||||
*/
|
||||
public $subject;
|
||||
|
||||
/**
|
||||
* @var $message string
|
||||
*/
|
||||
public $message;
|
||||
|
||||
/**
|
||||
* @var $htmlMessage string
|
||||
*/
|
||||
public $htmlMessage;
|
||||
}
|
10
api/BusinessLogic/Exceptions/AccessViolationException.php
Normal file
10
api/BusinessLogic/Exceptions/AccessViolationException.php
Normal file
@ -0,0 +1,10 @@
|
||||
<?php
|
||||
|
||||
namespace BusinessLogic\Exceptions;
|
||||
|
||||
|
||||
class AccessViolationException extends ApiFriendlyException {
|
||||
function __construct($message) {
|
||||
parent::__construct($message, 'Access Exception', 403);
|
||||
}
|
||||
}
|
25
api/BusinessLogic/Exceptions/ApiFriendlyException.php
Normal file
25
api/BusinessLogic/Exceptions/ApiFriendlyException.php
Normal file
@ -0,0 +1,25 @@
|
||||
<?php
|
||||
|
||||
namespace BusinessLogic\Exceptions;
|
||||
|
||||
|
||||
use Exception;
|
||||
|
||||
class ApiFriendlyException extends \BaseException {
|
||||
public $title;
|
||||
public $httpResponseCode;
|
||||
|
||||
/**
|
||||
* ApiFriendlyException constructor.
|
||||
* @param string $message
|
||||
* @param string $title
|
||||
* @param int $httpResponseCode
|
||||
*/
|
||||
function __construct($message, $title, $httpResponseCode) {
|
||||
$this->title = $title;
|
||||
$this->httpResponseCode = $httpResponseCode;
|
||||
|
||||
parent::__construct($message);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,17 @@
|
||||
<?php
|
||||
/**
|
||||
* Created by PhpStorm.
|
||||
* User: mkoch
|
||||
* Date: 2/22/2017
|
||||
* Time: 10:00 PM
|
||||
*/
|
||||
|
||||
namespace BusinessLogic\Exceptions;
|
||||
|
||||
|
||||
class EmailTemplateNotFoundException extends ApiFriendlyException {
|
||||
function __construct($emailTemplate, $language) {
|
||||
parent::__construct(sprintf("The email template '%s' was not found for the language '%s'", $emailTemplate, $language),
|
||||
'Email Template Not Found!', 400);
|
||||
}
|
||||
}
|
10
api/BusinessLogic/Exceptions/InternalUseOnlyException.php
Normal file
10
api/BusinessLogic/Exceptions/InternalUseOnlyException.php
Normal file
@ -0,0 +1,10 @@
|
||||
<?php
|
||||
|
||||
namespace BusinessLogic\Exceptions;
|
||||
|
||||
|
||||
class InternalUseOnlyException extends ApiFriendlyException {
|
||||
function __construct() {
|
||||
parent::__construct("This endpoint can only be used internally", "Internal Use Only", 401);
|
||||
}
|
||||
}
|
@ -0,0 +1,12 @@
|
||||
<?php
|
||||
|
||||
namespace BusinessLogic\Exceptions;
|
||||
|
||||
|
||||
class InvalidAuthenticationTokenException extends ApiFriendlyException {
|
||||
public function __construct() {
|
||||
parent::__construct('The X-Auth-Token is invalid. The token must be for an active helpdesk user.',
|
||||
'Security Exception',
|
||||
401);
|
||||
}
|
||||
}
|
@ -0,0 +1,16 @@
|
||||
<?php
|
||||
/**
|
||||
* Created by PhpStorm.
|
||||
* User: mkoch
|
||||
* Date: 2/23/2017
|
||||
* Time: 8:13 PM
|
||||
*/
|
||||
|
||||
namespace BusinessLogic\Exceptions;
|
||||
|
||||
|
||||
class InvalidEmailTemplateException extends ApiFriendlyException {
|
||||
function __construct($template) {
|
||||
parent::__construct(sprintf("The email template '%s' is invalid", $template), 'Invalid Email Template', 400);
|
||||
}
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
<?php
|
||||
|
||||
namespace BusinessLogic\Exceptions;
|
||||
|
||||
class MissingAuthenticationTokenException extends ApiFriendlyException {
|
||||
function __construct() {
|
||||
parent::__construct("An 'X-Auth-Token' is required for this request",
|
||||
'Security Exception',
|
||||
401);
|
||||
}
|
||||
}
|
16
api/BusinessLogic/Exceptions/SessionNotActiveException.php
Normal file
16
api/BusinessLogic/Exceptions/SessionNotActiveException.php
Normal file
@ -0,0 +1,16 @@
|
||||
<?php
|
||||
/**
|
||||
* Created by PhpStorm.
|
||||
* User: cokoch
|
||||
* Date: 5/2/2017
|
||||
* Time: 12:28 PM
|
||||
*/
|
||||
|
||||
namespace BusinessLogic\Exceptions;
|
||||
|
||||
|
||||
class SessionNotActiveException extends ApiFriendlyException {
|
||||
function __construct() {
|
||||
parent::__construct("You must be logged in to call internal API methods", "Authentication Required", 401);
|
||||
}
|
||||
}
|
21
api/BusinessLogic/Exceptions/ValidationException.php
Normal file
21
api/BusinessLogic/Exceptions/ValidationException.php
Normal file
@ -0,0 +1,21 @@
|
||||
<?php
|
||||
|
||||
namespace BusinessLogic\Exceptions;
|
||||
|
||||
use BusinessLogic\ValidationModel;
|
||||
use Exception;
|
||||
|
||||
class ValidationException extends ApiFriendlyException {
|
||||
/**
|
||||
* ValidationException constructor.
|
||||
* @param ValidationModel $validationModel The validation model
|
||||
* @throws Exception If the validationModel's errorKeys is empty
|
||||
*/
|
||||
function __construct($validationModel) {
|
||||
if (count($validationModel->errorKeys) === 0) {
|
||||
throw new Exception('Tried to throw a ValidationException, but the validation model was valid or had 0 error keys!');
|
||||
}
|
||||
|
||||
parent::__construct(implode(",", $validationModel->errorKeys), "Validation Failed. Error keys are available in the message section.", 400);
|
||||
}
|
||||
}
|
244
api/BusinessLogic/Helpers.php
Normal file
244
api/BusinessLogic/Helpers.php
Normal file
@ -0,0 +1,244 @@
|
||||
<?php
|
||||
|
||||
namespace BusinessLogic;
|
||||
|
||||
|
||||
class Helpers extends \BaseClass {
|
||||
static function getHeader($key) {
|
||||
$headers = getallheaders();
|
||||
|
||||
$uppercaseHeaders = array();
|
||||
foreach ($headers as $header => $value) {
|
||||
$uppercaseHeaders[strtoupper($header)] = $value;
|
||||
}
|
||||
|
||||
return isset($uppercaseHeaders[$key])
|
||||
? $uppercaseHeaders[$key]
|
||||
: NULL;
|
||||
}
|
||||
|
||||
static function hashToken($token) {
|
||||
return hash('sha512', $token);
|
||||
}
|
||||
|
||||
static function safeArrayGet($array, $key) {
|
||||
return $array !== null && array_key_exists($key, $array)
|
||||
? $array[$key]
|
||||
: null;
|
||||
}
|
||||
|
||||
static function boolval($val) {
|
||||
return $val == true;
|
||||
}
|
||||
|
||||
static function heskHtmlSpecialCharsDecode($in) {
|
||||
return str_replace(array('&', '<', '>', '"'), array('&', '<', '>', '"'), $in);
|
||||
}
|
||||
|
||||
static function heskMakeUrl($text, $class = '', $shortenLinks = true) {
|
||||
if (!defined('MAGIC_URL_EMAIL')) {
|
||||
define('MAGIC_URL_EMAIL', 1);
|
||||
define('MAGIC_URL_FULL', 2);
|
||||
define('MAGIC_URL_LOCAL', 3);
|
||||
define('MAGIC_URL_WWW', 4);
|
||||
}
|
||||
|
||||
$class = ($class) ? ' class="' . $class . '"' : '';
|
||||
|
||||
// matches a xxxx://aaaaa.bbb.cccc. ...
|
||||
$text = preg_replace_callback(
|
||||
'#(^|[\n\t (>.])(' . "[a-z][a-z\d+]*:/{2}(?:(?:[^\p{C}\p{Z}\p{S}\p{P}\p{Nl}\p{No}\p{Me}\x{1100}-\x{115F}\x{A960}-\x{A97C}\x{1160}-\x{11A7}\x{D7B0}-\x{D7C6}\x{20D0}-\x{20FF}\x{1D100}-\x{1D1FF}\x{1D200}-\x{1D24F}\x{0640}\x{07FA}\x{302E}\x{302F}\x{3031}-\x{3035}\x{303B}]*[\x{00B7}\x{0375}\x{05F3}\x{05F4}\x{30FB}\x{002D}\x{06FD}\x{06FE}\x{0F0B}\x{3007}\x{00DF}\x{03C2}\x{200C}\x{200D}\pL0-9\-._~!$&'(*+,;=:@|]+|%[\dA-F]{2})+|[0-9.]+|\[[a-z0-9.]+:[a-z0-9.]+:[a-z0-9.:]+\])(?::\d*)?(?:/(?:[^\p{C}\p{Z}\p{S}\p{P}\p{Nl}\p{No}\p{Me}\x{1100}-\x{115F}\x{A960}-\x{A97C}\x{1160}-\x{11A7}\x{D7B0}-\x{D7C6}\x{20D0}-\x{20FF}\x{1D100}-\x{1D1FF}\x{1D200}-\x{1D24F}\x{0640}\x{07FA}\x{302E}\x{302F}\x{3031}-\x{3035}\x{303B}]*[\x{00B7}\x{0375}\x{05F3}\x{05F4}\x{30FB}\x{002D}\x{06FD}\x{06FE}\x{0F0B}\x{3007}\x{00DF}\x{03C2}\x{200C}\x{200D}\pL0-9\-._~!$&'(*+,;=:@|]+|%[\dA-F]{2})*)*(?:\?(?:[^\p{C}\p{Z}\p{S}\p{P}\p{Nl}\p{No}\p{Me}\x{1100}-\x{115F}\x{A960}-\x{A97C}\x{1160}-\x{11A7}\x{D7B0}-\x{D7C6}\x{20D0}-\x{20FF}\x{1D100}-\x{1D1FF}\x{1D200}-\x{1D24F}\x{0640}\x{07FA}\x{302E}\x{302F}\x{3031}-\x{3035}\x{303B}]*[\x{00B7}\x{0375}\x{05F3}\x{05F4}\x{30FB}\x{002D}\x{06FD}\x{06FE}\x{0F0B}\x{3007}\x{00DF}\x{03C2}\x{200C}\x{200D}\pL0-9\-._~!$&'(*+,;=:@/?|]+|%[\dA-F]{2})*)?(?:\#(?:[^\p{C}\p{Z}\p{S}\p{P}\p{Nl}\p{No}\p{Me}\x{1100}-\x{115F}\x{A960}-\x{A97C}\x{1160}-\x{11A7}\x{D7B0}-\x{D7C6}\x{20D0}-\x{20FF}\x{1D100}-\x{1D1FF}\x{1D200}-\x{1D24F}\x{0640}\x{07FA}\x{302E}\x{302F}\x{3031}-\x{3035}\x{303B}]*[\x{00B7}\x{0375}\x{05F3}\x{05F4}\x{30FB}\x{002D}\x{06FD}\x{06FE}\x{0F0B}\x{3007}\x{00DF}\x{03C2}\x{200C}\x{200D}\pL0-9\-._~!$&'(*+,;=:@/?|]+|%[\dA-F]{2})*)?" . ')#iu',
|
||||
function($matches) use ($class, $shortenLinks) {
|
||||
return self::makeClickableCallback(MAGIC_URL_FULL, $matches[1], $matches[2], '', $class, $shortenLinks);
|
||||
},
|
||||
$text
|
||||
);
|
||||
|
||||
// matches a "www.xxxx.yyyy[/zzzz]" kinda lazy URL thing
|
||||
$text = preg_replace_callback(
|
||||
'#(^|[\n\t (>])(' . "www\.(?:[^\p{C}\p{Z}\p{S}\p{P}\p{Nl}\p{No}\p{Me}\x{1100}-\x{115F}\x{A960}-\x{A97C}\x{1160}-\x{11A7}\x{D7B0}-\x{D7C6}\x{20D0}-\x{20FF}\x{1D100}-\x{1D1FF}\x{1D200}-\x{1D24F}\x{0640}\x{07FA}\x{302E}\x{302F}\x{3031}-\x{3035}\x{303B}]*[\x{00B7}\x{0375}\x{05F3}\x{05F4}\x{30FB}\x{002D}\x{06FD}\x{06FE}\x{0F0B}\x{3007}\x{00DF}\x{03C2}\x{200C}\x{200D}\pL0-9\-._~!$&'(*+,;=:@|]+|%[\dA-F]{2})+(?::\d*)?(?:/(?:[^\p{C}\p{Z}\p{S}\p{P}\p{Nl}\p{No}\p{Me}\x{1100}-\x{115F}\x{A960}-\x{A97C}\x{1160}-\x{11A7}\x{D7B0}-\x{D7C6}\x{20D0}-\x{20FF}\x{1D100}-\x{1D1FF}\x{1D200}-\x{1D24F}\x{0640}\x{07FA}\x{302E}\x{302F}\x{3031}-\x{3035}\x{303B}]*[\x{00B7}\x{0375}\x{05F3}\x{05F4}\x{30FB}\x{002D}\x{06FD}\x{06FE}\x{0F0B}\x{3007}\x{00DF}\x{03C2}\x{200C}\x{200D}\pL0-9\-._~!$&'(*+,;=:@|]+|%[\dA-F]{2})*)*(?:\?(?:[^\p{C}\p{Z}\p{S}\p{P}\p{Nl}\p{No}\p{Me}\x{1100}-\x{115F}\x{A960}-\x{A97C}\x{1160}-\x{11A7}\x{D7B0}-\x{D7C6}\x{20D0}-\x{20FF}\x{1D100}-\x{1D1FF}\x{1D200}-\x{1D24F}\x{0640}\x{07FA}\x{302E}\x{302F}\x{3031}-\x{3035}\x{303B}]*[\x{00B7}\x{0375}\x{05F3}\x{05F4}\x{30FB}\x{002D}\x{06FD}\x{06FE}\x{0F0B}\x{3007}\x{00DF}\x{03C2}\x{200C}\x{200D}\pL0-9\-._~!$&'(*+,;=:@/?|]+|%[\dA-F]{2})*)?(?:\#(?:[^\p{C}\p{Z}\p{S}\p{P}\p{Nl}\p{No}\p{Me}\x{1100}-\x{115F}\x{A960}-\x{A97C}\x{1160}-\x{11A7}\x{D7B0}-\x{D7C6}\x{20D0}-\x{20FF}\x{1D100}-\x{1D1FF}\x{1D200}-\x{1D24F}\x{0640}\x{07FA}\x{302E}\x{302F}\x{3031}-\x{3035}\x{303B}]*[\x{00B7}\x{0375}\x{05F3}\x{05F4}\x{30FB}\x{002D}\x{06FD}\x{06FE}\x{0F0B}\x{3007}\x{00DF}\x{03C2}\x{200C}\x{200D}\pL0-9\-._~!$&'(*+,;=:@/?|]+|%[\dA-F]{2})*)?" . ')#iu',
|
||||
function($matches) use ($class, $shortenLinks) {
|
||||
return self::makeClickableCallback(MAGIC_URL_WWW, $matches[1], $matches[2], '', $class, $shortenLinks);
|
||||
},
|
||||
$text
|
||||
);
|
||||
|
||||
// matches an email address
|
||||
$text = preg_replace_callback(
|
||||
'/(^|[\n\t (>])(' . '((?:[\w\!\#$\%\&\'\*\+\-\/\=\?\^\`{\|\}\~]+\.)*(?:[\w\!\#$\%\'\*\+\-\/\=\?\^\`{\|\}\~]|&)+)@((((([a-z0-9]{1}[a-z0-9\-]{0,62}[a-z0-9]{1})|[a-z])\.)+[a-z]{2,63})|(\d{1,3}\.){3}\d{1,3}(\:\d{1,5})?)' . ')/iu',
|
||||
function($matches) use ($class, $shortenLinks) {
|
||||
return self::makeClickableCallback(MAGIC_URL_EMAIL, $matches[1], $matches[2], '', $class, $shortenLinks);
|
||||
},
|
||||
$text
|
||||
);
|
||||
|
||||
return $text;
|
||||
}
|
||||
|
||||
static function makeClickableCallback($type, $whitespace, $url, $relative_url, $class, $shortenLinks)
|
||||
{
|
||||
global $hesk_settings;
|
||||
|
||||
$orig_url = $url;
|
||||
$orig_relative = $relative_url;
|
||||
$append = '';
|
||||
$url = htmlspecialchars_decode($url);
|
||||
$relative_url = htmlspecialchars_decode($relative_url);
|
||||
|
||||
// make sure no HTML entities were matched
|
||||
$chars = array('<', '>', '"');
|
||||
$split = false;
|
||||
|
||||
foreach ($chars as $char) {
|
||||
$next_split = strpos($url, $char);
|
||||
if ($next_split !== false) {
|
||||
$split = ($split !== false) ? min($split, $next_split) : $next_split;
|
||||
}
|
||||
}
|
||||
|
||||
if ($split !== false) {
|
||||
// an HTML entity was found, so the URL has to end before it
|
||||
$append = substr($url, $split) . $relative_url;
|
||||
$url = substr($url, 0, $split);
|
||||
$relative_url = '';
|
||||
} else if ($relative_url) {
|
||||
// same for $relative_url
|
||||
$split = false;
|
||||
foreach ($chars as $char) {
|
||||
$next_split = strpos($relative_url, $char);
|
||||
if ($next_split !== false) {
|
||||
$split = ($split !== false) ? min($split, $next_split) : $next_split;
|
||||
}
|
||||
}
|
||||
|
||||
if ($split !== false) {
|
||||
$append = substr($relative_url, $split);
|
||||
$relative_url = substr($relative_url, 0, $split);
|
||||
}
|
||||
}
|
||||
|
||||
// if the last character of the url is a punctuation mark, exclude it from the url
|
||||
$last_char = ($relative_url) ? $relative_url[strlen($relative_url) - 1] : $url[strlen($url) - 1];
|
||||
|
||||
switch ($last_char) {
|
||||
case '.':
|
||||
case '?':
|
||||
case '!':
|
||||
case ':':
|
||||
case ',':
|
||||
$append = $last_char;
|
||||
if ($relative_url) {
|
||||
$relative_url = substr($relative_url, 0, -1);
|
||||
} else {
|
||||
$url = substr($url, 0, -1);
|
||||
}
|
||||
break;
|
||||
|
||||
// set last_char to empty here, so the variable can be used later to
|
||||
// check whether a character was removed
|
||||
default:
|
||||
$last_char = '';
|
||||
break;
|
||||
}
|
||||
|
||||
$short_url = ($hesk_settings['short_link'] && strlen($url) > 70 && $shortenLinks) ? substr($url, 0, 54) . ' ... ' . substr($url, -10) : $url;
|
||||
|
||||
switch ($type) {
|
||||
case MAGIC_URL_LOCAL:
|
||||
$tag = 'l';
|
||||
$relative_url = preg_replace('/[&?]sid=[0-9a-f]{32}$/', '', preg_replace('/([&?])sid=[0-9a-f]{32}&/', '$1', $relative_url));
|
||||
$url = $url . '/' . $relative_url;
|
||||
$text = $relative_url;
|
||||
|
||||
// this url goes to http://domain.tld/path/to/board/ which
|
||||
// would result in an empty link if treated as local so
|
||||
// don't touch it and let MAGIC_URL_FULL take care of it.
|
||||
if (!$relative_url) {
|
||||
return $whitespace . $orig_url . '/' . $orig_relative; // slash is taken away by relative url pattern
|
||||
}
|
||||
break;
|
||||
|
||||
case MAGIC_URL_FULL:
|
||||
$tag = 'm';
|
||||
$text = $short_url;
|
||||
break;
|
||||
|
||||
case MAGIC_URL_WWW:
|
||||
$tag = 'w';
|
||||
$url = 'http://' . $url;
|
||||
$text = $short_url;
|
||||
break;
|
||||
|
||||
case MAGIC_URL_EMAIL:
|
||||
$tag = 'e';
|
||||
$text = $short_url;
|
||||
$url = 'mailto:' . $url;
|
||||
break;
|
||||
}
|
||||
|
||||
$url = htmlspecialchars($url);
|
||||
$text = htmlspecialchars($text);
|
||||
$append = htmlspecialchars($append);
|
||||
|
||||
$html = "$whitespace<a href=\"$url\" target=\"blank\" $class>$text</a>$append";
|
||||
|
||||
return $html;
|
||||
} // END make_clickable_callback()
|
||||
|
||||
static function fullNameToFirstName($full_name) {
|
||||
$name_parts = explode(' ', $full_name);
|
||||
|
||||
// Only one part, return back the original
|
||||
if (count($name_parts) < 2){
|
||||
return $full_name;
|
||||
}
|
||||
|
||||
$first_name = self::heskMbStrToLower($name_parts[0]);
|
||||
|
||||
// Name prefixes without dots
|
||||
$prefixes = array('mr', 'ms', 'mrs', 'miss', 'dr', 'rev', 'fr', 'sr', 'prof', 'sir');
|
||||
|
||||
if (in_array($first_name, $prefixes) || in_array($first_name, array_map(function ($i) {return $i . '.';}, $prefixes))) {
|
||||
if(isset($name_parts[2])) {
|
||||
// Mr James Smith -> James
|
||||
$first_name = $name_parts[1];
|
||||
} else {
|
||||
// Mr Smith (no first name given)
|
||||
return $full_name;
|
||||
}
|
||||
}
|
||||
|
||||
// Detect LastName, FirstName
|
||||
if (self::heskMbSubstr($first_name, -1, 1) == ',') {
|
||||
if (count($name_parts) == 2) {
|
||||
$first_name = $name_parts[1];
|
||||
} else {
|
||||
return $full_name;
|
||||
}
|
||||
}
|
||||
|
||||
// If the first name doesn't have at least 3 chars, return the original
|
||||
if(self::heskMbStrlen($first_name) < 3) {
|
||||
return $full_name;
|
||||
}
|
||||
|
||||
// Return the name with first character uppercase
|
||||
return self::heskUcfirst($first_name);
|
||||
}
|
||||
|
||||
static function heskMbStrToLower($in) {
|
||||
return function_exists('mb_strtolower') ? mb_strtolower($in) : strtolower($in);
|
||||
}
|
||||
|
||||
static function heskMbStrlen($in) {
|
||||
return function_exists('mb_strlen') ? mb_strlen($in, 'UTF-8') : strlen($in);
|
||||
}
|
||||
|
||||
static function heskMbSubstr($in, $start, $length) {
|
||||
return function_exists('mb_substr') ? mb_substr($in, $start, $length, 'UTF-8') : substr($in, $start, $length);
|
||||
}
|
||||
|
||||
static function heskUcfirst($in) {
|
||||
return function_exists('mb_convert_case') ? mb_convert_case($in, MB_CASE_TITLE, 'UTF-8') : ucfirst($in);
|
||||
}
|
||||
}
|
30
api/BusinessLogic/Navigation/CustomNavElement.php
Normal file
30
api/BusinessLogic/Navigation/CustomNavElement.php
Normal file
@ -0,0 +1,30 @@
|
||||
<?php
|
||||
|
||||
namespace BusinessLogic\Navigation;
|
||||
|
||||
|
||||
class CustomNavElement extends \BaseClass {
|
||||
/* @var $id int*/
|
||||
public $id;
|
||||
|
||||
/* @var $text string[] */
|
||||
public $text;
|
||||
|
||||
/* @var $subtext string[]|null */
|
||||
public $subtext;
|
||||
|
||||
/* @var $imageUrl string|null */
|
||||
public $imageUrl;
|
||||
|
||||
/* @var $fontIcon string|null */
|
||||
public $fontIcon;
|
||||
|
||||
/* @var $place int */
|
||||
public $place;
|
||||
|
||||
/* @var $url string */
|
||||
public $url;
|
||||
|
||||
/* @var $sort int */
|
||||
public $sort;
|
||||
}
|
70
api/BusinessLogic/Navigation/CustomNavElementHandler.php
Normal file
70
api/BusinessLogic/Navigation/CustomNavElementHandler.php
Normal file
@ -0,0 +1,70 @@
|
||||
<?php
|
||||
|
||||
namespace BusinessLogic\Navigation;
|
||||
|
||||
// TODO Test!
|
||||
use BusinessLogic\Exceptions\ApiFriendlyException;
|
||||
use DataAccess\Navigation\CustomNavElementGateway;
|
||||
|
||||
class CustomNavElementHandler extends \BaseClass {
|
||||
/* @var $customNavElementGateway CustomNavElementGateway */
|
||||
private $customNavElementGateway;
|
||||
|
||||
function __construct(CustomNavElementGateway $customNavElementGateway) {
|
||||
$this->customNavElementGateway = $customNavElementGateway;
|
||||
}
|
||||
|
||||
|
||||
function getAllCustomNavElements($heskSettings) {
|
||||
return $this->customNavElementGateway->getAllCustomNavElements($heskSettings);
|
||||
}
|
||||
|
||||
function getCustomNavElement($id, $heskSettings) {
|
||||
$elements = $this->getAllCustomNavElements($heskSettings);
|
||||
|
||||
foreach ($elements as $element) {
|
||||
if ($element->id === intval($id)) {
|
||||
return output($element);
|
||||
}
|
||||
}
|
||||
|
||||
throw new ApiFriendlyException("Custom nav element {$id} not found!", "Element Not Found", 404);
|
||||
}
|
||||
|
||||
function deleteCustomNavElement($id, $heskSettings) {
|
||||
$this->customNavElementGateway->deleteCustomNavElement($id, $heskSettings);
|
||||
$this->customNavElementGateway->resortAllElements($heskSettings);
|
||||
}
|
||||
|
||||
function saveCustomNavElement($element, $heskSettings) {
|
||||
$this->customNavElementGateway->saveCustomNavElement($element, $heskSettings);
|
||||
}
|
||||
|
||||
function createCustomNavElement($element, $heskSettings) {
|
||||
$element = $this->customNavElementGateway->createCustomNavElement($element, $heskSettings);
|
||||
$this->customNavElementGateway->resortAllElements($heskSettings);
|
||||
|
||||
return $element;
|
||||
}
|
||||
|
||||
function sortCustomNavElement($elementId, $direction, $heskSettings) {
|
||||
/* @var $element CustomNavElement */
|
||||
$elements = $this->customNavElementGateway->getAllCustomNavElements($heskSettings);
|
||||
$elementToChange = null;
|
||||
foreach ($elements as $element) {
|
||||
if ($element->id === intval($elementId)) {
|
||||
$elementToChange = $element;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if ($direction === Direction::UP) {
|
||||
$elementToChange->sort -= 15;
|
||||
} else {
|
||||
$elementToChange->sort += 15;
|
||||
}
|
||||
|
||||
$this->customNavElementGateway->saveCustomNavElement($elementToChange, $heskSettings);
|
||||
$this->customNavElementGateway->resortAllElements($heskSettings);
|
||||
}
|
||||
}
|
10
api/BusinessLogic/Navigation/CustomNavElementPlace.php
Normal file
10
api/BusinessLogic/Navigation/CustomNavElementPlace.php
Normal file
@ -0,0 +1,10 @@
|
||||
<?php
|
||||
|
||||
namespace BusinessLogic\Navigation;
|
||||
|
||||
|
||||
class CustomNavElementPlace extends \BaseClass {
|
||||
const HOMEPAGE_BLOCK = 1;
|
||||
const CUSTOMER_NAVIGATION = 2;
|
||||
const ADMIN_NAVIGATION = 3;
|
||||
}
|
9
api/BusinessLogic/Navigation/Direction.php
Normal file
9
api/BusinessLogic/Navigation/Direction.php
Normal file
@ -0,0 +1,9 @@
|
||||
<?php
|
||||
|
||||
namespace BusinessLogic\Navigation;
|
||||
|
||||
|
||||
class Direction extends \BaseClass {
|
||||
const UP = 'up';
|
||||
const DOWN = 'down';
|
||||
}
|
52
api/BusinessLogic/Security/BanRetriever.php
Normal file
52
api/BusinessLogic/Security/BanRetriever.php
Normal file
@ -0,0 +1,52 @@
|
||||
<?php
|
||||
|
||||
namespace BusinessLogic\Security;
|
||||
|
||||
|
||||
use DataAccess\Security\BanGateway;
|
||||
|
||||
class BanRetriever extends \BaseClass {
|
||||
/**
|
||||
* @var BanGateway
|
||||
*/
|
||||
private $banGateway;
|
||||
|
||||
function __construct(BanGateway $banGateway) {
|
||||
$this->banGateway = $banGateway;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $email
|
||||
* @param $heskSettings
|
||||
* @return bool
|
||||
*/
|
||||
function isEmailBanned($email, $heskSettings) {
|
||||
|
||||
$bannedEmails = $this->banGateway->getEmailBans($heskSettings);
|
||||
|
||||
foreach ($bannedEmails as $bannedEmail) {
|
||||
if ($bannedEmail->email === $email) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $ip int the IP address, converted beforehand using ip2long()
|
||||
* @param $heskSettings
|
||||
* @return bool
|
||||
*/
|
||||
function isIpAddressBanned($ip, $heskSettings) {
|
||||
$bannedIps = $this->banGateway->getIpBans($heskSettings);
|
||||
|
||||
foreach ($bannedIps as $bannedIp) {
|
||||
if ($bannedIp->ipFrom <= $ip && $bannedIp->ipTo >= $ip) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
26
api/BusinessLogic/Security/BannedEmail.php
Normal file
26
api/BusinessLogic/Security/BannedEmail.php
Normal file
@ -0,0 +1,26 @@
|
||||
<?php
|
||||
|
||||
namespace BusinessLogic\Security;
|
||||
|
||||
|
||||
class BannedEmail extends \BaseClass {
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
public $id;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
public $email;
|
||||
|
||||
/**
|
||||
* @var int|null The user who banned the email, or null if the user was deleted
|
||||
*/
|
||||
public $bannedById;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
public $dateBanned;
|
||||
}
|
36
api/BusinessLogic/Security/BannedIp.php
Normal file
36
api/BusinessLogic/Security/BannedIp.php
Normal file
@ -0,0 +1,36 @@
|
||||
<?php
|
||||
|
||||
namespace BusinessLogic\Security;
|
||||
|
||||
|
||||
class BannedIp extends \BaseClass {
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
public $id;
|
||||
|
||||
/**
|
||||
* @var int the lower bound of the IP address range
|
||||
*/
|
||||
public $ipFrom;
|
||||
|
||||
/**
|
||||
* @var int the upper bound of the IP address range
|
||||
*/
|
||||
public $ipTo;
|
||||
|
||||
/**
|
||||
* @var string the display of the IP ban to be shown to the user
|
||||
*/
|
||||
public $ipDisplay;
|
||||
|
||||
/**
|
||||
* @var int|null The user who banned the IP, or null if the user was deleted
|
||||
*/
|
||||
public $bannedById;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
public $dateBanned;
|
||||
}
|
23
api/BusinessLogic/Security/PermissionChecker.php
Normal file
23
api/BusinessLogic/Security/PermissionChecker.php
Normal file
@ -0,0 +1,23 @@
|
||||
<?php
|
||||
|
||||
namespace BusinessLogic\Security;
|
||||
|
||||
|
||||
class PermissionChecker extends \BaseClass {
|
||||
/**
|
||||
* @param $userContext UserContext
|
||||
* @param $permission string
|
||||
* @return bool
|
||||
*/
|
||||
function doesUserHavePermission($userContext, $permission) {
|
||||
if ($userContext->admin) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (in_array($permission, $userContext->permissions)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
131
api/BusinessLogic/Security/UserContext.php
Normal file
131
api/BusinessLogic/Security/UserContext.php
Normal file
@ -0,0 +1,131 @@
|
||||
<?php
|
||||
|
||||
namespace BusinessLogic\Security;
|
||||
|
||||
|
||||
use BusinessLogic\Helpers;
|
||||
|
||||
class UserContext extends \BaseClass {
|
||||
/* @var $id int */
|
||||
public $id;
|
||||
|
||||
/* @var $username string */
|
||||
public $username;
|
||||
|
||||
/* @var $admin bool */
|
||||
public $admin;
|
||||
|
||||
/* @var $name string */
|
||||
public $name;
|
||||
|
||||
/* @var $email string */
|
||||
public $email;
|
||||
|
||||
/* @var $signature string */
|
||||
public $signature;
|
||||
|
||||
/* @var $language string|null */
|
||||
public $language;
|
||||
|
||||
/* @var $categories int[] */
|
||||
public $categories;
|
||||
|
||||
/* @var $permissions string[] */
|
||||
public $permissions;
|
||||
|
||||
/* @var UserContextPreferences */
|
||||
public $preferences;
|
||||
|
||||
/* @var UserContextNotifications */
|
||||
public $notificationSettings;
|
||||
|
||||
/* @var $autoAssign bool */
|
||||
public $autoAssign;
|
||||
|
||||
/* @var $ratingNegative int */
|
||||
public $ratingNegative;
|
||||
|
||||
/* @var $ratingPositive int */
|
||||
public $ratingPositive;
|
||||
|
||||
/* @var $rating float */
|
||||
public $rating;
|
||||
|
||||
/* @var $totalNumberOfReplies int */
|
||||
public $totalNumberOfReplies;
|
||||
|
||||
/* @var $active bool */
|
||||
public $active;
|
||||
|
||||
function isAnonymousUser() {
|
||||
return $this->id === -1;
|
||||
}
|
||||
|
||||
static function buildAnonymousUser() {
|
||||
$userContext = new UserContext();
|
||||
$userContext->id = -1;
|
||||
$userContext->username = "API - ANONYMOUS USER"; // Usernames can't have spaces, so no one will take this username
|
||||
$userContext->admin = false;
|
||||
$userContext->name = "ANONYMOUS USER";
|
||||
$userContext->email = "anonymous-user@example.com";
|
||||
$userContext->categories = array();
|
||||
$userContext->permissions = array();
|
||||
$userContext->autoAssign = false;
|
||||
$userContext->active = true;
|
||||
|
||||
return $userContext;
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds a user context based on the current session. **The session must be active!**
|
||||
* @param $dataRow array the $_SESSION superglobal or the hesk_users result set
|
||||
* @return UserContext the built user context
|
||||
*/
|
||||
static function fromDataRow($dataRow) {
|
||||
$userContext = new UserContext();
|
||||
$userContext->id = intval($dataRow['id']);
|
||||
$userContext->username = $dataRow['user'];
|
||||
$userContext->admin = Helpers::boolval($dataRow['isadmin']);
|
||||
$userContext->name = $dataRow['name'];
|
||||
$userContext->email = $dataRow['email'];
|
||||
$userContext->signature = $dataRow['signature'];
|
||||
$userContext->language = $dataRow['language'];
|
||||
if (is_array($dataRow['categories'])) {
|
||||
$userContext->categories = $dataRow['categories'];
|
||||
} else {
|
||||
$userContext->categories = explode(',', $dataRow['categories']);
|
||||
}
|
||||
$userContext->permissions = explode(',', $dataRow['heskprivileges']);
|
||||
$userContext->autoAssign = Helpers::boolval($dataRow['autoassign']);
|
||||
$userContext->ratingNegative = intval($dataRow['ratingneg']);
|
||||
$userContext->ratingPositive = intval($dataRow['ratingpos']);
|
||||
$userContext->rating = floatval($dataRow['rating']);
|
||||
$userContext->totalNumberOfReplies = intval($dataRow['replies']);
|
||||
$userContext->active = Helpers::boolval($dataRow['active']);
|
||||
|
||||
$preferences = new UserContextPreferences();
|
||||
$preferences->afterReply = intval($dataRow['afterreply']);
|
||||
$preferences->autoStartTimeWorked = Helpers::boolval($dataRow['autostart']);
|
||||
$preferences->autoreload = intval($dataRow['autoreload']);
|
||||
$preferences->defaultNotifyCustomerNewTicket = Helpers::boolval($dataRow['notify_customer_new']);
|
||||
$preferences->defaultNotifyCustomerReply = Helpers::boolval($dataRow['notify_customer_reply']);
|
||||
$preferences->showSuggestedKnowledgebaseArticles = Helpers::boolval($dataRow['show_suggested']);
|
||||
$preferences->defaultCalendarView = intval($dataRow['default_calendar_view']);
|
||||
$preferences->defaultTicketView = $dataRow['default_list'];
|
||||
$userContext->preferences = $preferences;
|
||||
|
||||
$notifications = new UserContextNotifications();
|
||||
$notifications->newUnassigned = Helpers::boolval($dataRow['notify_new_unassigned']);
|
||||
$notifications->newAssignedToMe = Helpers::boolval($dataRow['notify_new_my']);
|
||||
$notifications->replyUnassigned = Helpers::boolval($dataRow['notify_reply_unassigned']);
|
||||
$notifications->replyToMe = Helpers::boolval($dataRow['notify_reply_my']);
|
||||
$notifications->ticketAssignedToMe = Helpers::boolval($dataRow['notify_assigned']);
|
||||
$notifications->privateMessage = Helpers::boolval($dataRow['notify_pm']);
|
||||
$notifications->noteOnTicketAssignedToMe = Helpers::boolval($dataRow['notify_note']);
|
||||
$notifications->noteOnTicketNotAssignedToMe = Helpers::boolval($dataRow['notify_note_unassigned']);
|
||||
$notifications->overdueTicketUnassigned = Helpers::boolval($dataRow['notify_overdue_unassigned']);
|
||||
$userContext->notificationSettings = $notifications;
|
||||
|
||||
return $userContext;
|
||||
}
|
||||
}
|
87
api/BusinessLogic/Security/UserContextBuilder.php
Normal file
87
api/BusinessLogic/Security/UserContextBuilder.php
Normal file
@ -0,0 +1,87 @@
|
||||
<?php
|
||||
|
||||
namespace BusinessLogic\Security;
|
||||
|
||||
|
||||
use BusinessLogic\Exceptions\InvalidAuthenticationTokenException;
|
||||
use BusinessLogic\Exceptions\MissingAuthenticationTokenException;
|
||||
use BusinessLogic\Helpers;
|
||||
use DataAccess\Security\UserGateway;
|
||||
|
||||
class UserContextBuilder extends \BaseClass {
|
||||
/**
|
||||
* @var UserGateway
|
||||
*/
|
||||
private $userGateway;
|
||||
|
||||
function __construct(UserGateway $userGateway) {
|
||||
$this->userGateway = $userGateway;
|
||||
}
|
||||
|
||||
function buildUserContext($authToken, $heskSettings) {
|
||||
$NULL_OR_EMPTY_STRING = 'cf83e1357eefb8bdf1542850d66d8007d620e4050b5715dc83f4a921d36ce9ce47d0d13c5d85f2b0ff8318d2877eec2f63b931bd47417a81a538327af927da3e';
|
||||
|
||||
$hashedToken = Helpers::hashToken($authToken);
|
||||
|
||||
if ($hashedToken === $NULL_OR_EMPTY_STRING) {
|
||||
throw new MissingAuthenticationTokenException();
|
||||
}
|
||||
|
||||
$userRow = $this->userGateway->getUserForAuthToken($hashedToken, $heskSettings);
|
||||
|
||||
if ($userRow === null) {
|
||||
throw new InvalidAuthenticationTokenException();
|
||||
}
|
||||
|
||||
return UserContext::fromDataRow($userRow);
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds a user context based on the current session. **The session must be active!**
|
||||
* @param $dataRow array the $_SESSION superglobal or the hesk_users result set
|
||||
* @return UserContext the built user context
|
||||
*/
|
||||
function fromDataRow($dataRow) {
|
||||
$userContext = new UserContext();
|
||||
$userContext->id = $dataRow['id'];
|
||||
$userContext->username = $dataRow['user'];
|
||||
$userContext->admin = $dataRow['isadmin'];
|
||||
$userContext->name = $dataRow['name'];
|
||||
$userContext->email = $dataRow['email'];
|
||||
$userContext->signature = $dataRow['signature'];
|
||||
$userContext->language = $dataRow['language'];
|
||||
$userContext->categories = explode(',', $dataRow['categories']);
|
||||
$userContext->permissions = explode(',', $dataRow['heskprivileges']);
|
||||
$userContext->autoAssign = $dataRow['autoassign'];
|
||||
$userContext->ratingNegative = $dataRow['ratingneg'];
|
||||
$userContext->ratingPositive = $dataRow['ratingpos'];
|
||||
$userContext->rating = $dataRow['rating'];
|
||||
$userContext->totalNumberOfReplies = $dataRow['replies'];
|
||||
$userContext->active = $dataRow['active'];
|
||||
|
||||
$preferences = new UserContextPreferences();
|
||||
$preferences->afterReply = $dataRow['afterreply'];
|
||||
$preferences->autoStartTimeWorked = $dataRow['autostart'];
|
||||
$preferences->autoreload = $dataRow['autoreload'];
|
||||
$preferences->defaultNotifyCustomerNewTicket = $dataRow['notify_customer_new'];
|
||||
$preferences->defaultNotifyCustomerReply = $dataRow['notify_customer_reply'];
|
||||
$preferences->showSuggestedKnowledgebaseArticles = $dataRow['show_suggested'];
|
||||
$preferences->defaultCalendarView = $dataRow['default_calendar_view'];
|
||||
$preferences->defaultTicketView = $dataRow['default_list'];
|
||||
$userContext->preferences = $preferences;
|
||||
|
||||
$notifications = new UserContextNotifications();
|
||||
$notifications->newUnassigned = $dataRow['notify_new_unassigned'];
|
||||
$notifications->newAssignedToMe = $dataRow['notify_new_my'];
|
||||
$notifications->replyUnassigned = $dataRow['notify_reply_unassigned'];
|
||||
$notifications->replyToMe = $dataRow['notify_reply_my'];
|
||||
$notifications->ticketAssignedToMe = $dataRow['notify_assigned'];
|
||||
$notifications->privateMessage = $dataRow['notify_pm'];
|
||||
$notifications->noteOnTicketAssignedToMe = $dataRow['notify_note'];
|
||||
$notifications->noteOnTicketNotAssignedToMe = $dataRow['notify_note_unassigned'];
|
||||
$notifications->overdueTicketUnassigned = $dataRow['notify_overdue_unassigned'];
|
||||
$userContext->notificationSettings = $notifications;
|
||||
|
||||
return $userContext;
|
||||
}
|
||||
}
|
16
api/BusinessLogic/Security/UserContextNotifications.php
Normal file
16
api/BusinessLogic/Security/UserContextNotifications.php
Normal file
@ -0,0 +1,16 @@
|
||||
<?php
|
||||
|
||||
namespace BusinessLogic\Security;
|
||||
|
||||
|
||||
class UserContextNotifications extends \BaseClass {
|
||||
public $newUnassigned;
|
||||
public $newAssignedToMe;
|
||||
public $replyUnassigned;
|
||||
public $replyToMe;
|
||||
public $ticketAssignedToMe;
|
||||
public $privateMessage;
|
||||
public $noteOnTicketAssignedToMe;
|
||||
public $noteOnTicketNotAssignedToMe;
|
||||
public $overdueTicketUnassigned;
|
||||
}
|
15
api/BusinessLogic/Security/UserContextPreferences.php
Normal file
15
api/BusinessLogic/Security/UserContextPreferences.php
Normal file
@ -0,0 +1,15 @@
|
||||
<?php
|
||||
|
||||
namespace BusinessLogic\Security;
|
||||
|
||||
|
||||
class UserContextPreferences extends \BaseClass {
|
||||
public $afterReply;
|
||||
public $autoStartTimeWorked;
|
||||
public $autoreload;
|
||||
public $defaultNotifyCustomerNewTicket;
|
||||
public $defaultNotifyCustomerReply;
|
||||
public $showSuggestedKnowledgebaseArticles;
|
||||
public $defaultCalendarView;
|
||||
public $defaultTicketView;
|
||||
}
|
23
api/BusinessLogic/Security/UserPrivilege.php
Normal file
23
api/BusinessLogic/Security/UserPrivilege.php
Normal file
@ -0,0 +1,23 @@
|
||||
<?php
|
||||
/**
|
||||
* Created by PhpStorm.
|
||||
* User: mkoch
|
||||
* Date: 3/12/2017
|
||||
* Time: 12:11 PM
|
||||
*/
|
||||
|
||||
namespace BusinessLogic\Security;
|
||||
|
||||
|
||||
class UserPrivilege extends \BaseClass {
|
||||
const CAN_VIEW_TICKETS = 'can_view_tickets';
|
||||
const CAN_REPLY_TO_TICKETS = 'can_reply_tickets';
|
||||
const CAN_EDIT_TICKETS = 'can_edit_tickets';
|
||||
const CAN_DELETE_TICKETS = 'can_del_tickets';
|
||||
const CAN_MANAGE_CATEGORIES = 'can_man_cat';
|
||||
const CAN_VIEW_ASSIGNED_TO_OTHER = 'can_view_ass_others';
|
||||
const CAN_VIEW_UNASSIGNED = 'can_view_unassigned';
|
||||
const CAN_VIEW_ASSIGNED_BY_ME = 'can_view_ass_by';
|
||||
const CAN_MANAGE_SERVICE_MESSAGES = 'can_service_msg';
|
||||
const CAN_CHANGE_DUE_DATE = 'can_change_due_date';
|
||||
}
|
55
api/BusinessLogic/Security/UserToTicketChecker.php
Normal file
55
api/BusinessLogic/Security/UserToTicketChecker.php
Normal file
@ -0,0 +1,55 @@
|
||||
<?php
|
||||
|
||||
namespace BusinessLogic\Security;
|
||||
|
||||
|
||||
use BusinessLogic\Tickets\Ticket;
|
||||
use DataAccess\Security\UserGateway;
|
||||
|
||||
class UserToTicketChecker extends \BaseClass {
|
||||
/* @var $userGateway UserGateway */
|
||||
private $userGateway;
|
||||
|
||||
function __construct(UserGateway $userGateway) {
|
||||
$this->userGateway = $userGateway;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $user UserContext
|
||||
* @param $ticket Ticket
|
||||
* @param $heskSettings array
|
||||
* @param $extraPermissions UserPrivilege[] additional privileges the user needs besides CAN_VIEW_TICKETS (if not an admin)
|
||||
* for this to return true
|
||||
* @return bool
|
||||
*/
|
||||
function isTicketAccessibleToUser($user, $ticket, $heskSettings, $extraPermissions = array()) {
|
||||
if ($user->admin === true) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (in_array(UserPrivilege::CAN_VIEW_ASSIGNED_BY_ME, $user->permissions) &&
|
||||
$ticket->assignedBy === $user->id) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!in_array($ticket->categoryId, $user->categories)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$categoryManager = $this->userGateway->getManagerForCategory($ticket->categoryId, $heskSettings);
|
||||
|
||||
if ($categoryManager !== null && $user->id === $categoryManager->id) {
|
||||
return true;
|
||||
}
|
||||
|
||||
$extraPermissions[] = UserPrivilege::CAN_VIEW_TICKETS;
|
||||
|
||||
foreach ($extraPermissions as $permission) {
|
||||
if (!in_array($permission, $user->permissions)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
@ -0,0 +1,12 @@
|
||||
<?php
|
||||
|
||||
namespace BusinessLogic\ServiceMessages;
|
||||
|
||||
|
||||
class GetServiceMessagesFilter {
|
||||
/* @var $includeStaffServiceMessages bool */
|
||||
public $includeStaffServiceMessages = true;
|
||||
|
||||
/* @var $includeDrafts bool */
|
||||
public $includeDrafts = true;
|
||||
}
|
39
api/BusinessLogic/ServiceMessages/ServiceMessage.php
Normal file
39
api/BusinessLogic/ServiceMessages/ServiceMessage.php
Normal file
@ -0,0 +1,39 @@
|
||||
<?php
|
||||
|
||||
namespace BusinessLogic\ServiceMessages;
|
||||
|
||||
|
||||
class ServiceMessage extends \BaseClass {
|
||||
/* @var $id int */
|
||||
public $id;
|
||||
|
||||
/* @var $dateCreated string */
|
||||
public $dateCreated;
|
||||
|
||||
/* @var $createdBy int */
|
||||
public $createdBy;
|
||||
|
||||
/* @var $title string */
|
||||
public $title;
|
||||
|
||||
/* @var $message string */
|
||||
public $message;
|
||||
|
||||
/* @var $style string */
|
||||
public $style;
|
||||
|
||||
/* @var $published bool */
|
||||
public $published;
|
||||
|
||||
/* @var $order int */
|
||||
public $order;
|
||||
|
||||
/* @var $icon string */
|
||||
public $icon;
|
||||
|
||||
/* @var $locations string[] */
|
||||
public $locations;
|
||||
|
||||
/* @var $language string */
|
||||
public $language;
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user