mirror of
https://github.com/opensourcepos/opensourcepos.git
synced 2026-05-25 00:44:03 -04:00
Compare commits
2599 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4bab3fc4e3 | ||
|
|
5c1baf20b0 | ||
|
|
075d4e1aeb | ||
|
|
8dc7855e56 | ||
|
|
d992c434d8 | ||
|
|
1c07ba1945 | ||
|
|
6357491874 | ||
|
|
8880061e0e | ||
|
|
c397a81b48 | ||
|
|
76e1516147 | ||
|
|
c495cf29a0 | ||
|
|
c64ac468a3 | ||
|
|
0892944aaa | ||
|
|
abafd59683 | ||
|
|
dab4a8f90d | ||
|
|
ca7c3e9d76 | ||
|
|
61eeed0b75 | ||
|
|
3852bd5c3e | ||
|
|
cf8890efdc | ||
|
|
e4fe32b85c | ||
|
|
6bed03a2e7 | ||
|
|
390fefa803 | ||
|
|
3c069ad226 | ||
|
|
2e07818a2c | ||
|
|
5ce8c9694d | ||
|
|
0415cb53e9 | ||
|
|
a254f78750 | ||
|
|
adde140660 | ||
|
|
0a3414f4f3 | ||
|
|
4c3ab04e3d | ||
|
|
9e442e6c61 | ||
|
|
64dd3afa54 | ||
|
|
bd17e73b36 | ||
|
|
3e7faf1ea1 | ||
|
|
34048c2ba5 | ||
|
|
3848b72bbe | ||
|
|
154db58f34 | ||
|
|
2e5cfbc1e7 | ||
|
|
174338f9bf | ||
|
|
4d9840f9ad | ||
|
|
821aaa4e63 | ||
|
|
425f0fd21b | ||
|
|
41117b7007 | ||
|
|
6cc4196af8 | ||
|
|
4329f519f8 | ||
|
|
c29937ac68 | ||
|
|
9d7c07c1dd | ||
|
|
f24f62c0c6 | ||
|
|
9370d3434a | ||
|
|
a60a58337e | ||
|
|
6e8d9bb85c | ||
|
|
7642e45850 | ||
|
|
4d37b29304 | ||
|
|
ac5dbe0b0f | ||
|
|
cd19babd6e | ||
|
|
bbb77a00ad | ||
|
|
c48563b703 | ||
|
|
740d12e137 | ||
|
|
e4369db19c | ||
|
|
d5086ba42f | ||
|
|
1c95ed432f | ||
|
|
9f50a6ab92 | ||
|
|
ee319189ed | ||
|
|
0053398037 | ||
|
|
f106097e2d | ||
|
|
cc1497baad | ||
|
|
87317b00bd | ||
|
|
e949f776ac | ||
|
|
27ca6cf6f8 | ||
|
|
6d35fae28e | ||
|
|
27c8f2614d | ||
|
|
fbce16acd1 | ||
|
|
a700d4ffff | ||
|
|
738e1de6b4 | ||
|
|
5da3dc3928 | ||
|
|
129eb78552 | ||
|
|
97ab38436f | ||
|
|
0820a0d7ff | ||
|
|
a597fa86eb | ||
|
|
c05b814009 | ||
|
|
82c6954d1c | ||
|
|
b43ec350ae | ||
|
|
c6bc1680fa | ||
|
|
7d64b483ca | ||
|
|
cfa7891b06 | ||
|
|
3663c7e344 | ||
|
|
3ca871aea9 | ||
|
|
6b935ca169 | ||
|
|
41a9b03761 | ||
|
|
6a3da0f5dc | ||
|
|
a00c38bee8 | ||
|
|
593b5cebaa | ||
|
|
4b57b6144b | ||
|
|
d2fbceeb22 | ||
|
|
3113945f0f | ||
|
|
8a9e0f352a | ||
|
|
c844f2c1e7 | ||
|
|
9b0dc5a9c3 | ||
|
|
11ba752010 | ||
|
|
b26dbc7022 | ||
|
|
22f1ed10be | ||
|
|
0a289f9ed4 | ||
|
|
1b0eb0d936 | ||
|
|
d146a05991 | ||
|
|
8c43345a20 | ||
|
|
50c4b30df2 | ||
|
|
9f2e39711f | ||
|
|
43b4cee636 | ||
|
|
ba8c0b7b15 | ||
|
|
86622615fd | ||
|
|
3dfa877365 | ||
|
|
b22252be4e | ||
|
|
83697eaf8b | ||
|
|
fe627eb943 | ||
|
|
4dea268e51 | ||
|
|
2f7d738a20 | ||
|
|
b99ec9117b | ||
|
|
3c56ae6cb6 | ||
|
|
b1fdd45372 | ||
|
|
4d46da7974 | ||
|
|
84a5f654b1 | ||
|
|
01afdc5979 | ||
|
|
3c379a6458 | ||
|
|
bb203efe21 | ||
|
|
9e2a757b16 | ||
|
|
4079e44572 | ||
|
|
4595ab5c35 | ||
|
|
35150f14ed | ||
|
|
a7ecec4bd3 | ||
|
|
ae472d0176 | ||
|
|
b18ae57cf6 | ||
|
|
2f064d9a94 | ||
|
|
4f2b6badd9 | ||
|
|
bf76450ca5 | ||
|
|
7c88bdb21f | ||
|
|
544d8a496e | ||
|
|
88625ad83c | ||
|
|
e89f698dff | ||
|
|
a1e0e7946c | ||
|
|
68ce90ad8e | ||
|
|
06e36ac4f4 | ||
|
|
ccd52e1ded | ||
|
|
ed0fd469e6 | ||
|
|
7884bab2ed | ||
|
|
213bba8312 | ||
|
|
17982988f7 | ||
|
|
a7d4e4c163 | ||
|
|
2411fe1e3f | ||
|
|
b2a2ee9613 | ||
|
|
dc78162486 | ||
|
|
ffbb96fdee | ||
|
|
fd1cad99ed | ||
|
|
e7808b35cd | ||
|
|
16b9bd1305 | ||
|
|
3a3ddb99d2 | ||
|
|
49c6ec282f | ||
|
|
2557945713 | ||
|
|
3368c62690 | ||
|
|
3b411bbefc | ||
|
|
4d8006da2e | ||
|
|
a5c797b617 | ||
|
|
b9bc7583b2 | ||
|
|
b84d9d894f | ||
|
|
63d9fd219c | ||
|
|
ddb0e7560c | ||
|
|
a24a55f812 | ||
|
|
a353068ca5 | ||
|
|
442b64d1d1 | ||
|
|
8547c3b071 | ||
|
|
bf30652a3d | ||
|
|
7525c650ab | ||
|
|
f2ccebc84d | ||
|
|
5edfed5bfc | ||
|
|
8c60d6cdc6 | ||
|
|
33cc7e3f9c | ||
|
|
395ac217b8 | ||
|
|
1189c3dadf | ||
|
|
4c92e26e37 | ||
|
|
ee1f23289a | ||
|
|
84f6adb532 | ||
|
|
da5b6e2592 | ||
|
|
38b26a3e68 | ||
|
|
9d70b23b31 | ||
|
|
2466469a9c | ||
|
|
ad47e64dfd | ||
|
|
520ae0d2a9 | ||
|
|
8fccee51a7 | ||
|
|
32074771ac | ||
|
|
44a1c89292 | ||
|
|
55d4c004eb | ||
|
|
1fbc42c079 | ||
|
|
2b7a25d8a3 | ||
|
|
1f3074232c | ||
|
|
d3a77118ba | ||
|
|
83732383a7 | ||
|
|
b495a97483 | ||
|
|
a0672d04ce | ||
|
|
e9ac0adb81 | ||
|
|
6febdc4e9d | ||
|
|
8ca18edfbd | ||
|
|
6f4cd9d5eb | ||
|
|
63866bf0d3 | ||
|
|
4e8b63c002 | ||
|
|
1500aa8b51 | ||
|
|
9af064f003 | ||
|
|
0e4f894b2a | ||
|
|
91a677f018 | ||
|
|
556ab3c229 | ||
|
|
d7da611a76 | ||
|
|
fa8f42629b | ||
|
|
f8e1d57f71 | ||
|
|
380953d8b7 | ||
|
|
aea080052a | ||
|
|
3568debbe6 | ||
|
|
d2e8a156ab | ||
|
|
d6f6e2f234 | ||
|
|
22c6d5401c | ||
|
|
e44733599e | ||
|
|
acb12dd517 | ||
|
|
3dbc124f62 | ||
|
|
563fcf2385 | ||
|
|
accd11b74f | ||
|
|
c7b21362cb | ||
|
|
78b9daac39 | ||
|
|
00f90857a0 | ||
|
|
3bb8d7ad32 | ||
|
|
83ed48c7db | ||
|
|
7e0f099479 | ||
|
|
96af1b64ff | ||
|
|
a005ed6862 | ||
|
|
cf6df1e99c | ||
|
|
c1509a9dd1 | ||
|
|
d78b547b98 | ||
|
|
17136a011a | ||
|
|
171870f512 | ||
|
|
04a3a0631f | ||
|
|
2dd81f4e77 | ||
|
|
39a7665930 | ||
|
|
1223dccd8c | ||
|
|
d078523528 | ||
|
|
574bcbac09 | ||
|
|
8dad6d5249 | ||
|
|
75b9fdb698 | ||
|
|
6131e3db34 | ||
|
|
30f6e315e3 | ||
|
|
01dfed1793 | ||
|
|
f82990a304 | ||
|
|
6131c5eb53 | ||
|
|
a1b25d193c | ||
|
|
67eab51e4f | ||
|
|
97591e77fc | ||
|
|
146d0ce6c8 | ||
|
|
9733ca9171 | ||
|
|
b2fcd59841 | ||
|
|
f769561a3c | ||
|
|
2a617f7c5c | ||
|
|
544c142ef0 | ||
|
|
8991407b16 | ||
|
|
caedd4cfc0 | ||
|
|
9323f3803b | ||
|
|
a031fd924b | ||
|
|
afadb1e171 | ||
|
|
8f7f22726a | ||
|
|
5cbebec92f | ||
|
|
2b8e8bb13e | ||
|
|
cae200e06a | ||
|
|
49cbdb53ee | ||
|
|
e96e00d902 | ||
|
|
6ae6fa7c32 | ||
|
|
4653cde725 | ||
|
|
97f2ee521f | ||
|
|
ee55be347d | ||
|
|
cee7956788 | ||
|
|
ffa77cfb71 | ||
|
|
a956a009f9 | ||
|
|
9f7ca1a747 | ||
|
|
66d319f082 | ||
|
|
010a3c7126 | ||
|
|
c1b3382795 | ||
|
|
2a8078aac9 | ||
|
|
409f0f0084 | ||
|
|
df2a76b4cf | ||
|
|
ec97cd5cdf | ||
|
|
46da8bab1d | ||
|
|
ae6e082983 | ||
|
|
028f38784e | ||
|
|
136093b8ab | ||
|
|
17f3635574 | ||
|
|
c33a3b3720 | ||
|
|
63b728b118 | ||
|
|
1cfdee4114 | ||
|
|
98ccea3419 | ||
|
|
5306b6d26f | ||
|
|
63bc9d70a7 | ||
|
|
2590feee6c | ||
|
|
1dd375311c | ||
|
|
f121a31bb9 | ||
|
|
75d54f4f62 | ||
|
|
8d16b28160 | ||
|
|
97d07d96c8 | ||
|
|
78f9560e6d | ||
|
|
fd625afeb6 | ||
|
|
91374a54b4 | ||
|
|
9c4591ea31 | ||
|
|
5ade46bc35 | ||
|
|
b1bee3196a | ||
|
|
16dd8fb0a1 | ||
|
|
b69d57a4b9 | ||
|
|
1ba0f3c839 | ||
|
|
a258a27d9b | ||
|
|
082bfeca88 | ||
|
|
32075b96dd | ||
|
|
3844d6b5f5 | ||
|
|
aa6eed2947 | ||
|
|
4a74c645ad | ||
|
|
dc2c77752b | ||
|
|
85fdc661d1 | ||
|
|
64163e8e6e | ||
|
|
810ba78776 | ||
|
|
82a17eb6ce | ||
|
|
b726596ec1 | ||
|
|
5aac69ad6d | ||
|
|
c24c7ed721 | ||
|
|
f4519251af | ||
|
|
ba6e38f755 | ||
|
|
f838dae4b5 | ||
|
|
380d3a1355 | ||
|
|
ceb5b85640 | ||
|
|
fc6f8e4d92 | ||
|
|
37dcba63bb | ||
|
|
edf5c1ec90 | ||
|
|
426bdfbadd | ||
|
|
40114601df | ||
|
|
e2d9b2e141 | ||
|
|
427a2c3777 | ||
|
|
98864c0446 | ||
|
|
0995c71630 | ||
|
|
407e8723d8 | ||
|
|
022435d0db | ||
|
|
7f7943d538 | ||
|
|
780a4c37a7 | ||
|
|
b24879c9ef | ||
|
|
d6000c79f7 | ||
|
|
9ed0984c21 | ||
|
|
21415ccb3c | ||
|
|
cadae3eabc | ||
|
|
54150940ee | ||
|
|
81d76b0c03 | ||
|
|
469d3d500e | ||
|
|
36fe5ded7e | ||
|
|
fec096915a | ||
|
|
abdcd31b9e | ||
|
|
efd58f2281 | ||
|
|
211c18a99e | ||
|
|
166c2558e6 | ||
|
|
54237a1fed | ||
|
|
1d9548870b | ||
|
|
032276de87 | ||
|
|
61e16d2d33 | ||
|
|
463dfcd1a4 | ||
|
|
022dfea51a | ||
|
|
ef23596b6e | ||
|
|
58e8469dde | ||
|
|
60d77e1f61 | ||
|
|
49d60313f6 | ||
|
|
ed54adb70c | ||
|
|
a353e73549 | ||
|
|
e1508e610b | ||
|
|
463cf9266d | ||
|
|
23a6ae791b | ||
|
|
48d58b822a | ||
|
|
08de3e1167 | ||
|
|
20c30a2c15 | ||
|
|
b51ea94eb5 | ||
|
|
2c613bdc86 | ||
|
|
f784aa3956 | ||
|
|
73b97de3e5 | ||
|
|
5cc2898a4b | ||
|
|
820cae2d3d | ||
|
|
3569165097 | ||
|
|
2c1f2823f2 | ||
|
|
ce45769163 | ||
|
|
12b62119bf | ||
|
|
9caf22aea4 | ||
|
|
2258938604 | ||
|
|
3f2a9e8c52 | ||
|
|
385de892fe | ||
|
|
a5787ecb4e | ||
|
|
bfecf15ee2 | ||
|
|
5ffb6b4c18 | ||
|
|
a6d70b6fcd | ||
|
|
bee9c7af5d | ||
|
|
f0bdb84422 | ||
|
|
12e7c5d440 | ||
|
|
623ff4fee9 | ||
|
|
579a85a9fc | ||
|
|
22e3bba649 | ||
|
|
9075bfcf37 | ||
|
|
478b2c0ea5 | ||
|
|
91918fc937 | ||
|
|
017df21f17 | ||
|
|
e7d420f44f | ||
|
|
04f2e916bb | ||
|
|
7770c6817f | ||
|
|
6caf2ea672 | ||
|
|
317d0adb78 | ||
|
|
a7659d7b76 | ||
|
|
4353f5a12b | ||
|
|
160b7ca189 | ||
|
|
c9b15c7eeb | ||
|
|
a1f6dbccc5 | ||
|
|
d399637c18 | ||
|
|
54740f734f | ||
|
|
7e8ac7c100 | ||
|
|
4cff8d7dd2 | ||
|
|
a7ada7e85a | ||
|
|
a3bf1d7eeb | ||
|
|
ecce5d39bb | ||
|
|
9d113c3327 | ||
|
|
1f3b05a37b | ||
|
|
8e60437db0 | ||
|
|
6cb6e2fb24 | ||
|
|
71a95d7b31 | ||
|
|
8be987f564 | ||
|
|
8bf147f025 | ||
|
|
b3c42d4d06 | ||
|
|
043493ba0a | ||
|
|
88d5b3336a | ||
|
|
3a1b16c070 | ||
|
|
44e57c59e4 | ||
|
|
204499e5d0 | ||
|
|
31f736e2e0 | ||
|
|
5a4d7a40ec | ||
|
|
8c5706bc1f | ||
|
|
04af352fad | ||
|
|
677b296721 | ||
|
|
a4c8db7592 | ||
|
|
241f05a000 | ||
|
|
1f5ffb04a1 | ||
|
|
5f12d8ade3 | ||
|
|
da64b67e26 | ||
|
|
beedb7e2f6 | ||
|
|
fa63933f69 | ||
|
|
b32b767260 | ||
|
|
4457cf7055 | ||
|
|
458e9a2db5 | ||
|
|
3245ddb22d | ||
|
|
5c833e48fb | ||
|
|
49c3ad57fc | ||
|
|
67402b6cd5 | ||
|
|
cd2f2c35a4 | ||
|
|
4efbfe2581 | ||
|
|
2fd350d924 | ||
|
|
e1c6a7c98a | ||
|
|
873bbfd2b8 | ||
|
|
523cbd40e3 | ||
|
|
c97393f53b | ||
|
|
d175b97596 | ||
|
|
aff5dd146e | ||
|
|
768f73770f | ||
|
|
b8f4da9314 | ||
|
|
9c29e066ff | ||
|
|
7b0abf5982 | ||
|
|
9fe8cffa16 | ||
|
|
024990dac8 | ||
|
|
d479ed2512 | ||
|
|
f799d4f296 | ||
|
|
c389a2c8a5 | ||
|
|
0c8b4de6ac | ||
|
|
0d5cad8f27 | ||
|
|
abf163c6fa | ||
|
|
e1011b2662 | ||
|
|
cea2a2e051 | ||
|
|
376c8cd3b2 | ||
|
|
bea420032a | ||
|
|
0e8594b92b | ||
|
|
fff072d302 | ||
|
|
803e2391ff | ||
|
|
a6cc775d17 | ||
|
|
c02f93bdf9 | ||
|
|
c3bbf75d0e | ||
|
|
f533e7629b | ||
|
|
54099bf43a | ||
|
|
60ce1970e7 | ||
|
|
9abb83f98b | ||
|
|
7302b0c5d8 | ||
|
|
b7a03e1a85 | ||
|
|
91e08639b0 | ||
|
|
c5874e71bb | ||
|
|
1315c52d41 | ||
|
|
e9c56184e0 | ||
|
|
99fbbb94a8 | ||
|
|
3b3d019a5d | ||
|
|
ee20237021 | ||
|
|
4341501307 | ||
|
|
fc657f1776 | ||
|
|
6f55bb8626 | ||
|
|
62d34178b0 | ||
|
|
9d1152c392 | ||
|
|
84cbef62f8 | ||
|
|
8e2f5b6a5e | ||
|
|
58764ac632 | ||
|
|
49ed5ac10a | ||
|
|
02f873aa64 | ||
|
|
1e431582b5 | ||
|
|
0d49fa72e1 | ||
|
|
364886e395 | ||
|
|
9d3b215fc2 | ||
|
|
4cd0f13485 | ||
|
|
937896d436 | ||
|
|
d5c3d8056a | ||
|
|
69fc834118 | ||
|
|
bac9897bed | ||
|
|
424e4f0f87 | ||
|
|
8e069c4e10 | ||
|
|
3fff00c1f5 | ||
|
|
57a6a8b1a5 | ||
|
|
e0f7e48d5a | ||
|
|
a7733bd244 | ||
|
|
eb39c0ba56 | ||
|
|
69a2f6b7f3 | ||
|
|
e241b1eb89 | ||
|
|
f1edb38be8 | ||
|
|
6d74f80306 | ||
|
|
0456465383 | ||
|
|
f4fedef0fb | ||
|
|
713f6106c1 | ||
|
|
e44683e6b6 | ||
|
|
9d594854b3 | ||
|
|
7a55c2311e | ||
|
|
ba5fa39151 | ||
|
|
75b401b068 | ||
|
|
7029858f58 | ||
|
|
fad12b9de2 | ||
|
|
8b96af3d19 | ||
|
|
447571090f | ||
|
|
a6e08b5d7d | ||
|
|
b3835ec6a3 | ||
|
|
080d3c0e3b | ||
|
|
86019e002d | ||
|
|
e0329472ef | ||
|
|
62f34663ae | ||
|
|
9bf1d66b74 | ||
|
|
74449f6570 | ||
|
|
2a306b888f | ||
|
|
161fa4f5d3 | ||
|
|
20791d7c12 | ||
|
|
1a8a19d568 | ||
|
|
61062e1278 | ||
|
|
1e87fe0a24 | ||
|
|
5f3a42592e | ||
|
|
8e27a88d3a | ||
|
|
b98b842ebe | ||
|
|
8f634d7cff | ||
|
|
7ab2272abc | ||
|
|
c0e63cbdfd | ||
|
|
173574ffaf | ||
|
|
8f0af3b450 | ||
|
|
2d71d3bd02 | ||
|
|
7be5816fa1 | ||
|
|
56864e6919 | ||
|
|
846d99d037 | ||
|
|
6c563a210e | ||
|
|
b49dbd39ed | ||
|
|
25282381f4 | ||
|
|
13b3a3b98f | ||
|
|
455b462d25 | ||
|
|
058cf639db | ||
|
|
2c97c79737 | ||
|
|
11135e9e4f | ||
|
|
ce321877ff | ||
|
|
630017aea1 | ||
|
|
e7c7af36ac | ||
|
|
9632e8b508 | ||
|
|
546167ac01 | ||
|
|
7bcc3d0f56 | ||
|
|
751e70fc15 | ||
|
|
8b1b5fc1d7 | ||
|
|
f49bf8d4d4 | ||
|
|
af4e93f483 | ||
|
|
4e9236b2e3 | ||
|
|
195a24feb0 | ||
|
|
6c5ab60f59 | ||
|
|
0458fcc99c | ||
|
|
a11e1dc585 | ||
|
|
072396f951 | ||
|
|
b3a2ca4db4 | ||
|
|
66278805c6 | ||
|
|
b91d383acf | ||
|
|
a7d7cbe43c | ||
|
|
ab2685ef62 | ||
|
|
c96c2a69a6 | ||
|
|
323738210b | ||
|
|
d61d3b46f3 | ||
|
|
a08826e909 | ||
|
|
ad1e63fa3a | ||
|
|
a25a87ec60 | ||
|
|
8c6ff0ceb1 | ||
|
|
0f352abcaa | ||
|
|
4910441099 | ||
|
|
c248086566 | ||
|
|
c784a537dd | ||
|
|
00958608e0 | ||
|
|
d3cb3b7f87 | ||
|
|
983830ef70 | ||
|
|
35b6609327 | ||
|
|
b058e91a99 | ||
|
|
2cde603949 | ||
|
|
b5b2d4f62f | ||
|
|
473676fb08 | ||
|
|
64c2996c74 | ||
|
|
15ad253c3a | ||
|
|
fcab8e1fc9 | ||
|
|
8b92d19732 | ||
|
|
2f221004fb | ||
|
|
2b2396521c | ||
|
|
f26c703626 | ||
|
|
eef9dc82ca | ||
|
|
5a21ac7c89 | ||
|
|
269bb900b5 | ||
|
|
37ed01ed3e | ||
|
|
fe4961be8e | ||
|
|
058414e78c | ||
|
|
49dba3035c | ||
|
|
e73c33279a | ||
|
|
cc2916b65b | ||
|
|
a64c4db252 | ||
|
|
57172e17fc | ||
|
|
cc61365f4d | ||
|
|
59c27f275c | ||
|
|
95453620b7 | ||
|
|
daa99997d8 | ||
|
|
c3e5291e06 | ||
|
|
e2e84eccaa | ||
|
|
9d67268693 | ||
|
|
f9490ba571 | ||
|
|
767c818e8e | ||
|
|
6c3fcc29f3 | ||
|
|
b2c2749c99 | ||
|
|
c28061f006 | ||
|
|
bfd7e95db4 | ||
|
|
358104d6db | ||
|
|
0f3b0a0095 | ||
|
|
54efec81d3 | ||
|
|
0910e86724 | ||
|
|
504d69f9cc | ||
|
|
b1b6301b93 | ||
|
|
7aca0a57c5 | ||
|
|
9ff7f9f212 | ||
|
|
c5a78613ba | ||
|
|
826837e902 | ||
|
|
1b9fc76757 | ||
|
|
e7ea24bcda | ||
|
|
3d38b2322e | ||
|
|
66b1e538ad | ||
|
|
77714b97c4 | ||
|
|
f5e2f1ac0a | ||
|
|
fe79af8efd | ||
|
|
1802a16c02 | ||
|
|
86470a68f5 | ||
|
|
dd538e07cb | ||
|
|
0f09ae6657 | ||
|
|
b2d21dd8a5 | ||
|
|
89a1224ec3 | ||
|
|
79d5bc9156 | ||
|
|
a98bf2d69c | ||
|
|
852aa48463 | ||
|
|
398edf40a1 | ||
|
|
dc5ebd2e85 | ||
|
|
5c375636a2 | ||
|
|
39dbd9af52 | ||
|
|
5514676dee | ||
|
|
d63446cdb8 | ||
|
|
7789675a55 | ||
|
|
729283af37 | ||
|
|
01f4ea3890 | ||
|
|
92575844e3 | ||
|
|
883d42d529 | ||
|
|
efc9b36fdd | ||
|
|
775721a059 | ||
|
|
15d0e0b1f9 | ||
|
|
8b6e83e05c | ||
|
|
25e5751d8d | ||
|
|
09179be68b | ||
|
|
2a3c4bf655 | ||
|
|
76e37dedfe | ||
|
|
616f65306a | ||
|
|
e8f5102f99 | ||
|
|
1b93713028 | ||
|
|
e772f8d150 | ||
|
|
9020a67338 | ||
|
|
6144902cc1 | ||
|
|
ad913c79fc | ||
|
|
62c5f2ad16 | ||
|
|
ac32a06689 | ||
|
|
be15e98182 | ||
|
|
bd18549613 | ||
|
|
18e6a3f78b | ||
|
|
35b17b120b | ||
|
|
dbaf7e8481 | ||
|
|
372c3ab6bf | ||
|
|
27e9f3ff1a | ||
|
|
783b7f0205 | ||
|
|
02159d5045 | ||
|
|
6b00091332 | ||
|
|
59297f6954 | ||
|
|
8d7e8d6b9b | ||
|
|
c11973f78b | ||
|
|
6f1da83723 | ||
|
|
d1af54ff21 | ||
|
|
2c8fe60035 | ||
|
|
8e6b8f4da0 | ||
|
|
e687e505f8 | ||
|
|
ce6e9d6ba4 | ||
|
|
67cace93c7 | ||
|
|
6e82602a47 | ||
|
|
178ba9f702 | ||
|
|
cac02eaf96 | ||
|
|
aa346cbb3f | ||
|
|
07dd8158e5 | ||
|
|
f01537247b | ||
|
|
8408901e5a | ||
|
|
4c7abd7728 | ||
|
|
1fd6f5fb70 | ||
|
|
3a8b28fcb6 | ||
|
|
3de96b03a0 | ||
|
|
3e91eb33de | ||
|
|
4dc05063b8 | ||
|
|
4f93bc7430 | ||
|
|
8816c37236 | ||
|
|
b93d6a851d | ||
|
|
e85e2e5e55 | ||
|
|
c01663f901 | ||
|
|
700e695b4b | ||
|
|
07541bf933 | ||
|
|
ec76d85350 | ||
|
|
717bda9f31 | ||
|
|
76a0026bdb | ||
|
|
f2c4024734 | ||
|
|
4de3cbeab6 | ||
|
|
da1d435114 | ||
|
|
4036caf829 | ||
|
|
36d549cb9b | ||
|
|
af84a617de | ||
|
|
e42e01a07f | ||
|
|
de91510beb | ||
|
|
7a3aab92b9 | ||
|
|
771c1b9d1e | ||
|
|
5a9aa96b7e | ||
|
|
cfa051cee8 | ||
|
|
981aceda53 | ||
|
|
23b4dacb9a | ||
|
|
d5c390706b | ||
|
|
893aad3502 | ||
|
|
d98e788775 | ||
|
|
8a59470872 | ||
|
|
de38e26856 | ||
|
|
b98d56f126 | ||
|
|
2adbc403ad | ||
|
|
e1ffda5d27 | ||
|
|
5a6e17f9b0 | ||
|
|
18e6b12541 | ||
|
|
2754d8413c | ||
|
|
df442b734c | ||
|
|
283279955f | ||
|
|
2e208a7a2c | ||
|
|
685dde7ceb | ||
|
|
75eec14689 | ||
|
|
941e968fda | ||
|
|
cf24aebebc | ||
|
|
75e0b2898e | ||
|
|
4936f1b302 | ||
|
|
e4215df835 | ||
|
|
c6a519e4ad | ||
|
|
2b7e9cf631 | ||
|
|
a496b971db | ||
|
|
4d7397647f | ||
|
|
0b28e0c668 | ||
|
|
ba2e274cb0 | ||
|
|
9aee57da2f | ||
|
|
2499bc5015 | ||
|
|
6f9a15f464 | ||
|
|
51db8d5b91 | ||
|
|
040f4711d1 | ||
|
|
60fc671a9d | ||
|
|
48aa05f858 | ||
|
|
71de1d1247 | ||
|
|
12fcfcb24a | ||
|
|
a77fd438c5 | ||
|
|
887c8374b6 | ||
|
|
2bc702acc8 | ||
|
|
e1743f4d9f | ||
|
|
ec96bd8c89 | ||
|
|
bd38c1dc67 | ||
|
|
9e7b0db950 | ||
|
|
52ab4ce035 | ||
|
|
8dbd5e55dd | ||
|
|
1eb7ab2406 | ||
|
|
97fbfb32b9 | ||
|
|
c5f73e0f38 | ||
|
|
62030d50d8 | ||
|
|
d20dcce5b4 | ||
|
|
00d15765f3 | ||
|
|
11ff84e71d | ||
|
|
3806b9350b | ||
|
|
7429637dbf | ||
|
|
26fa619127 | ||
|
|
a6a3f83378 | ||
|
|
5ad39fe230 | ||
|
|
91ef1af0c5 | ||
|
|
54f1ca2d1f | ||
|
|
28953a0def | ||
|
|
688ce015fe | ||
|
|
b3189a01bf | ||
|
|
eee3132cce | ||
|
|
3730cb0803 | ||
|
|
a39c15c71d | ||
|
|
fea5b064a9 | ||
|
|
8169a08ff1 | ||
|
|
e26290469f | ||
|
|
5dfed09167 | ||
|
|
a3a48d3ea6 | ||
|
|
07441d2144 | ||
|
|
3612ecf577 | ||
|
|
f9edc63385 | ||
|
|
31367d8943 | ||
|
|
4c763ea9c0 | ||
|
|
7b8a7033a1 | ||
|
|
8478a7797c | ||
|
|
44a571ad4f | ||
|
|
0dcfc650a4 | ||
|
|
e4e106d6bc | ||
|
|
00bc200643 | ||
|
|
a40ccfd232 | ||
|
|
19cc328c65 | ||
|
|
f26963ed3b | ||
|
|
a175879fe2 | ||
|
|
46e515db1e | ||
|
|
3368003a53 | ||
|
|
0112fea0a6 | ||
|
|
2a5e8fe98c | ||
|
|
b07d99ea38 | ||
|
|
ea328d6543 | ||
|
|
b2b0cb34b5 | ||
|
|
a91aa3792b | ||
|
|
de49a50187 | ||
|
|
675404ce89 | ||
|
|
1ea015c734 | ||
|
|
56f4dee411 | ||
|
|
f393cb4c04 | ||
|
|
4a4172bd0f | ||
|
|
0aee736fd1 | ||
|
|
86fc8209a2 | ||
|
|
db49939d6e | ||
|
|
8f2052b43e | ||
|
|
b7aeb7f36d | ||
|
|
2fe9c1f58b | ||
|
|
63f859d392 | ||
|
|
26a5f4688b | ||
|
|
93d00f06b3 | ||
|
|
b5f6cd56d6 | ||
|
|
e451618114 | ||
|
|
8e8713d1b0 | ||
|
|
90523b79e2 | ||
|
|
c715bca5cd | ||
|
|
c88bbe3852 | ||
|
|
1ee11ea61c | ||
|
|
5a19031271 | ||
|
|
8817005401 | ||
|
|
6df1c7818e | ||
|
|
3af4bf0187 | ||
|
|
1d4692a44a | ||
|
|
258debc94a | ||
|
|
34c01ed179 | ||
|
|
477dcb78db | ||
|
|
d4ddb4c8ee | ||
|
|
9864b126a8 | ||
|
|
d29ed9441e | ||
|
|
e940c1e99d | ||
|
|
bdc63c5c02 | ||
|
|
120b932219 | ||
|
|
745b9efed1 | ||
|
|
582311a461 | ||
|
|
69b687989d | ||
|
|
1055ebc5ff | ||
|
|
d49cb4fc0f | ||
|
|
31bcad32a6 | ||
|
|
6956c6362e | ||
|
|
4821a8851e | ||
|
|
8f133b804f | ||
|
|
7894c0c0fc | ||
|
|
2254ce1fbb | ||
|
|
7eb8284f2e | ||
|
|
75f5e0f1fc | ||
|
|
0cf8543991 | ||
|
|
ec11d3f3e4 | ||
|
|
33ff6c9a44 | ||
|
|
5dd7a5fde1 | ||
|
|
6f261132a3 | ||
|
|
665edee213 | ||
|
|
a2af047899 | ||
|
|
bbec55e77b | ||
|
|
896cc96119 | ||
|
|
ec1ff216ad | ||
|
|
c57679cac1 | ||
|
|
ddaa1e88e9 | ||
|
|
6a65618e82 | ||
|
|
833490c9a3 | ||
|
|
92f62621d5 | ||
|
|
97334b2e42 | ||
|
|
767b0d293b | ||
|
|
ffc7b10b3c | ||
|
|
5a41626ffd | ||
|
|
e12de53fd8 | ||
|
|
768bbf8b18 | ||
|
|
0e4fcadd9f | ||
|
|
dd6c8fdd25 | ||
|
|
c579fcf2fa | ||
|
|
1ac7994758 | ||
|
|
c9fd560b00 | ||
|
|
a9afce8e14 | ||
|
|
2177e71f47 | ||
|
|
2a4668a80f | ||
|
|
86d152a668 | ||
|
|
f23f583ced | ||
|
|
712414c56e | ||
|
|
6fefe3e016 | ||
|
|
abd3e8ac34 | ||
|
|
c364d296cd | ||
|
|
8e86fbdc2a | ||
|
|
0f8c7f52cd | ||
|
|
bbe766165a | ||
|
|
48fe421bf0 | ||
|
|
6c714b2dc4 | ||
|
|
9d08e9e5be | ||
|
|
4a05f00307 | ||
|
|
6b0a2576a3 | ||
|
|
86d3c6bf04 | ||
|
|
3ef1abdcc5 | ||
|
|
627bbb9b07 | ||
|
|
283ec86c3f | ||
|
|
b15b302624 | ||
|
|
1f508d0b89 | ||
|
|
e218453ab3 | ||
|
|
0476265e7a | ||
|
|
1589b8ecee | ||
|
|
32e1babefd | ||
|
|
ec2fe4a5de | ||
|
|
91b03ab78b | ||
|
|
1f6e689151 | ||
|
|
560d25a281 | ||
|
|
0ab72d8719 | ||
|
|
991042a0f6 | ||
|
|
6c043e8c5f | ||
|
|
0530abc5f8 | ||
|
|
32004f28d4 | ||
|
|
2a05d91d44 | ||
|
|
a99d3536ce | ||
|
|
c6378ba4d2 | ||
|
|
aa0e250250 | ||
|
|
6dc1f81cbf | ||
|
|
c3d9173442 | ||
|
|
3d238ee78c | ||
|
|
f0fd8a305b | ||
|
|
a6045d9e7b | ||
|
|
02813c8374 | ||
|
|
4835507e1e | ||
|
|
3b0df85f69 | ||
|
|
36177d1431 | ||
|
|
bc04884190 | ||
|
|
8a3ba5692a | ||
|
|
e89bd73bb5 | ||
|
|
f1936dbb4d | ||
|
|
629f180b8d | ||
|
|
6485cf050d | ||
|
|
cd792eb56a | ||
|
|
256c926e3d | ||
|
|
c18c703237 | ||
|
|
6e64f8ef00 | ||
|
|
591d432d4f | ||
|
|
4a61119c3d | ||
|
|
d7237261f7 | ||
|
|
81512aa76e | ||
|
|
0dec6819ad | ||
|
|
afca2882f8 | ||
|
|
eb610fccb5 | ||
|
|
641e2f414c | ||
|
|
5d49728c74 | ||
|
|
858845f4f5 | ||
|
|
eccf08cf8f | ||
|
|
623572b0f5 | ||
|
|
dc0d580d05 | ||
|
|
fe05845bd4 | ||
|
|
1798b4553b | ||
|
|
e59a3372a9 | ||
|
|
8a7b93f1b9 | ||
|
|
61a3fee4a6 | ||
|
|
a92d60d99f | ||
|
|
47486b980f | ||
|
|
dc14cbd7ab | ||
|
|
d7b7f5510c | ||
|
|
323b7900e9 | ||
|
|
eb4d0c8c88 | ||
|
|
b0e3600ea6 | ||
|
|
41ae935223 | ||
|
|
60db2cc4b0 | ||
|
|
b7951ea5b2 | ||
|
|
cb31ebb06e | ||
|
|
3f0a53933c | ||
|
|
f92b06cff2 | ||
|
|
bab4791b5e | ||
|
|
421468f6d8 | ||
|
|
f3a08eab3b | ||
|
|
863988d2ab | ||
|
|
e524593a15 | ||
|
|
181d904360 | ||
|
|
4448348f7c | ||
|
|
bb762efac7 | ||
|
|
c5697edf76 | ||
|
|
3f73e449f0 | ||
|
|
a18745b3af | ||
|
|
0057c77721 | ||
|
|
fd3fecbd76 | ||
|
|
ad690c9ca6 | ||
|
|
ab29527619 | ||
|
|
12b5ed43c6 | ||
|
|
a78f053c80 | ||
|
|
5ea0324bc0 | ||
|
|
005193e3e0 | ||
|
|
95733ea476 | ||
|
|
c8499599ab | ||
|
|
2f44a9d5c2 | ||
|
|
d28e95208b | ||
|
|
c4bda0e1fe | ||
|
|
15e0da4515 | ||
|
|
c71ce1e8ae | ||
|
|
d5e2b6cb0d | ||
|
|
d25b1408c9 | ||
|
|
c3f83202a8 | ||
|
|
643c5d91a6 | ||
|
|
69e56d06ae | ||
|
|
ee2f66aa61 | ||
|
|
16502065fa | ||
|
|
1a7ed8a69b | ||
|
|
d2eaaab92c | ||
|
|
55666caac5 | ||
|
|
841c8166a2 | ||
|
|
4e5ac5c521 | ||
|
|
d59e713f1f | ||
|
|
78877094fb | ||
|
|
e2e0ade259 | ||
|
|
e61e409bfe | ||
|
|
5d22e41fe2 | ||
|
|
0d82db42da | ||
|
|
ff7848dcff | ||
|
|
4866457164 | ||
|
|
acd003a44c | ||
|
|
f407702dbe | ||
|
|
d129610b24 | ||
|
|
55bf5eddda | ||
|
|
94ea15bc18 | ||
|
|
91fd435cca | ||
|
|
8f019b4631 | ||
|
|
51e160982e | ||
|
|
1f2218bbc9 | ||
|
|
77145d29a8 | ||
|
|
3a447561eb | ||
|
|
6ee545d6eb | ||
|
|
afbf714bd2 | ||
|
|
1a2bc1cc42 | ||
|
|
4268a70388 | ||
|
|
189b189e08 | ||
|
|
403c875edf | ||
|
|
4f6cf8b917 | ||
|
|
fd6335081d | ||
|
|
234cedff15 | ||
|
|
8348628dc6 | ||
|
|
ade9a57fe0 | ||
|
|
6559f9c561 | ||
|
|
a7a559fc72 | ||
|
|
e25d1483ae | ||
|
|
41a5218583 | ||
|
|
cc7fcaf264 | ||
|
|
e776f31ec5 | ||
|
|
d60e1283bd | ||
|
|
b2d80acafc | ||
|
|
37097babcf | ||
|
|
15bb3ad6a3 | ||
|
|
5c0c74b037 | ||
|
|
7093874366 | ||
|
|
34ae6486dc | ||
|
|
2d3d385cbc | ||
|
|
c0a9349b60 | ||
|
|
c4a76ad01c | ||
|
|
8d1bc4cf17 | ||
|
|
daa1614615 | ||
|
|
34afb9d496 | ||
|
|
27d5fd882b | ||
|
|
d25c6dc8c1 | ||
|
|
11e1cc51aa | ||
|
|
b32c23ce10 | ||
|
|
00a792213c | ||
|
|
c710ec938f | ||
|
|
d0ada1e42f | ||
|
|
e89fc6afb2 | ||
|
|
f9fb9e44b3 | ||
|
|
4c2d63bbd3 | ||
|
|
ac92c16c0a | ||
|
|
edd1f047bd | ||
|
|
c8ac6a65dc | ||
|
|
6acfc60988 | ||
|
|
6682b77164 | ||
|
|
eb4f3b425b | ||
|
|
93b0844121 | ||
|
|
40d32e1b8a | ||
|
|
af1aee0015 | ||
|
|
1e64b3e610 | ||
|
|
8f728500d4 | ||
|
|
c68fa19584 | ||
|
|
5bdf6d396b | ||
|
|
0114223e99 | ||
|
|
b819442e98 | ||
|
|
15681edf43 | ||
|
|
0cd19ca43f | ||
|
|
621a74653d | ||
|
|
6dc49ca00e | ||
|
|
7a91388d8d | ||
|
|
1680f2b602 | ||
|
|
80c58cf27d | ||
|
|
dd21f205b7 | ||
|
|
8261cc1f72 | ||
|
|
08a7bd9606 | ||
|
|
56ae0f265a | ||
|
|
c95c56ade7 | ||
|
|
b057d1c3c0 | ||
|
|
248cd29e01 | ||
|
|
bacc07ce35 | ||
|
|
aef542d096 | ||
|
|
28141185a4 | ||
|
|
deb235a971 | ||
|
|
878d93aee9 | ||
|
|
9db7eddc68 | ||
|
|
e2232ba9cc | ||
|
|
4db76371fd | ||
|
|
9d01398a4b | ||
|
|
66a4507525 | ||
|
|
938907fe20 | ||
|
|
1738f76402 | ||
|
|
b7251dd693 | ||
|
|
8f7a425333 | ||
|
|
7e7c068c90 | ||
|
|
73ae7b8fd2 | ||
|
|
56b228c698 | ||
|
|
b5a44a8308 | ||
|
|
1788941b5f | ||
|
|
27f093cf73 | ||
|
|
efe9ed22b3 | ||
|
|
e6a51d8c28 | ||
|
|
27f5dd7efc | ||
|
|
07642bd953 | ||
|
|
99afc02c9d | ||
|
|
74972712a6 | ||
|
|
826ffd79c9 | ||
|
|
7f8ac815ef | ||
|
|
04f27c328d | ||
|
|
793dd73248 | ||
|
|
28d89c685b | ||
|
|
d59b79e4b6 | ||
|
|
422ca99ab3 | ||
|
|
0ff095e889 | ||
|
|
e0bc9bb8f7 | ||
|
|
86afbf0d30 | ||
|
|
26d5605de5 | ||
|
|
6c0124cd17 | ||
|
|
effba9d102 | ||
|
|
15b13e1a3d | ||
|
|
1a0a3fbeba | ||
|
|
b7e0c0eba6 | ||
|
|
354076f8c3 | ||
|
|
6e9e7abcff | ||
|
|
cf314f98a6 | ||
|
|
a316e250de | ||
|
|
33b9f97bce | ||
|
|
3677b61dd9 | ||
|
|
e592040962 | ||
|
|
e51c79c423 | ||
|
|
f556361ade | ||
|
|
a317c32d1e | ||
|
|
0e60d5e6e1 | ||
|
|
6fda5d63fe | ||
|
|
7c9a2dee37 | ||
|
|
06f404ddc4 | ||
|
|
562a43a942 | ||
|
|
cbda2dae13 | ||
|
|
1abdd765de | ||
|
|
2f4d0986d9 | ||
|
|
bbac0f16bf | ||
|
|
b986ad437a | ||
|
|
68883230e8 | ||
|
|
5cb8141641 | ||
|
|
e6d6bf0392 | ||
|
|
85d2cf9e68 | ||
|
|
91f33d14b7 | ||
|
|
5e004309f0 | ||
|
|
aa8351c147 | ||
|
|
adacc2ab5f | ||
|
|
8bb4171265 | ||
|
|
87bd59a6bf | ||
|
|
488fc58a03 | ||
|
|
8cd521c6d1 | ||
|
|
faaac45653 | ||
|
|
d8e19ceeca | ||
|
|
00f99c524a | ||
|
|
91d5157765 | ||
|
|
b8414cc969 | ||
|
|
387b0004a8 | ||
|
|
cdc401dd7e | ||
|
|
74681e78e3 | ||
|
|
3f489d6f53 | ||
|
|
55350b8bf8 | ||
|
|
f52b61ae36 | ||
|
|
e131cda843 | ||
|
|
991854f0f2 | ||
|
|
af7d2f27aa | ||
|
|
3650b47d8b | ||
|
|
deea43ce67 | ||
|
|
3d9665c0a9 | ||
|
|
ae90dfa333 | ||
|
|
02dcb4dc90 | ||
|
|
4dc3c49d9d | ||
|
|
a77d63fad8 | ||
|
|
b487573b05 | ||
|
|
4528436fd5 | ||
|
|
5876efbbee | ||
|
|
1e1b0cd06b | ||
|
|
6826115b2d | ||
|
|
032bb34131 | ||
|
|
e9aa0068fe | ||
|
|
e55b5a743a | ||
|
|
e4955027d1 | ||
|
|
9bf8989960 | ||
|
|
53dcdc02cf | ||
|
|
69391eb434 | ||
|
|
aff7e6df3b | ||
|
|
9bf24fee5f | ||
|
|
2c53f0e585 | ||
|
|
5aeb1234a2 | ||
|
|
6e62a3fe15 | ||
|
|
67594190fc | ||
|
|
c6597ba6ce | ||
|
|
2187898b04 | ||
|
|
a6b5220047 | ||
|
|
78cb4822c2 | ||
|
|
ae4ff80974 | ||
|
|
df2d616566 | ||
|
|
353fa8e95c | ||
|
|
699236bca0 | ||
|
|
4ca862ba9f | ||
|
|
7222df3551 | ||
|
|
72e1158847 | ||
|
|
145d97737f | ||
|
|
8140d1aee4 | ||
|
|
5f5394b18f | ||
|
|
ceb9687e5e | ||
|
|
7a4525319a | ||
|
|
a175111b59 | ||
|
|
4cda5343aa | ||
|
|
e7cbacaae6 | ||
|
|
faadbe554a | ||
|
|
999e12279a | ||
|
|
37bb9b50f9 | ||
|
|
5e02f31866 | ||
|
|
bf0d24a96f | ||
|
|
be66258bfc | ||
|
|
87247333cc | ||
|
|
5e75613fec | ||
|
|
5b4d12cac8 | ||
|
|
0e013220ad | ||
|
|
ae92231903 | ||
|
|
9a1cf6752c | ||
|
|
9db439a8fe | ||
|
|
e458b23b7e | ||
|
|
4ca0e74d42 | ||
|
|
47357aaafc | ||
|
|
a99f326bb8 | ||
|
|
cc584ca063 | ||
|
|
d85aeaeaf8 | ||
|
|
cc2fd1876d | ||
|
|
f4a52dab8b | ||
|
|
d75a936472 | ||
|
|
2719c43e3d | ||
|
|
85983cd17a | ||
|
|
df9b776d56 | ||
|
|
b373b1e07e | ||
|
|
68cf3bf68b | ||
|
|
f9c1dde054 | ||
|
|
1393af1676 | ||
|
|
f359c475d3 | ||
|
|
9bc9b5c984 | ||
|
|
4922f5bb66 | ||
|
|
e36b2a1a03 | ||
|
|
bb5d39cd0d | ||
|
|
afe564e152 | ||
|
|
17ff097406 | ||
|
|
3b37f6c61a | ||
|
|
96cefd97b4 | ||
|
|
03af00e26e | ||
|
|
92bd7c2d43 | ||
|
|
4d6cc381ae | ||
|
|
3f36a8b15e | ||
|
|
5a9b6bd98b | ||
|
|
b9e160eaa3 | ||
|
|
ba95853884 | ||
|
|
f157d4d43d | ||
|
|
a2c3130720 | ||
|
|
258622ec87 | ||
|
|
b4023a051c | ||
|
|
1cdbee1a42 | ||
|
|
feff5ff3f3 | ||
|
|
0507db6a6f | ||
|
|
9b473e415d | ||
|
|
47974074ee | ||
|
|
bc56ee54a3 | ||
|
|
046a02d83c | ||
|
|
57e559e67b | ||
|
|
10e3ce9a9f | ||
|
|
953fa534f4 | ||
|
|
c7982b9552 | ||
|
|
6e0011b165 | ||
|
|
a3c172624a | ||
|
|
3a81a712ff | ||
|
|
775f40cb75 | ||
|
|
5814bfc7e8 | ||
|
|
3f309298d8 | ||
|
|
4ef8fc8df3 | ||
|
|
a627276265 | ||
|
|
6e4155ccbb | ||
|
|
84ef147835 | ||
|
|
925bee2b0a | ||
|
|
680f2bb555 | ||
|
|
29920c5456 | ||
|
|
ace3bedbbc | ||
|
|
476db84e86 | ||
|
|
dc638c74b5 | ||
|
|
f04a2db4a5 | ||
|
|
dd6bd1cf11 | ||
|
|
4b1d5456cc | ||
|
|
4b85c14f00 | ||
|
|
9b33f39086 | ||
|
|
bebb9ca34b | ||
|
|
1dba07049c | ||
|
|
aae2d8ffc8 | ||
|
|
a387a52578 | ||
|
|
399b997fd0 | ||
|
|
cb907ea303 | ||
|
|
744d166f58 | ||
|
|
f3dd11e2c5 | ||
|
|
7f1c374e3d | ||
|
|
80aba48240 | ||
|
|
a8bca7681d | ||
|
|
01e918e776 | ||
|
|
6095577f47 | ||
|
|
06db967ee6 | ||
|
|
467ed586b1 | ||
|
|
74660bcaa1 | ||
|
|
d9a4f93cfa | ||
|
|
c6e4584f71 | ||
|
|
3a2dd7134f | ||
|
|
d9649edc3e | ||
|
|
31335deeea | ||
|
|
ae26d9a007 | ||
|
|
305d9dd55e | ||
|
|
9a9dc9bf1e | ||
|
|
311225a126 | ||
|
|
cabccf0858 | ||
|
|
9e8cc93082 | ||
|
|
57de863f79 | ||
|
|
00565ddc8f | ||
|
|
7d4dff0a37 | ||
|
|
1ed76fa091 | ||
|
|
114c215407 | ||
|
|
9bef65b9cb | ||
|
|
dc4d582898 | ||
|
|
8b32a26e80 | ||
|
|
422e2ddbab | ||
|
|
c5988adbbb | ||
|
|
2727e91c96 | ||
|
|
4304f5ceea | ||
|
|
1666a3e689 | ||
|
|
2f8d66664b | ||
|
|
7c5276b014 | ||
|
|
5231c027af | ||
|
|
3974279607 | ||
|
|
7ef68fbc76 | ||
|
|
1440e6bce9 | ||
|
|
b66827b0ff | ||
|
|
540c4f3ec0 | ||
|
|
9e1064979a | ||
|
|
5047ca0f41 | ||
|
|
5267eadc56 | ||
|
|
04246d35ad | ||
|
|
20c0ffb9b0 | ||
|
|
88db2af11b | ||
|
|
577e5b2db4 | ||
|
|
35e76bdd4d | ||
|
|
9766dcfad3 | ||
|
|
0e2f84c91d | ||
|
|
77806412fa | ||
|
|
737980c041 | ||
|
|
e86ea272ca | ||
|
|
284a73f41d | ||
|
|
5a4c27cf87 | ||
|
|
e22e081865 | ||
|
|
123cb25bf5 | ||
|
|
00eb59f083 | ||
|
|
19165133ae | ||
|
|
e1035ff54b | ||
|
|
ed80627ddd | ||
|
|
d380524f9d | ||
|
|
ca39fb38ad | ||
|
|
be1be80a0e | ||
|
|
868868163c | ||
|
|
a831f09fca | ||
|
|
b0b8c0e936 | ||
|
|
047fd7b7ad | ||
|
|
e6a61941df | ||
|
|
f4237e3f68 | ||
|
|
1f2e87ec09 | ||
|
|
519b19ae64 | ||
|
|
001cd411f2 | ||
|
|
eefd9a88bd | ||
|
|
88219b6aa0 | ||
|
|
4b5b985315 | ||
|
|
ef45c96ce8 | ||
|
|
6dfb24e6f1 | ||
|
|
49c89d1cec | ||
|
|
872aa7b829 | ||
|
|
4dbb8655ee | ||
|
|
e326c1dfd4 | ||
|
|
ab3acf1605 | ||
|
|
7668991d6c | ||
|
|
0f95c6c9b5 | ||
|
|
768ffdfb4b | ||
|
|
9a9637bfb7 | ||
|
|
2cbff93ab5 | ||
|
|
e42aaed0b1 | ||
|
|
4678764a03 | ||
|
|
4120015d78 | ||
|
|
5ecc6ead7d | ||
|
|
816fcd9203 | ||
|
|
6f444b1a33 | ||
|
|
94141e21db | ||
|
|
17c23ad417 | ||
|
|
ef5c513f1b | ||
|
|
60f78c8eeb | ||
|
|
dd66496ccc | ||
|
|
d2e21e18a1 | ||
|
|
d21bedd8c1 | ||
|
|
0a71cb3d4d | ||
|
|
7758d96e34 | ||
|
|
71ab84e30f | ||
|
|
b1c36b790f | ||
|
|
0723bd2922 | ||
|
|
f5716ab5a3 | ||
|
|
3208b83169 | ||
|
|
a2515cf922 | ||
|
|
1df3ed8b46 | ||
|
|
d6985853d4 | ||
|
|
dac61c498e | ||
|
|
badc108b2e | ||
|
|
b3efd5301d | ||
|
|
e21f25c15b | ||
|
|
2d8bd2d307 | ||
|
|
20a6c6ec0a | ||
|
|
0cb68d47cb | ||
|
|
04a77dff7d | ||
|
|
8732b0e69a | ||
|
|
fe193053f1 | ||
|
|
20279c3bc0 | ||
|
|
20e4a3b057 | ||
|
|
1723347359 | ||
|
|
3b578d41bc | ||
|
|
573367eddc | ||
|
|
c5986ea943 | ||
|
|
90efaf03ee | ||
|
|
8217b70984 | ||
|
|
fd50f6079e | ||
|
|
a9086cac49 | ||
|
|
3fbc53e9b8 | ||
|
|
2dddd1b7ee | ||
|
|
978cdee7be | ||
|
|
e9e2c877d4 | ||
|
|
3543321309 | ||
|
|
b1409f432b | ||
|
|
676948729b | ||
|
|
10ab3911dc | ||
|
|
24dcc3f680 | ||
|
|
64ba842730 | ||
|
|
83992cbf0d | ||
|
|
5a2bd9a569 | ||
|
|
2fcc473830 | ||
|
|
86de36d731 | ||
|
|
592f378d2a | ||
|
|
a87629000e | ||
|
|
15e84f9b37 | ||
|
|
a9963dcfd0 | ||
|
|
974744858f | ||
|
|
a1a6ede046 | ||
|
|
7bba5f9dd0 | ||
|
|
39dd29b3c8 | ||
|
|
10cac5496b | ||
|
|
d88aee1676 | ||
|
|
f2e2b5c91b | ||
|
|
b07631798e | ||
|
|
e7815a1251 | ||
|
|
9dfc186fe4 | ||
|
|
9c025c6feb | ||
|
|
fdbb158c1d | ||
|
|
c695505605 | ||
|
|
dea8683fd4 | ||
|
|
efc5996282 | ||
|
|
ec2aa52d85 | ||
|
|
7d7afd4904 | ||
|
|
8a3fa821d9 | ||
|
|
16958d3b99 | ||
|
|
5829dd8ba5 | ||
|
|
d0c86b8dc4 | ||
|
|
0d0ec68e60 | ||
|
|
cc4edaa468 | ||
|
|
ffbba16a08 | ||
|
|
f235b33959 | ||
|
|
fd9118887c | ||
|
|
5fddfe20d6 | ||
|
|
e42a4e843b | ||
|
|
3b00c5bf9e | ||
|
|
7f1b8a146b | ||
|
|
e05b2697d4 | ||
|
|
da0678f079 | ||
|
|
2ba7b000c2 | ||
|
|
548df573bb | ||
|
|
f1d8378bcb | ||
|
|
42121017b5 | ||
|
|
6fade459ad | ||
|
|
b2e85aa0d8 | ||
|
|
9f3ecb0866 | ||
|
|
6a29ebeff8 | ||
|
|
221a575e5c | ||
|
|
2afac17848 | ||
|
|
e381b3fea5 | ||
|
|
49ed750045 | ||
|
|
1e1cfec94e | ||
|
|
713b88bbc4 | ||
|
|
811fdf9bc0 | ||
|
|
d40a43e1ca | ||
|
|
386057d544 | ||
|
|
c60fcb171c | ||
|
|
11b1072151 | ||
|
|
036a711c53 | ||
|
|
ceaa378978 | ||
|
|
83b4f9f8a8 | ||
|
|
838df08eae | ||
|
|
7dd1c9791d | ||
|
|
fc2094a9c3 | ||
|
|
505ab59903 | ||
|
|
1f169d8fab | ||
|
|
ebc1237ddc | ||
|
|
b1aa16f7a9 | ||
|
|
3206bbb41d | ||
|
|
3b559b056d | ||
|
|
cd0ef34f75 | ||
|
|
f89315a298 | ||
|
|
4a4a7921d7 | ||
|
|
691fa674c4 | ||
|
|
fe55841187 | ||
|
|
18d3f7db52 | ||
|
|
e3c538dbaf | ||
|
|
d08b0b7ef4 | ||
|
|
003d4de6be | ||
|
|
b6bda3c3ed | ||
|
|
71e1cb8fd0 | ||
|
|
4139d53938 | ||
|
|
ffa5b4ddb7 | ||
|
|
068f426c9e | ||
|
|
6f62085ba6 | ||
|
|
08e8209446 | ||
|
|
ea7cc16cc9 | ||
|
|
e3c9cddacb | ||
|
|
aae1ce5329 | ||
|
|
7350f4dc76 | ||
|
|
da307fdfbd | ||
|
|
9012006e84 | ||
|
|
91b18d032f | ||
|
|
b5f6fb124c | ||
|
|
a5f16abbd5 | ||
|
|
d319c5a73d | ||
|
|
f3270a545e | ||
|
|
9e01ca2e43 | ||
|
|
c3316040bb | ||
|
|
17084d8a8f | ||
|
|
71e54d90bf | ||
|
|
eb59079fe5 | ||
|
|
35f9904dbe | ||
|
|
ce2c83b3f9 | ||
|
|
c88de60a9f | ||
|
|
2bf82e6472 | ||
|
|
3ce939ad20 | ||
|
|
96004f5699 | ||
|
|
a2d2965785 | ||
|
|
3d15148b80 | ||
|
|
31166c814e | ||
|
|
0ec94f1044 | ||
|
|
6e7b32cb1b | ||
|
|
775c0cebf2 | ||
|
|
d67b33d996 | ||
|
|
375408a7a7 | ||
|
|
7677c33ce1 | ||
|
|
a5b2c82395 | ||
|
|
13587908f5 | ||
|
|
9c3c283912 | ||
|
|
d290134a48 | ||
|
|
057fdaea5d | ||
|
|
f440ff5e89 | ||
|
|
7f65b9cf2b | ||
|
|
e8a96054ee | ||
|
|
ad19dbc5ed | ||
|
|
dc0245c4fb | ||
|
|
e25c330dff | ||
|
|
9a6bd6e000 | ||
|
|
e302086b13 | ||
|
|
45675b8f29 | ||
|
|
64d0483300 | ||
|
|
798246e589 | ||
|
|
2c1231ca61 | ||
|
|
d6b009fba8 | ||
|
|
ad8d0821ad | ||
|
|
a6ba67e2fc | ||
|
|
9e1afd3f2b | ||
|
|
43e7e353e7 | ||
|
|
e4fc2ac06b | ||
|
|
59bbe55215 | ||
|
|
6b63e381f9 | ||
|
|
af6b323013 | ||
|
|
919e478184 | ||
|
|
3f34775000 | ||
|
|
6e7da88f94 | ||
|
|
cf1eec761b | ||
|
|
b51022e93f | ||
|
|
2bda02dd74 | ||
|
|
01aeca579a | ||
|
|
2555203a54 | ||
|
|
4f5f875f1e | ||
|
|
b77d368885 | ||
|
|
4b569d093b | ||
|
|
51bdfc050e | ||
|
|
1b19fed206 | ||
|
|
3336d42245 | ||
|
|
6fdecbe619 | ||
|
|
55764d7625 | ||
|
|
dd8d848544 | ||
|
|
6203504976 | ||
|
|
059ec54c72 | ||
|
|
75567b9620 | ||
|
|
1b859a8726 | ||
|
|
1c02508759 | ||
|
|
4c337aa5c6 | ||
|
|
523714c26a | ||
|
|
28e776248b | ||
|
|
333067955c | ||
|
|
a0886caf2f | ||
|
|
31cc67ea52 | ||
|
|
8b08bf5daa | ||
|
|
597a5caee5 | ||
|
|
19403adde2 | ||
|
|
119476ca74 | ||
|
|
dd07b9fcb8 | ||
|
|
4a54dc7dc7 | ||
|
|
e1f796cf99 | ||
|
|
266610399d | ||
|
|
7602e77071 | ||
|
|
bd7dd4741d | ||
|
|
3ed454d1b3 | ||
|
|
2402da6e30 | ||
|
|
c76109ab0a | ||
|
|
fe5e99978c | ||
|
|
63a6706770 | ||
|
|
4ea056e3f7 | ||
|
|
5f1d9e7f45 | ||
|
|
9fa2676352 | ||
|
|
76630365e7 | ||
|
|
cbc42f7868 | ||
|
|
fba0915c42 | ||
|
|
ab075fd94f | ||
|
|
956f18e55c | ||
|
|
05628ddaff | ||
|
|
2519d0fb20 | ||
|
|
28129ef075 | ||
|
|
0727ae06af | ||
|
|
0efc49f713 | ||
|
|
352586531f | ||
|
|
745874f0b3 | ||
|
|
d8e4bf48d8 | ||
|
|
4be3c8f433 | ||
|
|
9a7061e9c5 | ||
|
|
2743e1353a | ||
|
|
75db191baf | ||
|
|
a66868651b | ||
|
|
68deca1537 | ||
|
|
1af612d18e | ||
|
|
cfdbd01dac | ||
|
|
d88b51794e | ||
|
|
c9d806bd26 | ||
|
|
39d678b977 | ||
|
|
a0e894895e | ||
|
|
09a3499069 | ||
|
|
86b32240d3 | ||
|
|
0924a0f433 | ||
|
|
55f7bef253 | ||
|
|
38d234fa5f | ||
|
|
120b2bbc6e | ||
|
|
a3704f9b12 | ||
|
|
c82e9e4929 | ||
|
|
7f169222d0 | ||
|
|
21f5e46488 | ||
|
|
ef2cd9d001 | ||
|
|
72efafdc50 | ||
|
|
0f88d6462d | ||
|
|
3af19daa0e | ||
|
|
f11c2d7a4d | ||
|
|
be2bac84f1 | ||
|
|
dc06119586 | ||
|
|
0cbd19353c | ||
|
|
3c969858cf | ||
|
|
fbba5ea2c5 | ||
|
|
6d8c3b94e0 | ||
|
|
b3a1259861 | ||
|
|
a74e7565bf | ||
|
|
df6f118a79 | ||
|
|
f04cbc9674 | ||
|
|
3cff918f81 | ||
|
|
5be0feafe9 | ||
|
|
4618af352c | ||
|
|
81d1aa7873 | ||
|
|
8002694c96 | ||
|
|
5de3f17af8 | ||
|
|
1b5105f3af | ||
|
|
7b674b2e3f | ||
|
|
01486fd41e | ||
|
|
a69194745e | ||
|
|
90660fd9e9 | ||
|
|
bb1a1ccd62 | ||
|
|
806c1b9986 | ||
|
|
0ba5cadbb7 | ||
|
|
5b81ee1b1d | ||
|
|
c136832db1 | ||
|
|
d8beedf1f7 | ||
|
|
4d6a665e04 | ||
|
|
201e26e521 | ||
|
|
b7cb5c5873 | ||
|
|
5cb755b0e3 | ||
|
|
43da232557 | ||
|
|
06c74045be | ||
|
|
ad54e759f0 | ||
|
|
163726abae | ||
|
|
6a108866f5 | ||
|
|
608b2ec075 | ||
|
|
7682f02222 | ||
|
|
7c65484ada | ||
|
|
163732b87f | ||
|
|
dd2dc7312c | ||
|
|
586c8f8db9 | ||
|
|
0293b6dbd8 | ||
|
|
d62af2a007 | ||
|
|
6466a71c0a | ||
|
|
d2d9aae9ce | ||
|
|
362b32357f | ||
|
|
4b64269905 | ||
|
|
e25ce12e55 | ||
|
|
b76d4526de | ||
|
|
1affe3c093 | ||
|
|
57759d2775 | ||
|
|
6744ad1891 | ||
|
|
d378cfdb5f | ||
|
|
6d012144db | ||
|
|
d911447b43 | ||
|
|
0bd74b9df5 | ||
|
|
725d447ab3 | ||
|
|
413fef4c6f | ||
|
|
6c9c28bd28 | ||
|
|
331d97b48f | ||
|
|
cf860be1fc | ||
|
|
2ca3911d56 | ||
|
|
67a2912537 | ||
|
|
9119c16c49 | ||
|
|
7e56617044 | ||
|
|
d72bddbd9d | ||
|
|
de9a4dac08 | ||
|
|
9bada9e18e | ||
|
|
b87f50aedf | ||
|
|
04fdbfb187 | ||
|
|
9a1def21cc | ||
|
|
0b423f5828 | ||
|
|
e4988d806f | ||
|
|
e9fe27a59e | ||
|
|
e56f418696 | ||
|
|
bb85a172a2 | ||
|
|
4cf1c31d4f | ||
|
|
15fd832705 | ||
|
|
17dcd3fdb2 | ||
|
|
8aa46126c5 | ||
|
|
6c791afffc | ||
|
|
6c6e41495c | ||
|
|
a4488ec090 | ||
|
|
c75675129b | ||
|
|
ac968e21e6 | ||
|
|
ad1b3aeaac | ||
|
|
8c5decee34 | ||
|
|
bbbf24c2a5 | ||
|
|
936c74211f | ||
|
|
fdb5e3406e | ||
|
|
359184934e | ||
|
|
776c819509 | ||
|
|
1c4f6f4fb3 | ||
|
|
28d3a3dce3 | ||
|
|
fb4dc5af84 | ||
|
|
26358620eb | ||
|
|
105eca20b2 | ||
|
|
9e675e81ec | ||
|
|
86b22e7987 | ||
|
|
c39e0a2ed4 | ||
|
|
1cadd2b06b | ||
|
|
6b5d61414c | ||
|
|
3890eaf162 | ||
|
|
4b0badfb30 | ||
|
|
1861f4f71f | ||
|
|
3129319efe | ||
|
|
1392055d44 | ||
|
|
4119d8d5a8 | ||
|
|
5d494fa08e | ||
|
|
3a5b88d51c | ||
|
|
11ad1c2476 | ||
|
|
17443a3d4f | ||
|
|
9dc7405eaa | ||
|
|
cd6277c1a8 | ||
|
|
73dc5a9f70 | ||
|
|
4da7285f38 | ||
|
|
b96ebeed22 | ||
|
|
edfd0319a8 | ||
|
|
facc25eb74 | ||
|
|
b7f54c0366 | ||
|
|
9f7ea6f1cb | ||
|
|
aae02dc060 | ||
|
|
e6c173dcdc | ||
|
|
0923ed0f80 | ||
|
|
1ad844fe74 | ||
|
|
9fb4d5ccd4 | ||
|
|
463938bc88 | ||
|
|
9d25520dbf | ||
|
|
03bfa43378 | ||
|
|
b72d1059c0 | ||
|
|
fc81e842c2 | ||
|
|
53b220b10b | ||
|
|
5129ebec0c | ||
|
|
a41a39aa0b | ||
|
|
0aa17d6374 | ||
|
|
bced04ca88 | ||
|
|
6d0ed7cc99 | ||
|
|
336e10d445 | ||
|
|
5cf23f2bd3 | ||
|
|
fe845692bf | ||
|
|
7980b12239 | ||
|
|
9248ffd044 | ||
|
|
da96edf304 | ||
|
|
b11377041d | ||
|
|
fa01e18e41 | ||
|
|
1453b5e21d | ||
|
|
7e6908b7bf | ||
|
|
eb9c04c774 | ||
|
|
fdb7cd9ac4 | ||
|
|
5e42684f27 | ||
|
|
f8ef4bb570 | ||
|
|
b6822b040c | ||
|
|
7c05b62cf0 | ||
|
|
d2f3497d1e | ||
|
|
998e9bbb8e | ||
|
|
8c6bba62c9 | ||
|
|
0a6b3d5785 | ||
|
|
9f7457e1de | ||
|
|
6e9830705f | ||
|
|
b904540aed | ||
|
|
fc5aa33d16 | ||
|
|
1968b598a4 | ||
|
|
6ad547049e | ||
|
|
5d66b9fbfd | ||
|
|
404fc5b548 | ||
|
|
6fe1e2a55a | ||
|
|
6e14dfb6d5 | ||
|
|
ce3e96ef5b | ||
|
|
1e7e73f482 | ||
|
|
a5f63d1cc0 | ||
|
|
e4cb04fd3e | ||
|
|
472ce16528 | ||
|
|
1b7bf0ed4f | ||
|
|
9f380bc083 | ||
|
|
8671a59b4b | ||
|
|
e9e5a3e475 | ||
|
|
9ae5957473 | ||
|
|
3c25a9ba8d | ||
|
|
ec5fbc16b5 | ||
|
|
5531f7fa9e | ||
|
|
9137c89fb7 | ||
|
|
5c42604fa7 | ||
|
|
fecb2163ea | ||
|
|
3e44c7caf5 | ||
|
|
719a0e6107 | ||
|
|
cd1ec7a5d6 | ||
|
|
0aadbc0467 | ||
|
|
63d6ac59df | ||
|
|
2475bfa609 | ||
|
|
609aef0a87 | ||
|
|
0a16ffcd39 | ||
|
|
457a1df478 | ||
|
|
3c0dcb20ac | ||
|
|
07fbffab08 | ||
|
|
bd208c6d0d | ||
|
|
41e4285d65 | ||
|
|
cfacf52a42 | ||
|
|
17bc62d94b | ||
|
|
fa84adc536 | ||
|
|
35b12df144 | ||
|
|
ec20eb96df | ||
|
|
41b3d00fb2 | ||
|
|
671f6d9e16 | ||
|
|
f2293297ce | ||
|
|
0d0ecd90d3 | ||
|
|
9b55205f0f | ||
|
|
5122dad996 | ||
|
|
7178f8b02b | ||
|
|
9762193ce0 | ||
|
|
2746a0ef03 | ||
|
|
ea77980bff | ||
|
|
bde97b3ec8 | ||
|
|
becab02bce | ||
|
|
fc2d5e89f0 | ||
|
|
31dd09e09b | ||
|
|
c83a46c726 | ||
|
|
20baece7c5 | ||
|
|
92b88bed20 | ||
|
|
45b498924c | ||
|
|
fc7735ab03 | ||
|
|
e07ee6a505 | ||
|
|
e0fdb7ed80 | ||
|
|
cbb562add2 | ||
|
|
7e8f0e1dc1 | ||
|
|
139100db35 | ||
|
|
19629cb05c | ||
|
|
87c55582b6 | ||
|
|
4c60b0f624 | ||
|
|
a56984a1a0 | ||
|
|
2a858b3f23 | ||
|
|
5312dba499 | ||
|
|
f7664616ec | ||
|
|
fdb826a8c4 | ||
|
|
53060397e5 | ||
|
|
349000bd8a | ||
|
|
358a9fc867 | ||
|
|
4b5d883c69 | ||
|
|
498f8a06b8 | ||
|
|
2171efcb7a | ||
|
|
ffd212da14 | ||
|
|
b210888dac | ||
|
|
3b4fbce6f6 | ||
|
|
c80b3e1c61 | ||
|
|
8fcc24db71 | ||
|
|
d78c871855 | ||
|
|
3cf018ac47 | ||
|
|
c3f2f41888 | ||
|
|
d94b1d921e | ||
|
|
4e17bb7a8c | ||
|
|
601fd10f4e | ||
|
|
ac765e4667 | ||
|
|
3451a70fe4 | ||
|
|
57fcd87ad4 | ||
|
|
f7ea83091c | ||
|
|
d9498964a0 | ||
|
|
16e6042c9c | ||
|
|
c11a9e000d | ||
|
|
a02a0c2a0b | ||
|
|
eca4b4ffb8 | ||
|
|
18764d5caf | ||
|
|
76560ca458 | ||
|
|
f207213474 | ||
|
|
9eb21137f6 | ||
|
|
488af06663 | ||
|
|
de711b82dd | ||
|
|
408774b14c | ||
|
|
e2f6bf283c | ||
|
|
c2f895c1d4 | ||
|
|
2adc096eeb | ||
|
|
b37f984eb6 | ||
|
|
130f749a48 | ||
|
|
e7a22e4e41 | ||
|
|
c568c08595 | ||
|
|
9caed90aee | ||
|
|
d5d96fa777 | ||
|
|
7e088348e0 | ||
|
|
c9142ca69b | ||
|
|
2dab5e0fe7 | ||
|
|
e7439c1616 | ||
|
|
4624665726 | ||
|
|
8cf32f4470 | ||
|
|
4c55da7229 | ||
|
|
48c49ddb74 | ||
|
|
9dfb2196e5 | ||
|
|
e09ebcaff9 | ||
|
|
bb95a120b1 | ||
|
|
46ad34548f | ||
|
|
3b9ae1d807 | ||
|
|
0cd45e275e | ||
|
|
873d14aac6 | ||
|
|
6f011da3ae | ||
|
|
2b03d3bfd7 | ||
|
|
af7b64a398 | ||
|
|
6e82c4904f | ||
|
|
a090ecb1a5 | ||
|
|
a745c52bd5 | ||
|
|
c9f8ca6771 | ||
|
|
10e2aa873c | ||
|
|
0eecaf4268 | ||
|
|
1f9c31da41 | ||
|
|
5fb73ce2cb | ||
|
|
2b9c9ce203 | ||
|
|
225a42be8a | ||
|
|
8042b6aa53 | ||
|
|
d01e9ffcfe | ||
|
|
cde401a078 | ||
|
|
ee237c3c2e | ||
|
|
0dca4b8906 | ||
|
|
e81bf14d91 | ||
|
|
d330472158 | ||
|
|
0d759ddd4e | ||
|
|
638e9ff535 | ||
|
|
3785cdb675 | ||
|
|
4ed63cc362 | ||
|
|
01d68ce3d5 | ||
|
|
8139d525cb | ||
|
|
34d09bc575 | ||
|
|
b88575b2a5 | ||
|
|
1cf3157089 | ||
|
|
ce2142add4 | ||
|
|
d1de7b67b9 | ||
|
|
9aa673448a | ||
|
|
9cfddaf2ab | ||
|
|
ae5d23f77d | ||
|
|
9f808dafde | ||
|
|
bb0989f6bd | ||
|
|
b177fe1dcf | ||
|
|
2948bb8a6b | ||
|
|
19d3a34bcc | ||
|
|
83d93464bc | ||
|
|
3b5be5cf97 | ||
|
|
7a3e09adb0 | ||
|
|
1ac0182867 | ||
|
|
fa084ec8d2 | ||
|
|
61a50577fa | ||
|
|
11e3cd63e0 | ||
|
|
0c47ec477d | ||
|
|
d9b007c1af | ||
|
|
c77fa6e5c4 | ||
|
|
fb16c4b65a | ||
|
|
e2ddb9388a | ||
|
|
a1311dca4c | ||
|
|
cf4fd0601f | ||
|
|
935e9f0bc8 | ||
|
|
031994f9b5 | ||
|
|
96701fad8e | ||
|
|
94e566bb89 | ||
|
|
1d3bcfc2ef | ||
|
|
c9b1e34035 | ||
|
|
910d846c21 | ||
|
|
62bcce369f | ||
|
|
ee319badc8 | ||
|
|
714c0ddead | ||
|
|
d27671ac3d | ||
|
|
4264ee763f | ||
|
|
2439055f01 | ||
|
|
ffd0f25e13 | ||
|
|
45bd6ece05 | ||
|
|
984f6c5cac | ||
|
|
cd102b7c2e | ||
|
|
d83c8051f6 | ||
|
|
2ffc7e2d2b | ||
|
|
4a3acd10e7 | ||
|
|
ea2a18c647 | ||
|
|
3b035aa204 | ||
|
|
3b1250afa7 | ||
|
|
2f07036940 | ||
|
|
db3f19770b | ||
|
|
570ca69c2f | ||
|
|
4ba4e38c1f | ||
|
|
16496d4a9c | ||
|
|
f88f19da71 | ||
|
|
8237825b4b | ||
|
|
7a05f13539 | ||
|
|
05ba84db37 | ||
|
|
95c4fe170b | ||
|
|
a7ad0cbecd | ||
|
|
3b1efdb9ad | ||
|
|
923f0e05fc | ||
|
|
c981bc7daa | ||
|
|
fc6c9f6d57 | ||
|
|
bca943bf34 | ||
|
|
49366ea5ab | ||
|
|
44dfb86230 | ||
|
|
f36e5ecef4 | ||
|
|
afcb1641b7 | ||
|
|
54455213a8 | ||
|
|
dda468291a | ||
|
|
3d7756f177 | ||
|
|
c5037c5725 | ||
|
|
bef7a2da25 | ||
|
|
12f4209055 | ||
|
|
76ff5da718 | ||
|
|
19bdcad78e | ||
|
|
6efdccfef0 | ||
|
|
97676f01a2 | ||
|
|
affefb44b4 | ||
|
|
62dea44922 | ||
|
|
da5c821de3 | ||
|
|
b2597df44c | ||
|
|
c8f6f6adf0 | ||
|
|
83edcaf955 | ||
|
|
2359af5fbb | ||
|
|
e3ddea07b9 | ||
|
|
953307cbc7 | ||
|
|
f303066039 | ||
|
|
22e38b6f2a | ||
|
|
68f5e73bff | ||
|
|
086d5b39f3 | ||
|
|
97d17da8c0 | ||
|
|
4d04cdd65f | ||
|
|
7d9013cb2d | ||
|
|
d996ff29cb | ||
|
|
51b776354a | ||
|
|
d51d1b458a | ||
|
|
7f44d379f5 | ||
|
|
69b3e9db52 | ||
|
|
faac1d6a10 | ||
|
|
2f5fd8e3d0 | ||
|
|
972f0e81f4 | ||
|
|
1e85edfef4 | ||
|
|
50e6739bad | ||
|
|
2322682014 | ||
|
|
16f438dea2 | ||
|
|
6ffec444d6 | ||
|
|
4e9731c59b | ||
|
|
4f3a845702 | ||
|
|
a3af051d43 | ||
|
|
f9f127e227 | ||
|
|
79a4414a13 | ||
|
|
96c4b57b18 | ||
|
|
98ad6f3db0 | ||
|
|
9cbbe111a7 | ||
|
|
258c95f02e | ||
|
|
fbd7465b03 | ||
|
|
e6472d525d | ||
|
|
fda45dd363 | ||
|
|
07e372a787 | ||
|
|
b9c088314b | ||
|
|
b72432a39e | ||
|
|
cb26c8cf33 | ||
|
|
611237ec86 | ||
|
|
3a4e9d9107 | ||
|
|
06420fa4b0 | ||
|
|
b57fc1f34d | ||
|
|
b5e07c9245 | ||
|
|
c6c6a1b4cf | ||
|
|
8cdb30fd25 | ||
|
|
91041bd7a9 | ||
|
|
f813780e15 | ||
|
|
bc53f544f4 | ||
|
|
d29176158b | ||
|
|
20fc9138e2 | ||
|
|
18857aca46 | ||
|
|
8fc24219fb | ||
|
|
38a2fb4ca1 | ||
|
|
a04b1d5803 | ||
|
|
06e7dcd471 | ||
|
|
d4dae9fd32 | ||
|
|
e3a10067f5 | ||
|
|
09dd7eca58 | ||
|
|
126f2254f6 | ||
|
|
64c7eb28b3 | ||
|
|
5e97358e90 | ||
|
|
eb838cdb9f | ||
|
|
983dad87af | ||
|
|
87853f0da4 | ||
|
|
e8e89f1c7e | ||
|
|
f6be7cdf23 | ||
|
|
7937e880c0 | ||
|
|
c52b5b5118 | ||
|
|
e47e80c69c | ||
|
|
6208569c7e | ||
|
|
1a41c6a360 | ||
|
|
38d52e4df0 | ||
|
|
1f56a8da8c | ||
|
|
4ad0d62f42 | ||
|
|
0bd5bbec77 | ||
|
|
340792cfc2 | ||
|
|
a817c8ae0a | ||
|
|
c124c08f89 | ||
|
|
d2565009d8 | ||
|
|
b38a5ca47a | ||
|
|
f32bba31b5 | ||
|
|
4b8f505625 | ||
|
|
4433edc552 | ||
|
|
019f93d98b | ||
|
|
98ebe1ff96 | ||
|
|
69c1af586e | ||
|
|
2df8645c5f | ||
|
|
f6b9ef16d0 | ||
|
|
399cc38eb9 | ||
|
|
652702f582 | ||
|
|
4913ffe114 | ||
|
|
668cd8d0f9 | ||
|
|
05a1dd561c | ||
|
|
5f0c9c282c | ||
|
|
de825f54e7 | ||
|
|
940a899231 | ||
|
|
70938f7b41 | ||
|
|
d510ab031d | ||
|
|
9c39f62b1e | ||
|
|
e175a96acb | ||
|
|
71a8dce949 | ||
|
|
747706e032 | ||
|
|
2a679ca2eb | ||
|
|
1f1b9c47ec | ||
|
|
ceac184c30 | ||
|
|
f9803cb4f5 | ||
|
|
626667b3fd | ||
|
|
bf2c6bfa1f | ||
|
|
5588c1e22e | ||
|
|
525fb7dcf9 | ||
|
|
e182c9d9f6 | ||
|
|
af69e83bda | ||
|
|
76639f6da1 | ||
|
|
01f59cc247 | ||
|
|
6f6f4354fd | ||
|
|
d7df291b9a | ||
|
|
1a1266a20c | ||
|
|
f366757476 | ||
|
|
741843586d | ||
|
|
fafdfd9afd | ||
|
|
a156ad8087 | ||
|
|
b36a03c4bc | ||
|
|
028bdb074b | ||
|
|
643ceb25b5 | ||
|
|
5f8eface28 | ||
|
|
8a5177f14c | ||
|
|
02c8a89bbe | ||
|
|
c67acaa6ec | ||
|
|
4bbacf6923 | ||
|
|
38ea682c88 | ||
|
|
0f1208d4d9 | ||
|
|
69942283e5 | ||
|
|
d13e034940 | ||
|
|
72059184df | ||
|
|
4d9dc0111e | ||
|
|
b9262230d1 | ||
|
|
df4cea3228 | ||
|
|
0f27348924 | ||
|
|
dd5aa1e241 | ||
|
|
5df62610d2 | ||
|
|
9dcbef988a | ||
|
|
d1a973564f | ||
|
|
da52ff99c1 | ||
|
|
ee07676193 | ||
|
|
007598df6a | ||
|
|
9a71bbc620 | ||
|
|
a5041a3a41 | ||
|
|
36d3717bd6 | ||
|
|
abd63731be | ||
|
|
b7c0e32cd0 | ||
|
|
c512d7167d | ||
|
|
6ccfc8ba7d | ||
|
|
b27d3c04c9 | ||
|
|
aa3948b9a2 | ||
|
|
75fa1a8167 | ||
|
|
c414922167 | ||
|
|
38ecacc62f | ||
|
|
cc05f9b2df | ||
|
|
d7d2c8cb35 | ||
|
|
ea394a00b5 | ||
|
|
49b1eb3150 | ||
|
|
4a216f0a7c | ||
|
|
674dd90221 | ||
|
|
2436cf5da5 | ||
|
|
9cd42e0614 | ||
|
|
a6fa6c9cd6 | ||
|
|
4403a6775a | ||
|
|
dfbab194de | ||
|
|
fe2787217f | ||
|
|
554f2b32db | ||
|
|
36f825d0fe | ||
|
|
04b6ba21f7 | ||
|
|
ff63adecdc | ||
|
|
6c29faeba1 | ||
|
|
517f67a3a9 | ||
|
|
7f37ebf87e | ||
|
|
f0af6f8927 | ||
|
|
d78c4dec67 | ||
|
|
0831089790 | ||
|
|
8faf1285da | ||
|
|
d5b278217b | ||
|
|
a04101d756 | ||
|
|
3cb41c9fe3 | ||
|
|
2ab9404229 | ||
|
|
6cef7a124e | ||
|
|
f226c774df | ||
|
|
06a1f1a869 | ||
|
|
44dc300c63 | ||
|
|
edaa936766 | ||
|
|
6d9a53edba | ||
|
|
1d9a7eced3 | ||
|
|
f9971aabb6 | ||
|
|
1fe26afe4f | ||
|
|
6d547048c4 | ||
|
|
687b68f13e | ||
|
|
c49728e2fc | ||
|
|
a201d18938 | ||
|
|
d433866e39 | ||
|
|
45da78bbde | ||
|
|
c9238877fa | ||
|
|
d4f456d868 | ||
|
|
2833b7598e | ||
|
|
68c4c1cc56 | ||
|
|
bc8673d883 | ||
|
|
6b76e28ebb | ||
|
|
f2e02e4e06 | ||
|
|
2b257d21fb | ||
|
|
92bfd903dc | ||
|
|
69fedb3712 | ||
|
|
c4df1f3671 | ||
|
|
0cd7af7c4f | ||
|
|
c675a73fc6 | ||
|
|
7b09961075 | ||
|
|
d96fafa92f | ||
|
|
20daecf4b1 | ||
|
|
c0a048251e | ||
|
|
99c92e68a6 | ||
|
|
af5d39a394 | ||
|
|
fc74708bf5 | ||
|
|
0dce125f67 | ||
|
|
d3b87189e3 | ||
|
|
4a68ab13e1 | ||
|
|
0c1f67f391 | ||
|
|
fd87c59492 | ||
|
|
af2736e462 | ||
|
|
d7ff9bed1a | ||
|
|
e5e3b89c6d | ||
|
|
67bfe560c4 | ||
|
|
d04fec09d5 | ||
|
|
e814f8835a | ||
|
|
7769334372 | ||
|
|
959f7da876 | ||
|
|
a9902219ae | ||
|
|
3cb9aaa055 | ||
|
|
831dc7a0b8 | ||
|
|
75cf2997b8 | ||
|
|
abdf2a23d0 | ||
|
|
deb4a501d6 | ||
|
|
80d7079953 | ||
|
|
fcf303b2b3 | ||
|
|
932ead0d3c | ||
|
|
03146d9e3b | ||
|
|
45c0163a9d | ||
|
|
56826ab3c1 | ||
|
|
55d6237f93 | ||
|
|
349da7e7ad | ||
|
|
5f0028a983 | ||
|
|
1aa5c72db3 | ||
|
|
fc20b74b57 | ||
|
|
7236902143 | ||
|
|
cf92544600 | ||
|
|
ab87b30423 | ||
|
|
0ad30370ae | ||
|
|
30223c38e1 | ||
|
|
967ba99c12 | ||
|
|
d2a11cdb91 | ||
|
|
bb966feb8a | ||
|
|
ebaec8de26 | ||
|
|
ee4297e22c | ||
|
|
aae36bce00 | ||
|
|
4a7e0af9a2 | ||
|
|
808943f250 | ||
|
|
f19e7142cd | ||
|
|
82a3f9a3e2 | ||
|
|
66a5a159d8 | ||
|
|
a5107445f0 | ||
|
|
c99ef3f315 | ||
|
|
cd5094d389 | ||
|
|
d1a596b0be | ||
|
|
a97929f239 | ||
|
|
444ba37eb1 | ||
|
|
52487a4a78 | ||
|
|
b6adf916c4 | ||
|
|
f92082270d | ||
|
|
4667282966 | ||
|
|
5546700fee | ||
|
|
644a159d0a | ||
|
|
3156ce217b | ||
|
|
7c10a9a63a | ||
|
|
fc3aac58b5 | ||
|
|
d788320a9d | ||
|
|
0f4d5e8f1b | ||
|
|
c5ab15ca64 | ||
|
|
42312bcc20 | ||
|
|
d69a3c6130 | ||
|
|
d003239525 | ||
|
|
45cb6bc4f7 | ||
|
|
b361d78051 | ||
|
|
8438942b10 | ||
|
|
2be22d8e48 | ||
|
|
1be861cd8d | ||
|
|
e0745b5109 | ||
|
|
792f6c4154 | ||
|
|
23b086fbc2 | ||
|
|
e35bd81c8b | ||
|
|
3f12930223 | ||
|
|
5fad0e13e8 | ||
|
|
715eac28c8 | ||
|
|
d31e1cef8f | ||
|
|
9cd31c761a | ||
|
|
e99b9cbe41 | ||
|
|
2f1d0fd4f7 | ||
|
|
2aae378808 | ||
|
|
29cdb8103f | ||
|
|
2da08769b2 | ||
|
|
7a85d70139 | ||
|
|
e78d5ba461 | ||
|
|
5aefa2a116 | ||
|
|
32cbf109a4 | ||
|
|
d15f341f90 | ||
|
|
b6d57a8f0e | ||
|
|
c48252790e | ||
|
|
5c95e02eac | ||
|
|
b1b125d2a4 | ||
|
|
634e626717 | ||
|
|
eee87c7bc2 | ||
|
|
c6855712d0 | ||
|
|
b27d94e316 | ||
|
|
ca8b5a75ea | ||
|
|
cb5a4c774c | ||
|
|
7e269f1256 | ||
|
|
f9c882bf24 | ||
|
|
f6356dd9e6 | ||
|
|
d5e0230b19 | ||
|
|
1b0bcf4e0b | ||
|
|
7180e7e9ed | ||
|
|
09831faaf4 | ||
|
|
a5e66eabed | ||
|
|
25f8a34b23 | ||
|
|
eb0cf07f4a | ||
|
|
375f6860aa | ||
|
|
79f0961e09 | ||
|
|
9ddccc6592 | ||
|
|
6606535fa9 | ||
|
|
2ea14273b8 | ||
|
|
445222bcdd | ||
|
|
40ddfdc2ab | ||
|
|
345d2d95d8 | ||
|
|
8a22f1c889 | ||
|
|
8d47faadd7 | ||
|
|
d07ed0c09f | ||
|
|
24b4c98d94 | ||
|
|
ea6fffc525 | ||
|
|
a0b422be34 | ||
|
|
6599ea6678 | ||
|
|
36cf19b1b9 | ||
|
|
9d056b2765 | ||
|
|
5c16c2a21a | ||
|
|
acd9beae73 | ||
|
|
e598817287 | ||
|
|
35d53e2fae | ||
|
|
fa3d77299e | ||
|
|
48a16d65e1 | ||
|
|
89f126ab04 | ||
|
|
67d9ca1e41 | ||
|
|
8f9d80a809 | ||
|
|
8698026e86 | ||
|
|
ec5d0ab4f7 | ||
|
|
3425920cb6 | ||
|
|
85c6da4346 | ||
|
|
93460daadf | ||
|
|
574548f360 | ||
|
|
847c4a67c9 | ||
|
|
8aab154a9f | ||
|
|
a3119d1993 | ||
|
|
0a159c803f | ||
|
|
22a7231d8f | ||
|
|
c36f6b603d | ||
|
|
05ff49616d | ||
|
|
342b889371 | ||
|
|
8e5b8712c0 | ||
|
|
f063aa16a8 | ||
|
|
2520970698 | ||
|
|
a21a825aac | ||
|
|
d66829d62d | ||
|
|
f52c5b0843 | ||
|
|
d48dc8b87b | ||
|
|
8f72756737 | ||
|
|
4fd7948987 | ||
|
|
e76833d364 | ||
|
|
3cb0094dde | ||
|
|
946c50b222 | ||
|
|
1dccee389d | ||
|
|
875c0b31b7 | ||
|
|
8bf77e27dc | ||
|
|
a51352017a | ||
|
|
68b28a17e4 | ||
|
|
463af45e73 | ||
|
|
4ccab6b8b5 | ||
|
|
1849ee807c | ||
|
|
bd7b4a1c14 | ||
|
|
c20520c877 | ||
|
|
35aec3c34f | ||
|
|
d9e18551b5 | ||
|
|
144da1ed6b | ||
|
|
125ffe9f73 | ||
|
|
a94f32dc50 | ||
|
|
8c338fc223 | ||
|
|
ca764a3165 | ||
|
|
b58547f988 | ||
|
|
05fbe8b218 | ||
|
|
823f8f0be3 | ||
|
|
b40b06a18e | ||
|
|
513250cadf | ||
|
|
216432f4b6 | ||
|
|
2b5825f841 | ||
|
|
46987845b3 | ||
|
|
e1cead8241 | ||
|
|
63f72b046d | ||
|
|
3fe39bbf73 | ||
|
|
81646a00ff | ||
|
|
8edd6a2e49 | ||
|
|
4cc3eadb97 | ||
|
|
4b9d5113d3 | ||
|
|
206751de0e | ||
|
|
4dd3c64e9d | ||
|
|
b400393a90 | ||
|
|
1f9cb92697 | ||
|
|
59fe366479 | ||
|
|
8eba67ceb8 | ||
|
|
1148ef1595 | ||
|
|
bcbdee3a50 | ||
|
|
cfbb700f0c | ||
|
|
95f6738d5b | ||
|
|
0cde54e985 | ||
|
|
a3d3cfad61 | ||
|
|
b89e9c56cc | ||
|
|
192955b33d | ||
|
|
195c8a0601 | ||
|
|
9048d68baf | ||
|
|
2b70762b7a | ||
|
|
de2d034377 | ||
|
|
f941a45d13 | ||
|
|
4280e05679 | ||
|
|
830f714a44 | ||
|
|
f8c9acd88f | ||
|
|
d67f08d842 | ||
|
|
72fc36c8f5 | ||
|
|
3c22f9069b | ||
|
|
c2eaf88d74 | ||
|
|
b72d620b15 | ||
|
|
dce413631c | ||
|
|
5468127e2f | ||
|
|
d66e6ab6ef | ||
|
|
a3929d2c6f | ||
|
|
b5cc1542b6 | ||
|
|
1a77960daa | ||
|
|
301fbf4427 | ||
|
|
2f0666325f | ||
|
|
d0c765ce20 | ||
|
|
a1ad99cc0d | ||
|
|
2d0b20499e | ||
|
|
5b01e60ed2 | ||
|
|
26ff81ab71 | ||
|
|
da3349765a | ||
|
|
b470fbfb3d | ||
|
|
1f86842757 | ||
|
|
de47b11880 | ||
|
|
6b2b3969ec | ||
|
|
14c5a0823b | ||
|
|
98b5c8da28 | ||
|
|
cd7060afed | ||
|
|
0787264f71 | ||
|
|
347609d20c | ||
|
|
0340dc7ffc | ||
|
|
d8057830c6 | ||
|
|
4ddde65b41 |
7
.bowerrc
Normal file
7
.bowerrc
Normal file
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"directory": "public/bower_components",
|
||||
"scripts": {
|
||||
"postinstall": "grunt default genlicense",
|
||||
"postuninstall": "grunt default genlicense"
|
||||
}
|
||||
}
|
||||
19
.dockerignore
Normal file
19
.dockerignore
Normal file
@@ -0,0 +1,19 @@
|
||||
node_modules
|
||||
tmp
|
||||
application/config/email.php
|
||||
*.patch
|
||||
patches/
|
||||
.idea/
|
||||
git-svn-diff.py
|
||||
*.bash
|
||||
.swp
|
||||
.buildpath
|
||||
.project
|
||||
.settings/*
|
||||
*.swp
|
||||
*.rej
|
||||
*.orig
|
||||
*~
|
||||
*.~
|
||||
*.log
|
||||
application/sessions/*
|
||||
2
.gitattributes
vendored
2
.gitattributes
vendored
@@ -1,3 +1,5 @@
|
||||
dist/ merge=ours
|
||||
application/language/**/*.php merge=ours
|
||||
text=auto
|
||||
application/config/config.php ident
|
||||
application/views/partial/footer.php ident
|
||||
|
||||
29
.github/ISSUE_TEMPLATE.md
vendored
Normal file
29
.github/ISSUE_TEMPLATE.md
vendored
Normal file
@@ -0,0 +1,29 @@
|
||||
### Background information
|
||||
|
||||
__IMPORTANT: If you choose to ignore this issue report template, your issue will be closed as we cannot help without the requested information.__
|
||||
|
||||
Please make sure you tick (add an x between the square brackets with no spaces) the following check boxes:
|
||||
|
||||
- [] Reporting an issue of an unmodified OSPOS installation
|
||||
- [] Checked [open and closed issues](https://github.com/opensourcepos/opensourcepos/issues?utf8=%E2%9C%93&q=is%3Aissue) and no similar issue was already reported (please make sure you searched!)
|
||||
- [] Read [README](https://github.com/opensourcepos/opensourcepos/blob/master/README.md), [WHATS_NEW](https://github.com/opensourcepos/opensourcepos/blob/master/WHATS_NEW.txt), [INSTALL.md](https://github.com/opensourcepos/opensourcepos/blob/master/INSTALL.md) and [UPGRADE](https://github.com/opensourcepos/opensourcepos/blob/master/UPGRADE.txt)
|
||||
- [] Read the [FAQ](https://github.com/opensourcepos/opensourcepos#faq) for any known install and/or upgrade gotchas (in specific PHP extensions installed)
|
||||
- [] Read the [wiki](https://github.com/opensourcepos/opensourcepos/wiki)
|
||||
- [] Executed any database upgrade scripts if an upgrade pre 3.0.0 (e.g. database/2.4_to_3.0.sql)
|
||||
- [] Aware the installation code is in [bintray](https://bintray.com/jekkos/opensourcepos/opensourcepos/view/files?sort=updated&order=asc#files) (see README), and [GitHub master](https://github.com/opensourcepos/opensourcepos/tree/master) is for [developers only](https://github.com/opensourcepos/opensourcepos/wiki/Development-setup) and therefore not complete nor stable
|
||||
|
||||
### Installation information
|
||||
|
||||
- OSPOS version is:
|
||||
- OSPOS git commit hash is:
|
||||
- PHP version is:
|
||||
- MySQL or MariaDB version is:
|
||||
- OS and version is:
|
||||
- WebServer is:
|
||||
- Selected language is:
|
||||
- (If applicable) Docker installation:
|
||||
- (If applicable) Installation package for the LAMP/LEMP stack is:
|
||||
|
||||
### Issue / Bug / Question / New Feature
|
||||
|
||||
Please write your issue here. If a bug, please make sure to provide as much information as possible including configuration settings (e.g. Decimals set, Tax mode), language and steps to reproduce the bug.
|
||||
14
.gitignore
vendored
14
.gitignore
vendored
@@ -1,7 +1,15 @@
|
||||
node_modules
|
||||
bower_components
|
||||
tmp
|
||||
application/config/email.php
|
||||
application/config/database.php
|
||||
application/sessions/*
|
||||
application/logs/*
|
||||
application/uploads/*
|
||||
public/license/.licenses
|
||||
public/license/bower.LICENSES
|
||||
public/dist
|
||||
dist/
|
||||
docs/
|
||||
public/bower_components
|
||||
*.patch
|
||||
patches/
|
||||
.idea/
|
||||
@@ -11,9 +19,11 @@ git-svn-diff.py
|
||||
.buildpath
|
||||
.project
|
||||
.settings/*
|
||||
vendor/
|
||||
*.swp
|
||||
*.rej
|
||||
*.orig
|
||||
*~
|
||||
*.~
|
||||
*.log
|
||||
.env
|
||||
|
||||
67
.htaccess
Executable file
67
.htaccess
Executable file
@@ -0,0 +1,67 @@
|
||||
# redirect to public page
|
||||
<IfModule mod_rewrite.c>
|
||||
RewriteEngine On
|
||||
RewriteCond %{REQUEST_URI} !^public$
|
||||
RewriteRule ^(.*)$ %{REQUEST_URI}public/ [R=301,L]
|
||||
</IfModule>
|
||||
|
||||
# disable directory browsing
|
||||
# For security reasons, Option all cannot be overridden.
|
||||
Options +ExecCGI +Includes +IncludesNOEXEC +SymLinksIfOwnerMatch -Indexes
|
||||
|
||||
# prevent folder listing
|
||||
IndexIgnore *
|
||||
|
||||
# Apache 2.4
|
||||
<IfModule authz_core_module>
|
||||
# secure htaccess file
|
||||
<Files .htaccess>
|
||||
Require all denied
|
||||
</Files>
|
||||
|
||||
# prevent access to PHP error log
|
||||
<Files error_log>
|
||||
Require all denied
|
||||
</Files>
|
||||
|
||||
# prevent access to LICENSE
|
||||
<Files LICENSE>
|
||||
Require all denied
|
||||
</Files>
|
||||
|
||||
# prevent access to csv, txt and md files
|
||||
<FilesMatch "\.(csv|txt|md|yml|json|lock)$">
|
||||
Require all denied
|
||||
</FilesMatch>
|
||||
</IfModule>
|
||||
|
||||
# Apache 2.2
|
||||
<IfModule !authz_core_module>
|
||||
# secure htaccess file
|
||||
<Files .htaccess>
|
||||
Order allow,deny
|
||||
Deny from all
|
||||
Satisfy all
|
||||
</Files>
|
||||
|
||||
# prevent access to PHP error log
|
||||
<Files error_log>
|
||||
Order allow,deny
|
||||
Deny from all
|
||||
Satisfy all
|
||||
</Files>
|
||||
|
||||
# prevent access to LICENSE
|
||||
<Files LICENSE>
|
||||
Order allow,deny
|
||||
Deny from all
|
||||
Satisfy all
|
||||
</Files>
|
||||
|
||||
# prevent access to csv, txt and md files
|
||||
<FilesMatch "\.(csv|txt|md|yml|json|lock)$">
|
||||
Order allow,deny
|
||||
Deny from all
|
||||
Satisfy all
|
||||
</FilesMatch>
|
||||
</IfModule>
|
||||
61
.travis.yml
61
.travis.yml
@@ -1,22 +1,39 @@
|
||||
language: php
|
||||
php:
|
||||
- 5.5
|
||||
install: npm install
|
||||
before_script:
|
||||
- npm update -g npm
|
||||
- npm install grunt-cli
|
||||
- sudo apt-get update
|
||||
- sudo apt-get install apache2 libapache2-mod-fastcgi
|
||||
# enable php-fpm
|
||||
- sudo cp ~/.phpenv/versions/$(phpenv version-name)/etc/php-fpm.conf.default ~/.phpenv/versions/$(phpenv version-name)/etc/php-fpm.conf
|
||||
- sudo a2enmod rewrite actions fastcgi alias
|
||||
- echo "cgi.fix_pathinfo = 1" >> ~/.phpenv/versions/$(phpenv version-name)/etc/php.ini
|
||||
- ~/.phpenv/versions/$(phpenv version-name)/sbin/php-fpm
|
||||
# configure apache virtual hosts
|
||||
- sudo cp -f travis-ci-apache /etc/apache2/sites-available/default
|
||||
- sudo sed -e "s?%TRAVIS_BUILD_DIR%?$(pwd)?g" --in-place /etc/apache2/sites-available/default
|
||||
- sudo service apache2 restart
|
||||
- mysql -e "create database IF NOT EXISTS ospos;" -uroot
|
||||
- mysql -e "use ospos; source database/database.sql;" -uroot
|
||||
- cp application/config/database.php.tmpl application/config/database.php
|
||||
script: grunt mochaWebdriver:test
|
||||
sudo: required
|
||||
dist: trusty
|
||||
group: deprecated-2017Q4
|
||||
branches:
|
||||
except:
|
||||
- weblate
|
||||
services:
|
||||
- docker
|
||||
before_install:
|
||||
- curl -L https://github.com/docker/compose/releases/download/1.7.1/docker-compose-`uname
|
||||
-s`-`uname -m` > docker-compose
|
||||
- chmod +x docker-compose
|
||||
- sudo mv docker-compose /usr/local/bin
|
||||
- date=`date +%Y%m%d%H%M%S` && branch=${TRAVIS_BRANCH} && rev=`git rev-parse --short=6
|
||||
HEAD` && sed -i "s/\$1/\$1.$date.$branch.$rev/g" deployment.json
|
||||
script:
|
||||
- docker run --rm -v $(pwd):/app composer/composer install
|
||||
- docker run --rm -v $(pwd):/app -w /app lucor/php7-cli php bin/install.php translations
|
||||
develop
|
||||
- docker run --rm -it -v $(pwd):/app -w /app digitallyseamless/nodejs-bower-grunt
|
||||
sh -c "npm install && bower install && grunt package"
|
||||
- docker-compose build
|
||||
env:
|
||||
- TAG=$(echo ${TRAVIS_BRANCH} | sed s/feature\\///)
|
||||
after_success: '[ -n ${DOCKER_USERNAME} ] && docker login -u="$DOCKER_USERNAME" -p="$DOCKER_PASSWORD"
|
||||
&& docker tag opensourcepos_php "jekkos/opensourcepos:$TAG" && docker tag opensourcepos_sqlscript
|
||||
jekkos/opensourcepos:sqlscript && docker push "jekkos/opensourcepos:$TAG" && docker
|
||||
push jekkos/opensourcepos:sqlscript'
|
||||
deploy:
|
||||
edge:
|
||||
source: travis-ci/dpl
|
||||
branch: master
|
||||
file: deployment.json
|
||||
provider: bintray
|
||||
skip_cleanup: true
|
||||
key: ${BINTRAY_API_KEY}
|
||||
user: jekkos
|
||||
on:
|
||||
all_branches: true
|
||||
|
||||
35
.travis.yml.
Normal file
35
.travis.yml.
Normal file
@@ -0,0 +1,35 @@
|
||||
sudo: required
|
||||
dist: trusty
|
||||
group: deprecated-2017Q4
|
||||
branches:
|
||||
except:
|
||||
- weblate
|
||||
services:
|
||||
- docker
|
||||
before_install:
|
||||
- curl -L https://github.com/docker/compose/releases/download/1.7.1/docker-compose-`uname
|
||||
-s`-`uname -m` > docker-compose
|
||||
- chmod +x docker-compose
|
||||
- sudo mv docker-compose /usr/local/bin
|
||||
- date=`date +%Y%m%d%H%M%S` && branch=${TRAVIS_BRANCH} && rev=`git rev-parse --short=6
|
||||
HEAD` && sed -i "s/\$1/\$1.$date.$branch.$rev/g" deployment.json
|
||||
script:
|
||||
- docker run --rm -v $(pwd):/app composer/composer install
|
||||
- docker run --rm -v $(pwd):/app -w /app lucor/php7-cli php bin/install.php translations
|
||||
develop
|
||||
- docker run --rm -it -v $(pwd):/app -w /app digitallyseamless/nodejs-bower-grunt
|
||||
sh -c "npm install && bower install && grunt package"
|
||||
- docker-compose build
|
||||
env:
|
||||
- TAG=$(echo ${TRAVIS_BRANCH} | sed s/feature\\///)
|
||||
after_success: '[ -n ${DOCKER_USERNAME} ] && docker login -u="$DOCKER_USERNAME" -p="$DOCKER_PASSWORD"
|
||||
&& docker tag opensourcepos_php "jekkos/opensourcepos:$TAG" && docker tag opensourcepos_sqlscript
|
||||
jekkos/opensourcepos:sqlscript && docker push "jekkos/opensourcepos:$TAG" && docker
|
||||
push jekkos/opensourcepos:sqlscript'
|
||||
deploy:
|
||||
provider: bintray
|
||||
file: deployment.json
|
||||
user: jekkos
|
||||
on:
|
||||
all_branches: true
|
||||
key: ${BINTRAY_API_KEY}
|
||||
18
Dockerfile
Normal file
18
Dockerfile
Normal file
@@ -0,0 +1,18 @@
|
||||
FROM php:7.0.29-apache
|
||||
MAINTAINER jekkos
|
||||
RUN apt-get update && DEBIAN_FRONTEND=noninteractive apt-get install -y \
|
||||
libicu-dev \
|
||||
libgd-dev \
|
||||
openssl
|
||||
|
||||
RUN a2enmod rewrite
|
||||
RUN docker-php-ext-install mysqli bcmath intl gd
|
||||
RUN echo "date.timezone = \"\${PHP_TIMEZONE}\"" > /usr/local/etc/php/conf.d/timezone.ini
|
||||
RUN echo -e “$(hostname -i)\t$(hostname) $(hostname).localhost” >> /etc/hosts
|
||||
|
||||
WORKDIR /app
|
||||
COPY . /app
|
||||
RUN ln -s /app/*[^public] /var/www && rm -rf /var/www/html && ln -nsf /app/public /var/www/html
|
||||
RUN chmod 755 /app/public/uploads && chown -R www-data:www-data /app/public /app/application
|
||||
|
||||
RUN [ ! -f test/ospos.js ] || sed -i -e "s/\(localhost\)/web/g" test/ospos.js
|
||||
9
Dockerfile.dev
Normal file
9
Dockerfile.dev
Normal file
@@ -0,0 +1,9 @@
|
||||
FROM jekkos/opensourcepos:master
|
||||
MAINTAINER jekkos
|
||||
|
||||
RUN mkdir -p /app/bower_components && ln -s /app/bower_components /var/www/html/bower_components
|
||||
RUN yes | pecl install xdebug \
|
||||
&& echo "zend_extension=$(find /usr/local/lib/php/extensions/ -name xdebug.so)" > /usr/local/etc/php/conf.d/xdebug.ini \
|
||||
&& echo "xdebug.remote_enable=on" >> /usr/local/etc/php/conf.d/xdebug.ini \
|
||||
&& echo "xdebug.remote_autostart=off" >> /usr/local/etc/php/conf.d/xdebug.ini
|
||||
|
||||
11
Dockerfile.test
Normal file
11
Dockerfile.test
Normal file
@@ -0,0 +1,11 @@
|
||||
FROM digitallyseamless/nodejs-bower-grunt:5
|
||||
MAINTAINER jekkos
|
||||
|
||||
# apt-get install curl
|
||||
|
||||
COPY Gruntfile.js .
|
||||
COPY package.json .
|
||||
COPY test .
|
||||
RUN npm install
|
||||
|
||||
CMD ['while ! curl web/index.php | grep username; do sleep 1; done; grunt mochaWebdriver:test']
|
||||
346
Gruntfile.js
346
Gruntfile.js
@@ -1,104 +1,252 @@
|
||||
module.exports = function(grunt) {
|
||||
|
||||
grunt.initConfig({
|
||||
pkg: grunt.file.readJSON('package.json'),
|
||||
concat: {
|
||||
options: {
|
||||
separator: ';'
|
||||
},
|
||||
dist: {
|
||||
src: ['js/jquery*', 'js/*.js'],
|
||||
dest: 'dist/<%= pkg.name %>.js'
|
||||
}
|
||||
},
|
||||
uglify: {
|
||||
options: {
|
||||
banner: '/*! <%= pkg.name %> <%= grunt.template.today("dd-mm-yyyy") %> */\n'
|
||||
},
|
||||
dist: {
|
||||
files: {
|
||||
'dist/<%= pkg.name %>.min.js': ['<%= concat.dist.dest %>']
|
||||
}
|
||||
}
|
||||
},
|
||||
jshint: {
|
||||
files: ['Gruntfile.js', 'js/*.js'],
|
||||
options: {
|
||||
// options here to override JSHint defaults
|
||||
globals: {
|
||||
jQuery: true,
|
||||
console: true,
|
||||
module: true,
|
||||
document: true
|
||||
}
|
||||
}
|
||||
},
|
||||
tags: {
|
||||
js : {
|
||||
options: {
|
||||
scriptTemplate: '<script type="text/javascript" src="{{ path }}" language="javascript"></script>',
|
||||
openTag: '<!-- start js template tags -->',
|
||||
closeTag: '<!-- end js template tags -->',
|
||||
absolutePath: true
|
||||
},
|
||||
src: [
|
||||
'js/jquery*.js', 'js/*.js',
|
||||
],
|
||||
dest: 'application/views/partial/header.php'
|
||||
},
|
||||
minjs : {
|
||||
options: {
|
||||
scriptTemplate: '<script type="text/javascript" src="{{ path }}" language="javascript"></script>',
|
||||
openTag: '<!-- start minjs template tags -->',
|
||||
closeTag: '<!-- end minjs template tags -->',
|
||||
absolutePath: true
|
||||
},
|
||||
src: [
|
||||
'dist/*min.js',
|
||||
],
|
||||
dest: 'application/views/partial/header.php'
|
||||
}
|
||||
},
|
||||
mochaWebdriver: {
|
||||
options: {
|
||||
timeout: 1000 * 60 * 3
|
||||
},
|
||||
test : {
|
||||
options: {
|
||||
usePhantom: true,
|
||||
usePromises: true
|
||||
},
|
||||
src: ['test/**/*.js']
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
files: ['<%= jshint.files %>'],
|
||||
tasks: ['jshint']
|
||||
},
|
||||
cachebreaker: {
|
||||
dev: {
|
||||
options: {
|
||||
match: ['opensourcepos.min.js'],
|
||||
src: {
|
||||
path: 'dist/opensourcepos.min.js'
|
||||
},
|
||||
replacement: 'md5'
|
||||
},
|
||||
files: {
|
||||
src: ['application/views/partial/header.php']
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
grunt.initConfig({
|
||||
pkg: grunt.file.readJSON('package.json'),
|
||||
wiredep: {
|
||||
task: {
|
||||
ignorePath: '../../../public/',
|
||||
src: ['application/views/partial/header.php']
|
||||
}
|
||||
},
|
||||
bower_concat: {
|
||||
all: {
|
||||
mainFiles: {
|
||||
'bootstrap-table': [ "src/bootstrap-table.js", "src/bootstrap-table.css", "dist/extensions/export/bootstrap-table-export.js", "dist/extensions/mobile/bootstrap-table-mobile.js", "dist/extensions/sticky-header/bootstrap-table-sticky-header.js", "dist/extensions/sticky-header/bootstrap-table-sticky-header.css"]
|
||||
},
|
||||
dest: {
|
||||
'js': 'tmp/opensourcepos_bower.js',
|
||||
'css': 'tmp/opensourcepos_bower.css'
|
||||
}
|
||||
}
|
||||
},
|
||||
bowercopy: {
|
||||
options: {
|
||||
report: false
|
||||
},
|
||||
targetdistjqueryui: {
|
||||
options: {
|
||||
srcPrefix: 'public/bower_components/jquery-ui',
|
||||
destPrefix: 'public/dist'
|
||||
},
|
||||
files: {
|
||||
'jquery-ui': 'themes/base/jquery-ui.min.css'
|
||||
}
|
||||
},
|
||||
targetdistbootswatch: {
|
||||
options: {
|
||||
srcPrefix: 'public/bower_components/bootswatch',
|
||||
destPrefix: 'public/dist'
|
||||
},
|
||||
files: {
|
||||
bootswatch: '*/'
|
||||
}
|
||||
},
|
||||
targetlicense: {
|
||||
options: {
|
||||
srcPrefix: './'
|
||||
},
|
||||
files: {
|
||||
'public/license': 'LICENSE'
|
||||
}
|
||||
}
|
||||
},
|
||||
cssmin: {
|
||||
target: {
|
||||
files: {
|
||||
'public/dist/<%= pkg.name %>.min.css': ['tmp/opensourcepos_bower.css', 'public/css/*.css', '!public/css/login.css', '!public/css/invoice_email.css', '!public/css/barcode_font.css']
|
||||
}
|
||||
}
|
||||
},
|
||||
concat: {
|
||||
js: {
|
||||
options: {
|
||||
separator: ';'
|
||||
},
|
||||
files: {
|
||||
'tmp/<%= pkg.name %>.js': ['tmp/opensourcepos_bower.js', 'public/js/jquery*', 'public/js/*.js']
|
||||
}
|
||||
},
|
||||
sql: {
|
||||
options: {
|
||||
banner: '-- >> This file is autogenerated from tables.sql and constraints.sql. Do not modify directly << --'
|
||||
},
|
||||
files: {
|
||||
'database/database.sql': ['database/tables.sql', 'database/constraints.sql'],
|
||||
'database/migrate_phppos_dist.sql': ['database/tables.sql', 'database/phppos_migrate.sql', 'database/constraints.sql']
|
||||
}
|
||||
}
|
||||
},
|
||||
uglify: {
|
||||
options: {
|
||||
banner: '/*! <%= pkg.name %> <%= grunt.template.today("dd-mm-yyyy") %> */\n'
|
||||
},
|
||||
dist: {
|
||||
files: {
|
||||
'public/dist/<%= pkg.name %>.min.js': ['tmp/<%= pkg.name %>.js']
|
||||
}
|
||||
}
|
||||
},
|
||||
jshint: {
|
||||
files: ['Gruntfile.js', 'public/js/*.js'],
|
||||
options: {
|
||||
// options here to override JSHint defaults
|
||||
globals: {
|
||||
jQuery: true,
|
||||
console: true,
|
||||
module: true,
|
||||
document: true
|
||||
}
|
||||
}
|
||||
},
|
||||
tags: {
|
||||
css_header: {
|
||||
options: {
|
||||
scriptTemplate: '<rel type="text/css" src="{{ path }}"></rel>',
|
||||
openTag: '<!-- start css template tags -->',
|
||||
closeTag: '<!-- end css template tags -->',
|
||||
ignorePath: '../../../public/'
|
||||
},
|
||||
src: ['public/css/*.css', '!public/css/login.css', '!public/css/invoice_email.css', '!public/css/barcode_font.css'],
|
||||
dest: 'application/views/partial/header.php',
|
||||
},
|
||||
mincss_header: {
|
||||
options: {
|
||||
scriptTemplate: '<rel type="text/css" src="{{ path }}"></rel>',
|
||||
openTag: '<!-- start mincss template tags -->',
|
||||
closeTag: '<!-- end mincss template tags -->',
|
||||
ignorePath: '../../../public/'
|
||||
},
|
||||
// jquery-ui must be first or at least before opensourcepos.min.css
|
||||
src: ['public/dist/jquery-ui/*.css', 'public/dist/*.css'],
|
||||
dest: 'application/views/partial/header.php',
|
||||
},
|
||||
css_login: {
|
||||
options: {
|
||||
scriptTemplate: '<rel type="text/css" src="{{ path }}"></rel>',
|
||||
openTag: '<!-- start css template tags -->',
|
||||
closeTag: '<!-- end css template tags -->',
|
||||
ignorePath: '../../public/'
|
||||
},
|
||||
src: ['public/css/login.css'],
|
||||
dest: 'application/views/login.php'
|
||||
},
|
||||
js: {
|
||||
options: {
|
||||
scriptTemplate: '<script type="text/javascript" src="{{ path }}"></script>',
|
||||
openTag: '<!-- start js template tags -->',
|
||||
closeTag: '<!-- end js template tags -->',
|
||||
ignorePath: '../../../public/'
|
||||
},
|
||||
src: ['public/js/jquery*', 'public/js/*.js'],
|
||||
dest: 'application/views/partial/header.php'
|
||||
},
|
||||
minjs: {
|
||||
options: {
|
||||
scriptTemplate: '<script type="text/javascript" src="{{ path }}"></script>',
|
||||
openTag: '<!-- start minjs template tags -->',
|
||||
closeTag: '<!-- end minjs template tags -->',
|
||||
ignorePath: '../../../public/'
|
||||
},
|
||||
src: ['public/dist/*min.js'],
|
||||
dest: 'application/views/partial/header.php'
|
||||
}
|
||||
},
|
||||
mochaWebdriver: {
|
||||
options: {
|
||||
timeout: 1000 * 60 * 3
|
||||
},
|
||||
test : {
|
||||
options: {
|
||||
usePhantom: true,
|
||||
usePromises: true
|
||||
},
|
||||
src: ['test/**/*.js']
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
files: ['<%= jshint.files %>'],
|
||||
tasks: ['jshint']
|
||||
},
|
||||
cachebreaker: {
|
||||
dev: {
|
||||
options: {
|
||||
match: [ {
|
||||
'opensourcepos.min.js': 'public/dist/opensourcepos.min.js',
|
||||
'opensourcepos.min.css': 'public/dist/opensourcepos.min.css'
|
||||
} ],
|
||||
replacement: 'md5'
|
||||
},
|
||||
files: {
|
||||
src: ['application/views/partial/header.php', 'application/views/login.php']
|
||||
}
|
||||
}
|
||||
},
|
||||
clean: {
|
||||
license: ['public/bower_components/**/bower.json']
|
||||
},
|
||||
license: {
|
||||
all: {
|
||||
// Target-specific file lists and/or options go here.
|
||||
options: {
|
||||
// Target-specific options go here.
|
||||
directory: 'public/bower_components',
|
||||
output: 'public/license/bower.LICENSES'
|
||||
}
|
||||
}
|
||||
},
|
||||
'bower-licensechecker': {
|
||||
options: {
|
||||
/*directory: 'path/to/bower',*/
|
||||
acceptable: [ 'MIT', 'BSD', 'LICENSE.md' ],
|
||||
printTotal: true,
|
||||
warn: {
|
||||
nonBower: true,
|
||||
noLicense: true,
|
||||
allGood: true,
|
||||
noGood: true
|
||||
},
|
||||
log: {
|
||||
outFile: 'public/license/.licenses',
|
||||
nonBower: true,
|
||||
noLicense: true,
|
||||
allGood: true,
|
||||
noGood: true,
|
||||
}
|
||||
}
|
||||
},
|
||||
apigen: {
|
||||
generate:{
|
||||
options: {
|
||||
apigenPath: 'vendor/bin/',
|
||||
source: 'application',
|
||||
destination: 'docs'
|
||||
}
|
||||
}
|
||||
},
|
||||
compress: {
|
||||
main: {
|
||||
options: {
|
||||
mode: 'zip',
|
||||
archive: 'dist/opensourcepos.zip'
|
||||
},
|
||||
files: [
|
||||
{src: ['public/**', 'vendor/**', 'application/**', '!/public/images/menubar/png/', '!/public/dist/bootswatch/', '/public/dist/bootswatch/*/*.css', 'database/**', '*.txt', '*.md', 'LICENSE', 'docker*', 'Dockerfile', '**/.htaccess', '*.csv']}
|
||||
]
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
grunt.loadNpmTasks('grunt-contrib-uglify');
|
||||
grunt.loadNpmTasks('grunt-contrib-jshint');
|
||||
grunt.loadNpmTasks('grunt-contrib-watch');
|
||||
grunt.loadNpmTasks('grunt-contrib-concat');
|
||||
grunt.loadNpmTasks('grunt-script-link-tags');
|
||||
grunt.loadNpmTasks('grunt-mocha-webdriver');
|
||||
grunt.loadNpmTasks('grunt-cache-breaker');
|
||||
|
||||
grunt.registerTask('default', ['tags:js', 'concat', 'uglify', 'tags:minjs', 'cachebreaker']);
|
||||
require('load-grunt-tasks')(grunt);
|
||||
grunt.loadNpmTasks('grunt-mocha-webdriver');
|
||||
grunt.loadNpmTasks('grunt-composer');
|
||||
grunt.loadNpmTasks('grunt-apigen');
|
||||
grunt.loadNpmTasks('grunt-contrib-compress');
|
||||
|
||||
grunt.registerTask('default', ['wiredep', 'bower_concat', 'bowercopy', 'concat', 'uglify', 'cssmin', 'tags', 'cachebreaker']);
|
||||
grunt.registerTask('update', ['composer:update', 'bower:update']);
|
||||
grunt.registerTask('genlicense', ['clean:license', 'license', 'bower-licensechecker']);
|
||||
grunt.registerTask('package', ['default', 'compress']);
|
||||
grunt.registerTask('packages', ['composer:update']);
|
||||
grunt.registerTask('gendocs', ['apigen:generate']);
|
||||
|
||||
};
|
||||
|
||||
87
INSTALL.md
Normal file
87
INSTALL.md
Normal file
@@ -0,0 +1,87 @@
|
||||
Server Requirements
|
||||
-------------------
|
||||
|
||||
* PHP version 5.6 to 7.2 is recommended. Please note that PHP needs to have `php-gd`, `php-bcmath`, `php-intl`, `php-openssl`, `php-mbstring` and `php-curl` installed and enabled.
|
||||
|
||||
* MySQL 5.5, 5.6 and 5.7 are supported, also MariaDB replacement is supported and apparently offering better performance.
|
||||
|
||||
* Apache 2.2 and 2.4 are supported. Also Nginx has been proven to work fine, see [wiki page here](https://github.com/opensourcepos/opensourcepos/wiki/Local-Deployment-using-LEMP)
|
||||
|
||||
* Raspberry PI based installations proved to work, see [wiki page here](https://github.com/opensourcepos/opensourcepos/wiki/Installing-on-Raspberry-PI---Orange-PI-(Headless-OSPOS))
|
||||
|
||||
* For Windows based installations please read [the wiki](https://github.com/opensourcepos/opensourcepos/wiki) and also existing closed issues as this topic has been covered well in all the variants and issues.
|
||||
|
||||
|
||||
Local install
|
||||
-------------
|
||||
|
||||
First of all, if you're seeing the message **'system folder missing'** after launching your browser, then that means you have cloned the repository and have not built the project properly.
|
||||
|
||||
1. Dowload the latest [stable release](https://github.com/opensourcepos/opensourcepos/releases) from github or [unstable build](https://bintray.com/jekkos/opensourcepos/opensourcepos/view/files?sort=updated&order=asc#files) from bintray. A regular repository clone will not work unless you are brave enough to build the whole project!
|
||||
2. Create/locate a new mysql database to install open source point of sale into
|
||||
3. Execute the file database/database.sql to create the tables needed
|
||||
4. unzip and upload Open Source Point of Sale files to web server
|
||||
5. Modify application/config/database.php and modify credentials if needed to connect to your database
|
||||
6. Modify application/config/config.php encryption key with your own
|
||||
7. Go to your point of sale install public dir via the browser
|
||||
8. LOGIN using
|
||||
* username: admin
|
||||
* password: pointofsale
|
||||
9. Enjoy
|
||||
10. Oops an issue? Please make sure you read the FAQ, wiki page and you checked open and closed issue on GitHub. PHP display_errors is disabled by default. Create an application/config/.env file from the .env.example to enable it in a development environment.
|
||||
|
||||
|
||||
Local install using Docker
|
||||
--------------------------
|
||||
|
||||
From now on ospos can be deployed using Docker on Linux, Mac or Windows. This setup dramatically reduces the number of possible issues as all setup is now done in a Dockerfile. Docker runs natively on mac and linux, but will require more overhead on windows. Please refer to the docker documentation for instructions on how to set it up on your platform.
|
||||
|
||||
* To build and run the image, download the latest build from bintray and issue following commands in a terminal with docker installed
|
||||
|
||||
```
|
||||
docker-compose build
|
||||
docker-compose up
|
||||
```
|
||||
|
||||
* If you want to run from the latest git source, then use docker and composer to run the build
|
||||
|
||||
```
|
||||
docker run --rm -v $(pwd):/app composer/composer install
|
||||
docker run --rm -v $(pwd):/app -w /app lucor/php7-cli php bin/install.php translations develop
|
||||
docker run --rm -it -v $(pwd):/app -w /app digitallyseamless/nodejs-bower-grunt "sh -c npm install && bower install"
|
||||
docker-compose build
|
||||
docker-compose up
|
||||
```
|
||||
|
||||
Cloud install
|
||||
-------------
|
||||
|
||||
A quick option would be to install directly to [Digitalocean](https://m.do.co/c/ac38c262507b) using their preconfigured LAMP stack.
|
||||
Create a DO account first, add a droplet with preconfigured LAMP and follow the instructions for Local Install below. You will be running a provisioned VPS within minutes.
|
||||
|
||||
|
||||
Cloud install using Docker
|
||||
--------------------------
|
||||
This installation is NOT Recommended anymore and will soon be replaced by a one click DO installation procedure.
|
||||
Existing setups will keep working until the 21th of May but will need to be migrated in time in order to ensure user's safety.
|
||||
|
||||
|
||||
If you want to run a quick demo of ospos or run it permanently in the cloud, then we
|
||||
suggest using Docker cloud together with the DigitalOcean hosting platform. This way all the
|
||||
configuration is done automatically and the install will just work.
|
||||
|
||||
If you choose *DigitalOcean* [through this link](https://m.do.co/c/ac38c262507b), you will get a *$10 credit* for a first
|
||||
month of uptime on the platform. A full setup will only take about 2 minutes by following steps below.
|
||||
|
||||
1. Create a [Digitalocean account](https://m.do.co/c/ac38c262507b)
|
||||
2. Create a [docker cloud account](https://cloud.docker.com)
|
||||
3. Login to docker cloud
|
||||
4. Associate your docker cloud account with your previously created digital ocean account under settings
|
||||
5. Create a new node on DigitalOcean through the `Infrastructure > Nodes` tab. Fill in a name (ospos) and choose a region near to you. We recommend to choose a node with minimum 1G RAM for the whole stack
|
||||
6. Click [](https://cloud.docker.com/stack/deploy/?repo=https://github.com/opensourcepos/opensourcepos)
|
||||
7. Othewise create a new stack under `Applications > Stacks` and paste the [contents of docker-cloud.yml](https://github.com/opensourcepos/opensourcepos/blob/master/docker-cloud.yml) from the source repository in the text field and hit `Create and deploy`
|
||||
8. Find your website url under `Infrastructure > Nodes > <yournode> > Endpoints > web`
|
||||
9. Login with default username/password admin/pointofsale
|
||||
10. DNS name for this server can be easily configured in the DigitalOcean control panel
|
||||
|
||||
More info [on maintaining a docker](https://github.com/opensourcepos/opensourcepos/wiki/Docker-cloud-maintenance) install can be found on the wiki
|
||||
@@ -5,9 +5,19 @@ Copyright (c) 2012 Alain
|
||||
Copyright (c) 2013 Rob Garrison
|
||||
Copyright (c) 2013 Parq
|
||||
Copyright (c) 2013 Ramel
|
||||
Copyright (c) 2014-2015 jekkos
|
||||
Copyright (c) 2015 FrancescoUK (aka daN4cat)
|
||||
Copyright (c) 2013-2018 jekkos
|
||||
Copyright (c) 2015-2018 FrancescoUK (aka daN4cat)
|
||||
Copyright (c) 2015 Aamir Shahzad (aka asakpke), RoshanTech.com
|
||||
Copyright (c) 2015 Toni Haryanto (aka yllumi)
|
||||
Copyright (c) 2016-2017 Ramkrishna Mondal (aka RamkrishnaMondal)
|
||||
Copyright (c) 2016 Rinaldy@dbarber (aka rnld26)
|
||||
Copyright (c) 2016-2017 Jorge Colmenarez (aka jlctmaster), frontuari.com
|
||||
Copyright (c) 2017-2018 Steve Ireland
|
||||
Copyright (c) 2017 Jesus Guerrero Botella (aka i92guboj)
|
||||
Copyright (c) 2017 Deep Shah (aka deepshah)
|
||||
Copyright (c) 2017 Joshua Fernandez (aka joshua1234511)
|
||||
Copyright (c) 2017 odiea
|
||||
Copyright (c) 2017 asadjaved63
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
this software and associated documentation files (the "Software"), to deal in
|
||||
@@ -19,9 +29,15 @@ subject to the following conditions:
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
You cannot claim copyright or ownership of the Software.
|
||||
|
||||
Footer signatures "You are using Open Source Point Of Sale" and/or "Open Source Point Of Sale"
|
||||
with version, hash and URL link to the original distribution of the code MUST BE RETAINED,
|
||||
MUST BE VISIBLE IN EVERY PAGE and CANNOT BE MODIFIED.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
145
README.md
145
README.md
@@ -1,25 +1,136 @@
|
||||
Open Source Point of Sale is a web based point of sale system written in the PHP language. It uses MySQL as the data storage back-end and has a simple user interface.
|
||||
[](https://travis-ci.org/opensourcepos/opensourcepos)
|
||||
[](https://gitter.im/jekkos/opensourcepos?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
|
||||
[](https://david-dm.org/jekkos/opensourcepos#info=dev)
|
||||
[](https://gemnasium.com/github.com/jekkos/opensourcepos)
|
||||
[](https://badge.fury.io/gh/jekkos%2Fopensourcepos)
|
||||
[](http://weblate.jpeelaer.net/engage/ospos/?utm_source=widget)
|
||||
|
||||
[](https://travis-ci.org/jekkos/opensourcepos)
|
||||
|
||||
How to Install
|
||||
--------------
|
||||
1. Create/locate a new mysql database to install open source point of sale into
|
||||
2. Execute the file database/database.sql to create the tables needed
|
||||
3. unzip and upload Open Source Point of Sale files to web server
|
||||
4. Copy application/config/database.php.tmpl to application/config/database.php
|
||||
5. Modify application/config/database.php to connect to your database
|
||||
6. Modify application/config/config.php encryption key with your own
|
||||
7. Go to your point of sale install via the browser
|
||||
8. LOGIN using
|
||||
username: admin
|
||||
password:pointofsale
|
||||
9. Enjoy
|
||||
Introduction
|
||||
------------
|
||||
|
||||
A more extensive setup guide can be found at [this site](http://www.opensourceposguide.com/guide/gettingstarted/installation)
|
||||
Open Source Point of Sale is a web based point of sale system.
|
||||
The main features are:
|
||||
* Stock management (Items and Kits)
|
||||
* VAT, customer and multi tiers taxation
|
||||
* Sale register with transactions logging
|
||||
* Quotation and invoicing
|
||||
* Expenses logging
|
||||
* Receipt and invoice printing and/or emailing
|
||||
* Barcode generation and printing
|
||||
* Suppliers and Customers database
|
||||
* Multiuser with permission control
|
||||
* Reporting on sales, orders, expenses, inventory status
|
||||
* Receivings
|
||||
* Giftcard
|
||||
* Rewards
|
||||
* Restaurant tables
|
||||
* Messaging (SMS)
|
||||
* Multilanguage
|
||||
* Selectable Boostrap (Bootswatch) based UI theme
|
||||
* Mailchimp integration
|
||||
* reCAPTCHA to protect login page from brute force attacks
|
||||
|
||||
If you like the project, and you are making money out of it on a daily basis, then consider to buy me a coffee so I can keep adding features.
|
||||
The software is written in PHP language, it uses MySQL (or MariaDB) as data storage back-end and has a simple but intuitive user interface.
|
||||
|
||||
The latest 3.x version is a complete overhaul of the original software.
|
||||
It is now based on Bootstrap 3 using Bootswatch themes, and still uses CodeIgniter 3 as framework.
|
||||
It also has improved functionality and security.
|
||||
|
||||
Deployed to a Cloud it's a SaaS (Software as a Service) solution.
|
||||
|
||||
|
||||
Installation
|
||||
------------
|
||||
|
||||
Please **refrain from creating issues** about installation issues **before reading the FAQ and going through existing github issues**. We have a build pipeline that checks the sanity of our latest repository commit and in case the application itself is broken then our build will be as well.
|
||||
|
||||
This application **can be setup in many different ways** and we only **support the ones described in the INSTALL file linked below**.
|
||||
|
||||
Read the [INSTALL.md](https://github.com/opensourcepos/opensourcepos/blob/master/INSTALL.md) in our repository.
|
||||
|
||||
|
||||
License
|
||||
-------
|
||||
|
||||
Open Source Point of Sale is licensed under MIT terms with an important addition:
|
||||
|
||||
_The footer signature "You are using Open Source Point Of Sale" with version,
|
||||
hash and link to the original distribution of the code MUST BE RETAINED,
|
||||
MUST BE VISIBLE IN EVERY PAGE and CANNOT BE MODIFIED._
|
||||
|
||||
Also worth noting:
|
||||
|
||||
_The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software._
|
||||
|
||||
For more details please read the file [LICENSE](https://github.com/opensourcepos/opensourcepos/blob/master/LICENSE).
|
||||
|
||||
It's important to understand that althought you are free to use the software the copyright stays and the license agreement applies in all cases.
|
||||
Therefore any actions like:
|
||||
|
||||
- Removing LICENSE and any license files is prohibited
|
||||
- Authoring the footer notice replacing it with your own or even worse claiming the copyright is absolutely prohibited
|
||||
- Claiming full ownership of the code is prohibited
|
||||
|
||||
In short you are free to use the software but you cannot claim any property on it.
|
||||
|
||||
Any person or company found breaching the license agreement will have a bunch of monkeys at the door ready to destroy their servers.
|
||||
|
||||
|
||||
Keep the Machine Running
|
||||
------------------------
|
||||
|
||||
If you like the project, and you are making money out of it in some form, then consider buying us a coffee so we can keep adding features.
|
||||
|
||||
[](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=MUN6AEG7NY6H8)
|
||||
|
||||
|
||||
Language Translations
|
||||
---------------------
|
||||
|
||||
To help us with OSPOS translations please use [Weblate website here](http://translate.opensourcepos.org) and sign up. After registering you can subscribe to different languages and you will be notified once a new translation is added.
|
||||
|
||||
Please also read the [wiki page here](https://github.com/opensourcepos/opensourcepos/wiki/Adding-translations) to find our Translations Guideline.
|
||||
|
||||
Only with the help of the community we can keep language translations up to date.
|
||||
|
||||
|
||||
Reporting Bugs
|
||||
--------------
|
||||
|
||||
If you are taking a release candidate code please make sure you always run the latest database upgrade script and you took the latest code from master.
|
||||
Please DO NOT post issues if you have not done those step.
|
||||
|
||||
Bug reports must follow this schema:
|
||||
|
||||
1. Ospos **version string with git commit hash** (see ospos footer)
|
||||
2. OS name and version running your Web Server (e.g. CentOS 6.9, Ubuntu 16.4, Windows 10)
|
||||
3. Web Server name and version (e.g. Apache 2.2, Apache 2.4, Nginx 1.12, Nginx 1.13)
|
||||
4. Database name and version (e.g. MySQL 5.5, MySQL 5.6, MySQL 5.7, MariaDB 10.0, MariaDB 10.1, MariaDB 10.2)
|
||||
5. PHP version (e.g. 5.5, 5.6, 7.0, 7.1)
|
||||
6. Language selected in OSPOS (e.g. English, Spanish)
|
||||
7. Any configuration of OSPOS that you changed
|
||||
8. Exact steps to reproduce the issue (test case)
|
||||
9. Optionally some screenshots to illustrate each step
|
||||
|
||||
If above information is not provided in full, your issue will be tagged as pending.
|
||||
If missing information is not provided within a week we will close your issue.
|
||||
|
||||
|
||||
FAQ
|
||||
---
|
||||
|
||||
* If you are seeing the message **system folder missing**, then you have cloned the source using git and you need to run a build *first*. Check [INSTALL.md](https://github.com/opensourcepos/opensourcepos/blob/master/INSTALL.md) for instructions or download latest zip file from [bintray](https://bintray.com/jekkos/opensourcepos/opensourcepos/view/files?sort=updated&order=desc#files) instead.
|
||||
|
||||
* If at login time you read "The installation is not correct, check your php.ini file.", please check the error_log in public folder to understand what's wrong and make sure you read the [INSTALL.md](https://github.com/opensourcepos/opensourcepos/blob/master/INSTALL.md).
|
||||
|
||||
* If you installed your OSPOS under a web server subdir, please edit public/.htaccess and go to the lines with comment `if in web root` and `if in subdir comment above line, uncomment below one and replace <OSPOS path> with your path` and follow the instruction on the second comment line. If you face more issues please read [issue #920](https://github.com/opensourcepos/opensourcepos/issues/920) for more help.
|
||||
|
||||
* Apache server configurations are SysAdmin issues and not strictly related to OSPOS. Please make sure you first can show a "hello world" html page before pointing to OSPOS public directory. Make sure .htaccess is correctly configured.
|
||||
|
||||
* If the avatar pictures are not shown in Items or at Item save time you get an error, please make sure your public and subdirs are assigned to the correct owner and the access permission is set to 755.
|
||||
|
||||
* If you install ospos in docker behind a proxy that performs ssloffloading, you can enable the url generated to be https instead of http, by activating the environment variable FORCE_HTTPS = 1.
|
||||
|
||||
* If you have suhosin installed and face an issue with CSRF, please make sure you read [issue #1492](https://github.com/opensourcepos/opensourcepos/issues/1492).
|
||||
|
||||
16
UPGRADE.txt
16
UPGRADE.txt
@@ -1,4 +1,16 @@
|
||||
How to Upgrade
|
||||
-------------------------
|
||||
1. Replace all code from your point of sale installation with the code downloaded
|
||||
2. Run the necessary database upgrades from the database folder
|
||||
1. Backup all your current database and OSPOS code
|
||||
2. Make sure you have a copy of application/config/config.php and application/config/database.php
|
||||
3. Remove all directories
|
||||
4. Install the new OSPOS
|
||||
5. Run the database upgrade scripts from database/ dir (check which ones you need according to the version you are upgrading from and only applicable if upgrading from pre 3.0.0)
|
||||
6. Take the saved old config.php and upgrade the new config.php with any additional changes you made in the old.
|
||||
Take time to understand if new config rules require some changes (e.g. encryption keys)
|
||||
7. Take the saved old database.php and change the new database.php to contain all the configuration you had in the old setup.
|
||||
Please try not to use the old layout, use the new one and just copy the content of the config variables
|
||||
8. Restore the content of the old uploads/ folder into public/uploads/ one
|
||||
9. Once the new code is in place, database is updated and config files are sorted you are good to start the new OSPOS
|
||||
10. The first login will take longer because OSPOS post 3.0.0 will upgrade automatically to the latest version
|
||||
11. Now you can use OSPOS
|
||||
12. If any issue please check README, FAQ and GitHub issues as somebody else might have had your problem already before creating a new issue
|
||||
|
||||
143
WHATS_NEW.txt
143
WHATS_NEW.txt
@@ -1,3 +1,139 @@
|
||||
Version 3.2.0
|
||||
-------------
|
||||
+ Code Igniter 3.1.8 upgrade
|
||||
+ PHP 7.2 support (use OpenSSL and not MCrypt)
|
||||
+ Automatic database upgrades from vs 3.0.0 at first login (no more sql scripts)
|
||||
+ Home and (back) Office menu switch (top menu can be organised in two views)
|
||||
+ Expenses feature
|
||||
+ Quote, Work Order features
|
||||
+ Improved Invoice support
|
||||
+ Sale suspend, soft delete, complete as state not as different tables or hard delete
|
||||
+ Restore deleted Sales
|
||||
+ Improved Items Kits
|
||||
+ Export tables all records and export to pdf
|
||||
+ Table sticky header (headers visible during scrolling)
|
||||
+ Allow duplicate barcodes (Config option)
|
||||
+ Search suggestion formatting (Config option)
|
||||
+ Define print and email checkboxes behaviour (Config option)
|
||||
+ Edit customer from sale register
|
||||
+ Added and Updated translations
|
||||
+ Various Jquery plugins upgrade
|
||||
+ Fixed permission issues (e.g. password change)
|
||||
+ Fixed various reports issues and renamed Sales to Transactions
|
||||
+ Various bug fixes (e.g. Tax, Rounding, Library circular dependency)
|
||||
|
||||
Version 3.1.1
|
||||
-------------
|
||||
+ Updated en-US and en-GB translations, better grammar and consistency
|
||||
+ Fixed database migration issue with VAT tax included
|
||||
+ Fixed database backup bug
|
||||
+ Fixed Gift card error
|
||||
+ Fixed database upgrade to 3.1.x script (now it's to 3.1.1 and there is no 3.1.0 anymore)
|
||||
+ Fixed old database upgrade scripts for people upgrading from 2.x versions
|
||||
+ Fixed .htaccess file in opensourcepos root dir (it was not forwarding to public subdir)
|
||||
+ Fixed few jQuery 2.0 upgrade issues
|
||||
|
||||
Version 3.1.0
|
||||
-------------
|
||||
+ MySQL 5.7 and PHP 7.x support
|
||||
+ Advanced Tax support with customer tax categories and etc,
|
||||
+ Better HORECA use case support with Dinner Table sale tagging
|
||||
+ Customer Rewards support
|
||||
+ Added quote support and better invoice support
|
||||
+ Added integration with Mailchimp to connect Customer list with Mailchimp list
|
||||
+ Prevent inserting two customers with same email address
|
||||
+ Customer total spending and stats
|
||||
+ Added reCAPTCHA to Login page to increase protection from Brute Force attacks
|
||||
+ Added due payment for credit sale support
|
||||
+ Gifcard numbering with two options: Series and Random
|
||||
+ Extended Item Kits functionality
|
||||
+ Employee allowed to change their own password clicking their name on top bar
|
||||
+ Cash rounding support, extended decimals
|
||||
+ Reworked Item Pictures and file name and storing
|
||||
+ Financial year start date and selection from date range pickers
|
||||
+ Date time range filters can be date & time or date only
|
||||
+ Added two new Bootswatch themes
|
||||
+ Receipts font size support
|
||||
+ Fix automatically people's name first capital letter, emails in lower case only
|
||||
+ Fixes to Receiving
|
||||
+ Various amendments to database script updates from older versions
|
||||
+ Added dotenv support
|
||||
+ Updates to language translations (split English to American English and British English)
|
||||
+ Various Dockers support improvements
|
||||
+ Minor bugfixes
|
||||
|
||||
Version 3.0.2
|
||||
-------------
|
||||
+ Fixed error when performing scans multiple times in a row
|
||||
+ Fixed summary reports
|
||||
+ Protect Employee privacy printing just the first letter of the family name
|
||||
+ Updates to language translations
|
||||
+ Various Dockers support improvements
|
||||
+ Minor bugfixes
|
||||
|
||||
Version 3.0.1
|
||||
-------------
|
||||
+ *CodeIgniter 3.1.2 Upgrade*
|
||||
+ *Substantial database performance improvements*
|
||||
+ *Improved security: email and sms passwords encryption, removed phpinfo.php*
|
||||
+ *Set code to be production and not development in index.php*
|
||||
+ *Reports improvements, fixed table sorting, tax calculation and made profit to be net profit*
|
||||
+ Better Apache 2.4 support in .htaccess
|
||||
+ Updates to language translations
|
||||
+ Fixed excel template download links
|
||||
+ Fixed employee name in Sale receipt and invoice reprinting
|
||||
+ Fixed 2.3.2_to_2.3.3.sql database upgrade script mistake
|
||||
+ Fixed phppos to ospos database migration script
|
||||
+ Minor bugfixes and some general code clean up
|
||||
|
||||
Version 3.0.0
|
||||
-------------
|
||||
+ *CodeIgniter 3.1 Upgrade*
|
||||
+ Major UI overhaul based on *Boostrap 3.0 and Bootswatch Themes*
|
||||
+ New tabular views with advanced filtering using *Bootstrap Tables*
|
||||
+ New graphical reports with no more Adobe flash dependency
|
||||
+ Redesign of all modal dialogs
|
||||
+ Updated Sales register with simplified payment flow
|
||||
+ *Improved security: MySQL injection, XSS, CSFR, BCrypt password encryption, safer project layout*
|
||||
+ Support for TXT messaging (interfacing to specific support required)
|
||||
+ Email configuration
|
||||
+ Improved Localisation support
|
||||
+ Improved Store Config page
|
||||
+ Docker container ready for Cloud installation
|
||||
+ Composer PHP support
|
||||
+ More languages and integration with Weblate for continuous translation
|
||||
+ About 280 closed issues under 3.0.0 release label, too many to produce a meaningful list
|
||||
+ Various code cleanup, refactoring, optimisation and etc.
|
||||
|
||||
Version 2.4.0
|
||||
-------------
|
||||
+ *CodeIgniter 3.0.5* Upgrade (please read UPGRADE.txt)
|
||||
+ Fix for spurious logouts
|
||||
+ Apache .htaccess mod_expiry caching and security optimizations
|
||||
+ Bulk item edit fixes (category, tax and supplier fields)
|
||||
+ Remove f-key shortcuts used for module navigation
|
||||
+ Allow to use custom invoice numbers when suspending sale
|
||||
+ PHP7 fixes
|
||||
+ Specific warnings to distinguish between reorder level and out of stock situation in sales
|
||||
+ Fix malware detection issues due to usage of base64 encoding for storing session variables
|
||||
+ Improve language generation scripts (use PHP builtin functionality)
|
||||
+ Add extra buttons for navigation and printing to receipt and invoice
|
||||
+ Improve print layout for invoices
|
||||
+ Make layout consistent for items between receipt and invoice templates
|
||||
+ Minor bugfixes
|
||||
|
||||
Version 2.3.4
|
||||
-------------
|
||||
+ Migration script fixes
|
||||
+ Improved continuous integration setup
|
||||
+ More integration tests
|
||||
+ Virtualized container setup (docker install)
|
||||
+ Live clock functionality + favicon
|
||||
+ Improved PHP 7 compatbility
|
||||
+ Added de_CH (German) as language
|
||||
+ Minor code cleanup
|
||||
+ Removal of annoying backup prompt on logout
|
||||
|
||||
Version 2.3.3
|
||||
-------------
|
||||
+ Item kit fixes (search, list, ..)
|
||||
@@ -43,7 +179,6 @@ Version 2.3.2
|
||||
|
||||
Version 2.3.1
|
||||
-------------
|
||||
|
||||
+ Extra report permissions (this includes a refactoring of the database model - new grants table)
|
||||
+ Tax inclusive/exclusive pricing
|
||||
+ Receivings amount multiplication (can be configured in items section)
|
||||
@@ -52,8 +187,8 @@ Version 2.3.1
|
||||
+ Fix item import through csv
|
||||
+ Bug fixes for reports
|
||||
|
||||
Version 2.3
|
||||
-----------
|
||||
Version 2.3.0
|
||||
-------------
|
||||
+ Support for multiple stock locations
|
||||
|
||||
Version 2.2.2
|
||||
@@ -65,7 +200,7 @@ Version 2.2.2
|
||||
+ Fix duplicated session cookies in http headers (this broke the application when running on nginx)
|
||||
|
||||
Version 2.1.1
|
||||
-------------
|
||||
---------------
|
||||
+ Barcodes on the order receipt weren't generated correctly
|
||||
+ Sales edit screen for detailed sales reports is now available with thickbox as in the rest of the application
|
||||
+ Indonesian language files updated (Oktafianus)
|
||||
|
||||
@@ -1 +1,6 @@
|
||||
Deny from all
|
||||
<IfModule authz_core_module>
|
||||
Require all denied
|
||||
</IfModule>
|
||||
<IfModule !authz_core_module>
|
||||
Deny from all
|
||||
</IfModule>
|
||||
7
application/cache/.htaccess
vendored
7
application/cache/.htaccess
vendored
@@ -1 +1,6 @@
|
||||
deny from all
|
||||
<IfModule authz_core_module>
|
||||
Require all denied
|
||||
</IfModule>
|
||||
<IfModule !authz_core_module>
|
||||
Deny from all
|
||||
</IfModule>
|
||||
3
application/cache/index.html
vendored
3
application/cache/index.html
vendored
@@ -1,3 +1,4 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>403 Forbidden</title>
|
||||
@@ -7,4 +8,4 @@
|
||||
<p>Directory access is forbidden.</p>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
</html>
|
||||
|
||||
7
application/config/.env.example
Normal file
7
application/config/.env.example
Normal file
@@ -0,0 +1,7 @@
|
||||
CI_ENV="development"
|
||||
|
||||
#Database Settings
|
||||
MYSQL_HOST_NAME="localhost"
|
||||
MYSQL_USERNAME=""
|
||||
MYSQL_PASSWORD=""
|
||||
MYSQL_DB_NAME=""
|
||||
@@ -1,4 +1,6 @@
|
||||
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
|
||||
<?php
|
||||
defined('BASEPATH') OR exit('No direct script access allowed');
|
||||
|
||||
/*
|
||||
| -------------------------------------------------------------------
|
||||
| AUTO-LOADER
|
||||
@@ -20,40 +22,64 @@
|
||||
|
|
||||
| 1. Packages
|
||||
| 2. Libraries
|
||||
| 3. Helper files
|
||||
| 4. Custom config files
|
||||
| 5. Language files
|
||||
| 6. Models
|
||||
| 3. Drivers
|
||||
| 4. Helper files
|
||||
| 5. Custom config files
|
||||
| 6. Language files
|
||||
| 7. Models
|
||||
|
|
||||
*/
|
||||
|
||||
/*
|
||||
| -------------------------------------------------------------------
|
||||
| Auto-load Packges
|
||||
| Auto-load Packages
|
||||
| -------------------------------------------------------------------
|
||||
| Prototype:
|
||||
|
|
||||
| $autoload['packages'] = array(APPPATH.'third_party', '/usr/local/shared');
|
||||
|
|
||||
*/
|
||||
|
||||
$autoload['packages'] = array();
|
||||
|
||||
|
||||
/*
|
||||
| -------------------------------------------------------------------
|
||||
| Auto-load Libraries
|
||||
| -------------------------------------------------------------------
|
||||
| These are the classes located in the system/libraries folder
|
||||
| or in your application/libraries folder.
|
||||
| These are the classes located in system/libraries/ or your
|
||||
| application/libraries/ directory, with the addition of the
|
||||
| 'database' library, which is somewhat of a special case.
|
||||
|
|
||||
| Prototype:
|
||||
|
|
||||
| $autoload['libraries'] = array('database', 'session', 'xmlrpc');
|
||||
| $autoload['libraries'] = array('database', 'email', 'session');
|
||||
|
|
||||
| You can also supply an alternative library name to be assigned
|
||||
| in the controller:
|
||||
|
|
||||
| $autoload['libraries'] = array('user_agent' => 'ua');
|
||||
*/
|
||||
$autoload['libraries'] = array('database', 'form_validation', 'session', 'user_agent', 'pagination', 'encryption');
|
||||
|
||||
$autoload['libraries'] = array('database','form_validation','session','user_agent', 'pagination');
|
||||
|
||||
/*
|
||||
| -------------------------------------------------------------------
|
||||
| Auto-load Drivers
|
||||
| -------------------------------------------------------------------
|
||||
| These classes are located in system/libraries/ or in your
|
||||
| application/libraries/ directory, but are also placed inside their
|
||||
| own subdirectory and they extend the CI_Driver_Library class. They
|
||||
| offer multiple interchangeable driver options.
|
||||
|
|
||||
| Prototype:
|
||||
|
|
||||
| $autoload['drivers'] = array('cache');
|
||||
|
|
||||
| You can also supply an alternative property name to be assigned in
|
||||
| the controller:
|
||||
|
|
||||
| $autoload['drivers'] = array('cache' => 'cch');
|
||||
|
|
||||
*/
|
||||
$autoload['drivers'] = array();
|
||||
|
||||
/*
|
||||
| -------------------------------------------------------------------
|
||||
@@ -63,9 +89,7 @@ $autoload['libraries'] = array('database','form_validation','session','user_agen
|
||||
|
|
||||
| $autoload['helper'] = array('url', 'file');
|
||||
*/
|
||||
|
||||
$autoload['helper'] = array('form','url','table','text','currency', 'html', 'download', 'directory', 'dateformat_helper');
|
||||
|
||||
$autoload['helper'] = array('form', 'url', 'tabular', 'text', 'locale', 'html', 'download', 'directory', 'migration');
|
||||
|
||||
/*
|
||||
| -------------------------------------------------------------------
|
||||
@@ -79,10 +103,8 @@ $autoload['helper'] = array('form','url','table','text','currency', 'html', 'dow
|
||||
| config files. Otherwise, leave it blank.
|
||||
|
|
||||
*/
|
||||
|
||||
$autoload['config'] = array();
|
||||
|
||||
|
||||
/*
|
||||
| -------------------------------------------------------------------
|
||||
| Auto-load Language files
|
||||
@@ -95,22 +117,19 @@ $autoload['config'] = array();
|
||||
| "codeigniter_lang.php" would be referenced as array('codeigniter');
|
||||
|
|
||||
*/
|
||||
|
||||
$autoload['language'] = array();
|
||||
|
||||
|
||||
/*
|
||||
| -------------------------------------------------------------------
|
||||
| Auto-load Models
|
||||
| -------------------------------------------------------------------
|
||||
| Prototype:
|
||||
|
|
||||
| $autoload['model'] = array('model1', 'model2');
|
||||
| $autoload['model'] = array('first_model', 'second_model');
|
||||
|
|
||||
| You can also supply an alternative model name to be assigned
|
||||
| in the controller:
|
||||
|
|
||||
| $autoload['model'] = array('first_model' => 'first');
|
||||
*/
|
||||
|
||||
$autoload['model'] = array('Appconfig','Person','Customer','Employee','Module','Item', 'Item_taxes', 'Sale', 'Sale_suspended', 'Supplier','Inventory','Receiving','Giftcard', 'Item_kit', 'Item_kit_items','Stock_location','Item_quantity');
|
||||
|
||||
|
||||
/* End of file autoload.php */
|
||||
/* Location: ./application/config/autoload.php */
|
||||
$autoload['model'] = array('Appconfig', 'Person', 'Customer', 'Employee', 'Module', 'Item', 'Item_taxes', 'Sale', 'Supplier', 'Inventory', 'Receiving', 'Giftcard', 'Item_kit', 'Item_kit_items', 'Stock_location', 'Item_quantity', 'Dinner_table', 'Customer_rewards', 'Rewards', 'Tax', 'Expense_category', 'Expense' );
|
||||
|
||||
@@ -1,18 +1,50 @@
|
||||
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
|
||||
<?php defined('BASEPATH') OR exit('No direct script access allowed');
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Code Version
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| This is the version of Open Source Point of Sale you're running
|
||||
|
|
||||
|
|
||||
*/
|
||||
$config['application_version'] = '3.2.0';
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Commit sha1
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| This is the commit hash for the version you are currently using
|
||||
|
|
||||
|
|
||||
*/
|
||||
$config['commit_sha1'] = '$Id $';
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Internal to OSPOS XSS Clean
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| This is to indicated whether we want XSS clean to be performed or not
|
||||
| By default it's enabled as it's assumed the installation has Internet access and needs to be protected,
|
||||
| however intranet only installations may not need this so they can set FALSE to improve performance
|
||||
|
|
||||
*/
|
||||
$config['ospos_xss_clean'] = TRUE;
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Code Version
|
||||
| Enable database query logging hook
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| This is the version of Open Source Point of Sale you're running
|
||||
|
|
||||
| Logs are stored in application/logs
|
||||
|
|
||||
*/
|
||||
$config['application_version'] = '2.3.3';
|
||||
$config['db_log_enabled'] = FALSE;
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Base Site URL
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
@@ -21,13 +53,21 @@ $config['application_version'] = '2.3.3';
|
||||
|
|
||||
| http://example.com/
|
||||
|
|
||||
| If this is not set then CodeIgniter will guess the protocol, domain and
|
||||
| path to your installation.
|
||||
| WARNING: You MUST set this value!
|
||||
|
|
||||
| If it is not set, then CodeIgniter will try guess the protocol and path
|
||||
| your installation, but due to security concerns the hostname will be set
|
||||
| to $_SERVER['SERVER_ADDR'] if available, or localhost otherwise.
|
||||
| The auto-detection mechanism exists only for convenience during
|
||||
| development and MUST NOT be used in production!
|
||||
|
|
||||
| If you need to allow multiple domains, remember that this file is still
|
||||
| a PHP script and you can easily do that on your own.
|
||||
|
|
||||
*/
|
||||
$config['base_url'] = ((isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] == "on") ? "https" : "http");
|
||||
$config['base_url'] .= "://".$_SERVER['HTTP_HOST'];
|
||||
$config['base_url'] .= str_replace(basename($_SERVER['SCRIPT_NAME']),"",$_SERVER['SCRIPT_NAME']);
|
||||
$config['base_url'] = ((isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] == 'on') || isset($_ENV['FORCE_HTTPS'])) ? 'https' : 'http';
|
||||
$config['base_url'] .= '://' . $_SERVER['HTTP_HOST'];
|
||||
$config['base_url'] .= str_replace(basename($_SERVER['SCRIPT_NAME']), '', $_SERVER['SCRIPT_NAME']);
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
@@ -39,7 +79,7 @@ $config['base_url'] .= str_replace(basename($_SERVER['SCRIPT_NAME']),"",$_SERVER
|
||||
| variable so that it is blank.
|
||||
|
|
||||
*/
|
||||
$config['index_page'] = 'index.php';
|
||||
$config['index_page'] = '';
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
@@ -47,17 +87,16 @@ $config['index_page'] = 'index.php';
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| This item determines which server global should be used to retrieve the
|
||||
| URI string. The default setting of 'AUTO' works for most servers.
|
||||
| URI string. The default setting of 'REQUEST_URI' works for most servers.
|
||||
| If your links do not seem to work, try one of the other delicious flavors:
|
||||
|
|
||||
| 'AUTO' Default - auto detects
|
||||
| 'PATH_INFO' Uses the PATH_INFO
|
||||
| 'QUERY_STRING' Uses the QUERY_STRING
|
||||
| 'REQUEST_URI' Uses the REQUEST_URI
|
||||
| 'ORIG_PATH_INFO' Uses the ORIG_PATH_INFO
|
||||
| 'REQUEST_URI' Uses $_SERVER['REQUEST_URI']
|
||||
| 'QUERY_STRING' Uses $_SERVER['QUERY_STRING']
|
||||
| 'PATH_INFO' Uses $_SERVER['PATH_INFO']
|
||||
|
|
||||
| WARNING: If you set this to 'PATH_INFO', URIs will always be URL-decoded!
|
||||
*/
|
||||
$config['uri_protocol'] = 'AUTO';
|
||||
$config['uri_protocol'] = 'REQUEST_URI';
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
@@ -67,9 +106,8 @@ $config['uri_protocol'] = 'AUTO';
|
||||
| This option allows you to add a suffix to all URLs generated by CodeIgniter.
|
||||
| For more information please see the user guide:
|
||||
|
|
||||
| http://codeigniter.com/user_guide/general/urls.html
|
||||
| https://codeigniter.com/user_guide/general/urls.html
|
||||
*/
|
||||
|
||||
$config['url_suffix'] = '';
|
||||
|
||||
/*
|
||||
@@ -82,7 +120,7 @@ $config['url_suffix'] = '';
|
||||
| than english.
|
||||
|
|
||||
*/
|
||||
$config['language'] = 'en';
|
||||
$config['language'] = 'english';
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
@@ -92,6 +130,8 @@ $config['language'] = 'en';
|
||||
| This determines which character set is used by default in various methods
|
||||
| that require a character set to be provided.
|
||||
|
|
||||
| See http://php.net/htmlspecialchars for a list of supported charsets.
|
||||
|
|
||||
*/
|
||||
$config['charset'] = 'UTF-8';
|
||||
|
||||
@@ -106,7 +146,6 @@ $config['charset'] = 'UTF-8';
|
||||
*/
|
||||
$config['enable_hooks'] = TRUE;
|
||||
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Class Extension Prefix
|
||||
@@ -115,33 +154,56 @@ $config['enable_hooks'] = TRUE;
|
||||
| This item allows you to set the filename/classname prefix when extending
|
||||
| native libraries. For more information please see the user guide:
|
||||
|
|
||||
| http://codeigniter.com/user_guide/general/core_classes.html
|
||||
| http://codeigniter.com/user_guide/general/creating_libraries.html
|
||||
| https://codeigniter.com/user_guide/general/core_classes.html
|
||||
| https://codeigniter.com/user_guide/general/creating_libraries.html
|
||||
|
|
||||
*/
|
||||
$config['subclass_prefix'] = 'MY_';
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Composer auto-loading
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| Enabling this setting will tell CodeIgniter to look for a Composer
|
||||
| package auto-loader script in application/vendor/autoload.php.
|
||||
|
|
||||
| $config['composer_autoload'] = TRUE;
|
||||
|
|
||||
| Or if you have your vendor/ directory located somewhere else, you
|
||||
| can opt to set a specific path as well:
|
||||
|
|
||||
| $config['composer_autoload'] = '/path/to/vendor/autoload.php';
|
||||
|
|
||||
| For more information about Composer, please visit http://getcomposer.org/
|
||||
|
|
||||
| Note: This will NOT disable or override the CodeIgniter-specific
|
||||
| autoloading (application/config/autoload.php)
|
||||
*/
|
||||
$config['composer_autoload'] = realpath(APPPATH . '../vendor/autoload.php');
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Allowed URL Characters
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| This lets you specify with a regular expression which characters are permitted
|
||||
| within your URLs. When someone tries to submit a URL with disallowed
|
||||
| characters they will get a warning message.
|
||||
| This lets you specify which characters are permitted within your URLs.
|
||||
| When someone tries to submit a URL with disallowed characters they will
|
||||
| get a warning message.
|
||||
|
|
||||
| As a security measure you are STRONGLY encouraged to restrict URLs to
|
||||
| as few characters as possible. By default only these are allowed: a-z 0-9~%.:_-
|
||||
|
|
||||
| Leave blank to allow all characters -- but only if you are insane.
|
||||
|
|
||||
| The configured value is actually a regular expression character group
|
||||
| and it will be executed as: ! preg_match('/^[<permitted_uri_chars>]+$/i
|
||||
|
|
||||
| DO NOT CHANGE THIS UNLESS YOU FULLY UNDERSTAND THE REPERCUSSIONS!!
|
||||
|
|
||||
*/
|
||||
$config['permitted_uri_chars'] = 'a-z 0-9~%.:_\-';
|
||||
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Enable Query Strings
|
||||
@@ -167,19 +229,17 @@ $config['permitted_uri_chars'] = 'a-z 0-9~%.:_\-';
|
||||
| use segment based URLs.
|
||||
|
|
||||
*/
|
||||
$config['allow_get_array'] = TRUE;
|
||||
$config['allow_get_array'] = TRUE;
|
||||
$config['enable_query_strings'] = FALSE;
|
||||
$config['controller_trigger'] = 'c';
|
||||
$config['function_trigger'] = 'm';
|
||||
$config['directory_trigger'] = 'd'; // experimental not currently in use
|
||||
$config['controller_trigger'] = 'c';
|
||||
$config['function_trigger'] = 'm';
|
||||
$config['directory_trigger'] = 'd';
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Error Logging Threshold
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| If you have enabled error logging, you can set an error threshold to
|
||||
| determine what gets logged. Threshold options are:
|
||||
| You can enable error logging by setting a threshold over zero. The
|
||||
| threshold determines what gets logged. Threshold options are:
|
||||
|
|
||||
@@ -189,6 +249,10 @@ $config['directory_trigger'] = 'd'; // experimental not currently in use
|
||||
| 3 = Informational Messages
|
||||
| 4 = All Messages
|
||||
|
|
||||
| You can also pass an array with threshold levels to show individual error types
|
||||
|
|
||||
| array(2) = Debug Messages, without Error Messages
|
||||
|
|
||||
| For a live site you'll usually only enable Errors (1) to be logged otherwise
|
||||
| your log files will fill up very fast.
|
||||
|
|
||||
@@ -201,11 +265,37 @@ $config['log_threshold'] = 0;
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| Leave this BLANK unless you would like to set something other than the default
|
||||
| application/logs/ folder. Use a full server path with trailing slash.
|
||||
| application/logs/ directory. Use a full server path with trailing slash.
|
||||
|
|
||||
*/
|
||||
$config['log_path'] = '';
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Log File Extension
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| The default filename extension for log files. The default 'php' allows for
|
||||
| protecting the log files via basic scripting, when they are to be stored
|
||||
| under a publicly accessible directory.
|
||||
|
|
||||
| Note: Leaving it blank will default to 'php'.
|
||||
|
|
||||
*/
|
||||
$config['log_file_extension'] = '';
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Log File Permissions
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| The file system permissions to be applied on newly created log files.
|
||||
|
|
||||
| IMPORTANT: This MUST be an integer (no quotes) and you MUST use octal
|
||||
| integer notation (i.e. 0700, 0644, etc.)
|
||||
*/
|
||||
$config['log_file_permissions'] = 0644;
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Date Format for Logs
|
||||
@@ -217,71 +307,152 @@ $config['log_path'] = '';
|
||||
*/
|
||||
$config['log_date_format'] = 'Y-m-d H:i:s';
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Error Views Directory Path
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| Leave this BLANK unless you would like to set something other than the default
|
||||
| application/views/errors/ directory. Use a full server path with trailing slash.
|
||||
|
|
||||
*/
|
||||
$config['error_views_path'] = '';
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Cache Directory Path
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| Leave this BLANK unless you would like to set something other than the default
|
||||
| system/cache/ folder. Use a full server path with trailing slash.
|
||||
| application/cache/ directory. Use a full server path with trailing slash.
|
||||
|
|
||||
*/
|
||||
$config['cache_path'] = '';
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Cache Include Query String
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| Whether to take the URL query string into consideration when generating
|
||||
| output cache files. Valid options are:
|
||||
|
|
||||
| FALSE = Disabled
|
||||
| TRUE = Enabled, take all query parameters into account.
|
||||
| Please be aware that this may result in numerous cache
|
||||
| files generated for the same page over and over again.
|
||||
| array('q') = Enabled, but only take into account the specified list
|
||||
| of query parameters.
|
||||
|
|
||||
*/
|
||||
$config['cache_query_string'] = FALSE;
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Encryption Key
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| If you use the Encryption class or the Session class you
|
||||
| MUST set an encryption key. See the user guide for info.
|
||||
| If you use the Encryption class, you must set an encryption key.
|
||||
| See the user guide for more info.
|
||||
|
|
||||
| https://codeigniter.com/user_guide/libraries/encryption.html
|
||||
|
|
||||
*/
|
||||
$config['encryption_key'] = 'PUT_YOUR_ENCRYPTION_KEY_HERE';
|
||||
$config['encryption_key'] = getenv('ENCRYPTION_KEY') ? getenv('ENCRYPTION_KEY') : '';
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Session Variables
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| 'sess_cookie_name' = the name you want for the cookie
|
||||
| 'sess_expiration' = the number of SECONDS you want the session to last.
|
||||
| by default sessions last 7200 seconds (two hours). Set to zero for no expiration.
|
||||
| 'sess_expire_on_close' = Whether to cause the session to expire automatically
|
||||
| when the browser window is closed
|
||||
| 'sess_encrypt_cookie' = Whether to encrypt the cookie
|
||||
| 'sess_use_database' = Whether to save the session data to a database
|
||||
| 'sess_table_name' = The name of the session database table
|
||||
| 'sess_match_ip' = Whether to match the user's IP address when reading the session data
|
||||
| 'sess_match_useragent' = Whether to match the User Agent when reading the session data
|
||||
| 'sess_time_to_update' = how many seconds between CI refreshing Session Information
|
||||
| 'sess_driver'
|
||||
|
|
||||
| The storage driver to use: files, database, redis, memcached
|
||||
|
|
||||
| 'sess_cookie_name'
|
||||
|
|
||||
| The session cookie name, must contain only [0-9a-z_-] characters
|
||||
|
|
||||
| 'sess_expiration'
|
||||
|
|
||||
| The number of SECONDS you want the session to last.
|
||||
| Setting to 0 (zero) means expire when the browser is closed.
|
||||
|
|
||||
| 'sess_save_path'
|
||||
|
|
||||
| The location to save sessions to, driver dependent.
|
||||
|
|
||||
| For the 'files' driver, it's a path to a writable directory.
|
||||
| WARNING: Only absolute paths are supported!
|
||||
|
|
||||
| For the 'database' driver, it's a table name.
|
||||
| Please read up the manual for the format with other session drivers.
|
||||
|
|
||||
| IMPORTANT: You are REQUIRED to set a valid save path!
|
||||
|
|
||||
| 'sess_match_ip'
|
||||
|
|
||||
| Whether to match the user's IP address when reading the session data.
|
||||
|
|
||||
| WARNING: If you're using the database driver, don't forget to update
|
||||
| your session table's PRIMARY KEY when changing this setting.
|
||||
|
|
||||
| 'sess_time_to_update'
|
||||
|
|
||||
| How many seconds between CI regenerating the session ID.
|
||||
|
|
||||
| 'sess_regenerate_destroy'
|
||||
|
|
||||
| Whether to destroy session data associated with the old session ID
|
||||
| when auto-regenerating the session ID. When set to FALSE, the data
|
||||
| will be later deleted by the garbage collector.
|
||||
|
|
||||
| Other session cookie settings are shared with the rest of the application,
|
||||
| except for 'cookie_prefix' and 'cookie_httponly', which are ignored here.
|
||||
|
|
||||
*/
|
||||
$config['sess_cookie_name'] = 'ci_session';
|
||||
$config['sess_expiration'] = 0;
|
||||
$config['sess_expire_on_close'] = FALSE;
|
||||
$config['sess_encrypt_cookie'] = FALSE;
|
||||
$config['sess_use_database'] = TRUE;
|
||||
$config['sess_table_name'] = 'sessions';
|
||||
$config['sess_match_ip'] = FALSE;
|
||||
$config['sess_match_useragent'] = FALSE;
|
||||
$config['sess_time_to_update'] = 120;
|
||||
$config['sess_driver'] = 'database';
|
||||
$config['sess_cookie_name'] = 'ospos_session';
|
||||
$config['sess_expiration'] = 7200;
|
||||
$config['sess_save_path'] = 'sessions';
|
||||
$config['sess_match_ip'] = TRUE;
|
||||
$config['sess_time_to_update'] = 300;
|
||||
$config['sess_regenerate_destroy'] = FALSE;
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Cookie Related Variables
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| 'cookie_prefix' = Set a prefix if you need to avoid collisions
|
||||
| 'cookie_domain' = Set to .your-domain.com for site-wide cookies
|
||||
| 'cookie_path' = Typically will be a forward slash
|
||||
| 'cookie_secure' = Cookies will only be set if a secure HTTPS connection exists.
|
||||
| 'cookie_prefix' = Set a cookie name prefix if you need to avoid collisions
|
||||
| 'cookie_domain' = Set to .your-domain.com for site-wide cookies
|
||||
| 'cookie_path' = Typically will be a forward slash
|
||||
| 'cookie_secure' = Cookie will only be set if a secure HTTPS connection exists.
|
||||
| 'cookie_httponly' = Cookie will only be accessible via HTTP(S) (no javascript)
|
||||
|
|
||||
| Note: These settings (with the exception of 'cookie_prefix' and
|
||||
| 'cookie_httponly') will also affect sessions.
|
||||
|
|
||||
*/
|
||||
$config['cookie_prefix'] = "";
|
||||
$config['cookie_domain'] = "";
|
||||
$config['cookie_path'] = "/";
|
||||
$config['cookie_secure'] = FALSE;
|
||||
$config['cookie_prefix'] = '';
|
||||
$config['cookie_domain'] = '';
|
||||
$config['cookie_path'] = '/';
|
||||
$config['cookie_secure'] = FALSE;
|
||||
$config['cookie_httponly'] = FALSE;
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Standardize newlines
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| Determines whether to standardize newline characters in input data,
|
||||
| meaning to replace \r\n, \r, \n occurrences with the PHP_EOL value.
|
||||
|
|
||||
| This is particularly useful for portability between UNIX-based OSes,
|
||||
| (usually \n) and Windows (\r\n).
|
||||
|
|
||||
*/
|
||||
$config['standardize_newlines'] = FALSE;
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
@@ -291,6 +462,9 @@ $config['cookie_secure'] = FALSE;
|
||||
| Determines whether the XSS filter is always active when GET, POST or
|
||||
| COOKIE data is encountered
|
||||
|
|
||||
| WARNING: This feature is DEPRECATED and currently available only
|
||||
| for backwards compatibility purposes!
|
||||
|
|
||||
*/
|
||||
$config['global_xss_filtering'] = FALSE;
|
||||
|
||||
@@ -305,11 +479,15 @@ $config['global_xss_filtering'] = FALSE;
|
||||
| 'csrf_token_name' = The token name
|
||||
| 'csrf_cookie_name' = The cookie name
|
||||
| 'csrf_expire' = The number in seconds the token should expire.
|
||||
| 'csrf_regenerate' = Regenerate token on every submission
|
||||
| 'csrf_exclude_uris' = Array of URIs which ignore CSRF checks
|
||||
*/
|
||||
$config['csrf_protection'] = FALSE;
|
||||
$config['csrf_token_name'] = 'csrf_test_name';
|
||||
$config['csrf_cookie_name'] = 'csrf_cookie_name';
|
||||
$config['csrf_protection'] = TRUE;
|
||||
$config['csrf_token_name'] = 'csrf_ospos_v3';
|
||||
$config['csrf_cookie_name'] = 'csrf_cookie_ospos_v3';
|
||||
$config['csrf_expire'] = 7200;
|
||||
$config['csrf_regenerate'] = TRUE;
|
||||
$config['csrf_exclude_uris'] = array();
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
@@ -321,6 +499,9 @@ $config['csrf_expire'] = 7200;
|
||||
| Even if it does, however, not all browsers support compression
|
||||
| so enable only if you are reasonably sure your visitors can handle it.
|
||||
|
|
||||
| Only used if zlib.output_compression is turned off in your php.ini.
|
||||
| Please do not use it together with httpd-level output compression.
|
||||
|
|
||||
| VERY IMPORTANT: If you are getting a blank page when compression is enabled it
|
||||
| means you are prematurely outputting something to your browser. It could
|
||||
| even be a line of whitespace at the end of one of your scripts. For
|
||||
@@ -330,20 +511,20 @@ $config['csrf_expire'] = 7200;
|
||||
*/
|
||||
$config['compress_output'] = FALSE;
|
||||
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Master Time Reference
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| Options are 'local' or 'gmt'. This pref tells the system whether to use
|
||||
| your server's local time as the master 'now' reference, or convert it to
|
||||
| GMT. See the 'date helper' page of the user guide for information
|
||||
| regarding date handling.
|
||||
| Options are 'local' or any PHP supported timezone. This preference tells
|
||||
| the system whether to use your server's local time as the master 'now'
|
||||
| reference, or convert it to the configured one timezone. See the 'date
|
||||
| helper' page of the user guide for information regarding date handling.
|
||||
|
|
||||
*/
|
||||
$config['time_reference'] = 'local';
|
||||
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Rewrite PHP Short Tags
|
||||
@@ -353,23 +534,25 @@ $config['time_reference'] = 'local';
|
||||
| can rewrite the tags on-the-fly, enabling you to utilize that syntax
|
||||
| in your view files. Options are TRUE or FALSE (boolean)
|
||||
|
|
||||
| Note: You need to have eval() enabled for this to work.
|
||||
|
|
||||
*/
|
||||
$config['rewrite_short_tags'] = FALSE;
|
||||
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Reverse Proxy IPs
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| If your server is behind a reverse proxy, you must whitelist the proxy IP
|
||||
| addresses from which CodeIgniter should trust the HTTP_X_FORWARDED_FOR
|
||||
| header in order to properly identify the visitor's IP address.
|
||||
| Comma-delimited, e.g. '10.0.1.200,10.0.1.201'
|
||||
| If your server is behind a reverse proxy, you must whitelist the proxy
|
||||
| IP addresses from which CodeIgniter should trust headers such as
|
||||
| HTTP_X_FORWARDED_FOR and HTTP_CLIENT_IP in order to properly identify
|
||||
| the visitor's IP address.
|
||||
|
|
||||
| You can use both an array or a comma-separated list of proxy addresses,
|
||||
| as well as specifying whole subnets. Here are a few examples:
|
||||
|
|
||||
| Comma-separated: '10.0.1.200,192.168.5.0/24'
|
||||
| Array: array('10.0.1.200', '192.168.5.0/24')
|
||||
*/
|
||||
$config['proxy_ips'] = '';
|
||||
|
||||
|
||||
/* End of file config.php */
|
||||
/* Location: ./application/config/config.php */
|
||||
|
||||
@@ -1,4 +1,17 @@
|
||||
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
|
||||
<?php
|
||||
defined('BASEPATH') OR exit('No direct script access allowed');
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Display Debug backtrace
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| If set to TRUE, a backtrace will be displayed along with php errors. If
|
||||
| error_reporting is disabled, the backtrace will not display, regardless
|
||||
| of this setting
|
||||
|
|
||||
*/
|
||||
defined('SHOW_DEBUG_BACKTRACE') OR define('SHOW_DEBUG_BACKTRACE', TRUE);
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
@@ -13,10 +26,10 @@
|
||||
| always be used to set the mode correctly.
|
||||
|
|
||||
*/
|
||||
define('FILE_READ_MODE', 0644);
|
||||
define('FILE_WRITE_MODE', 0666);
|
||||
define('DIR_READ_MODE', 0755);
|
||||
define('DIR_WRITE_MODE', 0777);
|
||||
defined('FILE_READ_MODE') OR define('FILE_READ_MODE', 0644);
|
||||
defined('FILE_WRITE_MODE') OR define('FILE_WRITE_MODE', 0666);
|
||||
defined('DIR_READ_MODE') OR define('DIR_READ_MODE', 0755);
|
||||
defined('DIR_WRITE_MODE') OR define('DIR_WRITE_MODE', 0755);
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
@@ -26,20 +39,47 @@ define('DIR_WRITE_MODE', 0777);
|
||||
| These modes are used when working with fopen()/popen()
|
||||
|
|
||||
*/
|
||||
|
||||
define('FOPEN_READ', 'rb');
|
||||
define('FOPEN_READ_WRITE', 'r+b');
|
||||
define('FOPEN_WRITE_CREATE_DESTRUCTIVE', 'wb'); // truncates existing file data, use with care
|
||||
define('FOPEN_READ_WRITE_CREATE_DESTRUCTIVE', 'w+b'); // truncates existing file data, use with care
|
||||
define('FOPEN_WRITE_CREATE', 'ab');
|
||||
define('FOPEN_READ_WRITE_CREATE', 'a+b');
|
||||
define('FOPEN_WRITE_CREATE_STRICT', 'xb');
|
||||
define('FOPEN_READ_WRITE_CREATE_STRICT', 'x+b');
|
||||
defined('FOPEN_READ') OR define('FOPEN_READ', 'rb');
|
||||
defined('FOPEN_READ_WRITE') OR define('FOPEN_READ_WRITE', 'r+b');
|
||||
defined('FOPEN_WRITE_CREATE_DESTRUCTIVE') OR define('FOPEN_WRITE_CREATE_DESTRUCTIVE', 'wb'); // truncates existing file data, use with care
|
||||
defined('FOPEN_READ_WRITE_CREATE_DESTRUCTIVE') OR define('FOPEN_READ_WRITE_CREATE_DESTRUCTIVE', 'w+b'); // truncates existing file data, use with care
|
||||
defined('FOPEN_WRITE_CREATE') OR define('FOPEN_WRITE_CREATE', 'ab');
|
||||
defined('FOPEN_READ_WRITE_CREATE') OR define('FOPEN_READ_WRITE_CREATE', 'a+b');
|
||||
defined('FOPEN_WRITE_CREATE_STRICT') OR define('FOPEN_WRITE_CREATE_STRICT', 'xb');
|
||||
defined('FOPEN_READ_WRITE_CREATE_STRICT') OR define('FOPEN_READ_WRITE_CREATE_STRICT', 'x+b');
|
||||
|
||||
/*
|
||||
| Precision for calculations performed on decimals
|
||||
*/
|
||||
define("PRECISION", 5);
|
||||
|
||||
/* End of file constants.php */
|
||||
/* Location: ./application/config/constants.php */
|
||||
|--------------------------------------------------------------------------
|
||||
| Exit Status Codes
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| Used to indicate the conditions under which the script is exit()ing.
|
||||
| While there is no universal standard for error codes, there are some
|
||||
| broad conventions. Three such conventions are mentioned below, for
|
||||
| those who wish to make use of them. The CodeIgniter defaults were
|
||||
| chosen for the least overlap with these conventions, while still
|
||||
| leaving room for others to be defined in future versions and user
|
||||
| applications.
|
||||
|
|
||||
| The three main conventions used for determining exit status codes
|
||||
| are as follows:
|
||||
|
|
||||
| Standard C/C++ Library (stdlibc):
|
||||
| http://www.gnu.org/software/libc/manual/html_node/Exit-Status.html
|
||||
| (This link also contains other GNU-specific conventions)
|
||||
| BSD sysexits.h:
|
||||
| http://www.gsp.com/cgi-bin/man.cgi?section=3&topic=sysexits
|
||||
| Bash scripting:
|
||||
| http://tldp.org/LDP/abs/html/exitcodes.html
|
||||
|
|
||||
*/
|
||||
defined('EXIT_SUCCESS') OR define('EXIT_SUCCESS', 0); // no errors
|
||||
defined('EXIT_ERROR') OR define('EXIT_ERROR', 1); // generic error
|
||||
defined('EXIT_CONFIG') OR define('EXIT_CONFIG', 3); // configuration error
|
||||
defined('EXIT_UNKNOWN_FILE') OR define('EXIT_UNKNOWN_FILE', 4); // file not found
|
||||
defined('EXIT_UNKNOWN_CLASS') OR define('EXIT_UNKNOWN_CLASS', 5); // unknown class
|
||||
defined('EXIT_UNKNOWN_METHOD') OR define('EXIT_UNKNOWN_METHOD', 6); // unknown class member
|
||||
defined('EXIT_USER_INPUT') OR define('EXIT_USER_INPUT', 7); // invalid user input
|
||||
defined('EXIT_DATABASE') OR define('EXIT_DATABASE', 8); // database error
|
||||
defined('EXIT__AUTO_MIN') OR define('EXIT__AUTO_MIN', 9); // lowest automatically-assigned error code
|
||||
defined('EXIT__AUTO_MAX') OR define('EXIT__AUTO_MAX', 125); // highest automatically-assigned error code
|
||||
|
||||
96
application/config/database.php
Normal file
96
application/config/database.php
Normal file
@@ -0,0 +1,96 @@
|
||||
<?php
|
||||
defined('BASEPATH') OR exit('No direct script access allowed');
|
||||
|
||||
/*
|
||||
| -------------------------------------------------------------------
|
||||
| DATABASE CONNECTIVITY SETTINGS
|
||||
| -------------------------------------------------------------------
|
||||
| This file will contain the settings needed to access your database.
|
||||
|
|
||||
| For complete instructions please consult the 'Database Connection'
|
||||
| page of the User Guide.
|
||||
|
|
||||
| -------------------------------------------------------------------
|
||||
| EXPLANATION OF VARIABLES
|
||||
| -------------------------------------------------------------------
|
||||
|
|
||||
| ['dsn'] The full DSN string describe a connection to the database.
|
||||
| ['hostname'] The hostname of your database server.
|
||||
| ['username'] The username used to connect to the database
|
||||
| ['password'] The password used to connect to the database
|
||||
| ['database'] The name of the database you want to connect to
|
||||
| ['dbdriver'] The database driver. e.g.: mysqli.
|
||||
| Currently supported:
|
||||
| cubrid, ibase, mssql, mysql, mysqli, oci8,
|
||||
| odbc, pdo, postgre, sqlite, sqlite3, sqlsrv
|
||||
| ['dbprefix'] You can add an optional prefix, which will be added
|
||||
| to the table name when using the Query Builder class
|
||||
| ['pconnect'] TRUE/FALSE - Whether to use a persistent connection
|
||||
| ['db_debug'] TRUE/FALSE - Whether database errors should be displayed.
|
||||
| ['cache_on'] TRUE/FALSE - Enables/disables query caching
|
||||
| ['cachedir'] The path to the folder where cache files should be stored
|
||||
| ['char_set'] The character set used in communicating with the database
|
||||
| ['dbcollat'] The character collation used in communicating with the database
|
||||
| NOTE: For MySQL and MySQLi databases, this setting is only used
|
||||
| as a backup if your server is running PHP < 5.2.3 or MySQL < 5.0.7
|
||||
| (and in table creation queries made with DB Forge).
|
||||
| There is an incompatibility in PHP with mysql_real_escape_string() which
|
||||
| can make your site vulnerable to SQL injection if you are using a
|
||||
| multi-byte character set and are running versions lower than these.
|
||||
| Sites using Latin-1 or UTF-8 database character set and collation are unaffected.
|
||||
| ['swap_pre'] A default table prefix that should be swapped with the dbprefix
|
||||
| ['encrypt'] Whether or not to use an encrypted connection.
|
||||
|
|
||||
| 'mysql' (deprecated), 'sqlsrv' and 'pdo/sqlsrv' drivers accept TRUE/FALSE
|
||||
| 'mysqli' and 'pdo/mysql' drivers accept an array with the following options:
|
||||
|
|
||||
| 'ssl_key' - Path to the private key file
|
||||
| 'ssl_cert' - Path to the public key certificate file
|
||||
| 'ssl_ca' - Path to the certificate authority file
|
||||
| 'ssl_capath' - Path to a directory containing trusted CA certificats in PEM format
|
||||
| 'ssl_cipher' - List of *allowed* ciphers to be used for the encryption, separated by colons (':')
|
||||
| 'ssl_verify' - TRUE/FALSE; Whether verify the server certificate or not ('mysqli' only)
|
||||
|
|
||||
| ['compress'] Whether or not to use client compression (MySQL only)
|
||||
| ['stricton'] TRUE/FALSE - forces 'Strict Mode' connections
|
||||
| - good for ensuring strict SQL while developing
|
||||
| ['ssl_options'] Used to set various SSL options that can be used when making SSL connections.
|
||||
| ['failover'] array - A array with 0 or more data for connections if the main should fail.
|
||||
| ['save_queries'] TRUE/FALSE - Whether to "save" all executed queries.
|
||||
| NOTE: Disabling this will also effectively disable both
|
||||
| $this->db->last_query() and profiling of DB queries.
|
||||
| When you run a query, with this setting set to TRUE (default),
|
||||
| CodeIgniter will store the SQL statement for debugging purposes.
|
||||
| However, this may cause high memory usage, especially if you run
|
||||
| a lot of SQL queries ... disable this to avoid that problem.
|
||||
|
|
||||
| The $active_group variable lets you choose which connection group to
|
||||
| make active. By default there is only one group (the 'default' group).
|
||||
|
|
||||
| The $query_builder variables lets you determine whether or not to load
|
||||
| the query builder class.
|
||||
*/
|
||||
$active_group = 'default';
|
||||
$query_builder = TRUE;
|
||||
|
||||
$db['default'] = array(
|
||||
'dsn' => '',
|
||||
'hostname' => !empty(getenv('MYSQL_HOST_NAME')) ? getenv('MYSQL_HOST_NAME') : 'localhost',
|
||||
'username' => !empty(getenv('MYSQL_USERNAME')) ? getenv('MYSQL_USERNAME') : 'admin',
|
||||
'password' => !empty(getenv('MYSQL_PASSWORD')) ? getenv('MYSQL_PASSWORD') : 'pointofsale',
|
||||
'database' => !empty(getenv('MYSQL_DB_NAME')) ? getenv('MYSQL_DB_NAME') : 'ospos',
|
||||
'dbdriver' => 'mysqli',
|
||||
'dbprefix' => 'ospos_',
|
||||
'pconnect' => FALSE,
|
||||
'db_debug' => (ENVIRONMENT !== 'production'),
|
||||
'cache_on' => FALSE,
|
||||
'cachedir' => '',
|
||||
'char_set' => 'utf8',
|
||||
'dbcollat' => 'utf8_general_ci',
|
||||
'swap_pre' => '',
|
||||
'encrypt' => FALSE,
|
||||
'compress' => FALSE,
|
||||
'stricton' => FALSE,
|
||||
'failover' => array(),
|
||||
'save_queries' => TRUE
|
||||
);
|
||||
@@ -1,69 +0,0 @@
|
||||
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
|
||||
/*
|
||||
| -------------------------------------------------------------------
|
||||
| DATABASE CONNECTIVITY SETTINGS
|
||||
| -------------------------------------------------------------------
|
||||
| This file will contain the settings needed to access your database.
|
||||
|
|
||||
| For complete instructions please consult the 'Database Connection'
|
||||
| page of the User Guide.
|
||||
|
|
||||
| -------------------------------------------------------------------
|
||||
| EXPLANATION OF VARIABLES
|
||||
| -------------------------------------------------------------------
|
||||
|
|
||||
| ['hostname'] The hostname of your database server.
|
||||
| ['username'] The username used to connect to the database
|
||||
| ['password'] The password used to connect to the database
|
||||
| ['database'] The name of the database you want to connect to
|
||||
| ['dbdriver'] The database type. ie: mysql. Currently supported:
|
||||
mysql, mysqli, postgre, odbc, mssql, sqlite, oci8
|
||||
| ['dbprefix'] You can add an optional prefix, which will be added
|
||||
| to the table name when using the Active Record class
|
||||
| ['pconnect'] TRUE/FALSE - Whether to use a persistent connection
|
||||
| ['db_debug'] TRUE/FALSE - Whether database errors should be displayed.
|
||||
| ['cache_on'] TRUE/FALSE - Enables/disables query caching
|
||||
| ['cachedir'] The path to the folder where cache files should be stored
|
||||
| ['char_set'] The character set used in communicating with the database
|
||||
| ['dbcollat'] The character collation used in communicating with the database
|
||||
| NOTE: For MySQL and MySQLi databases, this setting is only used
|
||||
| as a backup if your server is running PHP < 5.2.3 or MySQL < 5.0.7
|
||||
| (and in table creation queries made with DB Forge).
|
||||
| There is an incompatibility in PHP with mysql_real_escape_string() which
|
||||
| can make your site vulnerable to SQL injection if you are using a
|
||||
| multi-byte character set and are running versions lower than these.
|
||||
| Sites using Latin-1 or UTF-8 database character set and collation are unaffected.
|
||||
| ['swap_pre'] A default table prefix that should be swapped with the dbprefix
|
||||
| ['autoinit'] Whether or not to automatically initialize the database.
|
||||
| ['stricton'] TRUE/FALSE - forces 'Strict Mode' connections
|
||||
| - good for ensuring strict SQL while developing
|
||||
|
|
||||
| The $active_group variable lets you choose which connection group to
|
||||
| make active. By default there is only one group (the 'default' group).
|
||||
|
|
||||
| The $active_record variables lets you determine whether or not to load
|
||||
| the active record class
|
||||
*/
|
||||
|
||||
$active_group = 'default';
|
||||
$active_record = TRUE;
|
||||
|
||||
$db['default']['hostname'] = 'localhost';
|
||||
$db['default']['username'] = 'root';
|
||||
$db['default']['password'] = '';
|
||||
$db['default']['database'] = 'ospos';
|
||||
$db['default']['dbdriver'] = 'mysql';
|
||||
$db['default']['dbprefix'] = 'ospos_';
|
||||
$db['default']['pconnect'] = FALSE;
|
||||
$db['default']['db_debug'] = TRUE;
|
||||
$db['default']['cache_on'] = FALSE;
|
||||
$db['default']['cachedir'] = '';
|
||||
$db['default']['char_set'] = 'utf8';
|
||||
$db['default']['dbcollat'] = 'utf8_general_ci';
|
||||
$db['default']['swap_pre'] = '';
|
||||
$db['default']['autoinit'] = TRUE;
|
||||
$db['default']['stricton'] = FALSE;
|
||||
|
||||
|
||||
/* End of file database.php */
|
||||
/* Location: ./application/config/database.php */
|
||||
@@ -1,15 +1,24 @@
|
||||
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
|
||||
<?php
|
||||
defined('BASEPATH') OR exit('No direct script access allowed');
|
||||
|
||||
$_doctypes = array(
|
||||
'xhtml11' => '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">',
|
||||
'xhtml1-strict' => '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">',
|
||||
'xhtml1-trans' => '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">',
|
||||
'xhtml1-frame' => '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Frameset//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-frameset.dtd">',
|
||||
'html5' => '<!DOCTYPE html>',
|
||||
'html4-strict' => '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">',
|
||||
'html4-trans' => '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">',
|
||||
'html4-frame' => '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Frameset//EN" "http://www.w3.org/TR/html4/frameset.dtd">'
|
||||
);
|
||||
|
||||
/* End of file doctypes.php */
|
||||
/* Location: ./application/config/doctypes.php */
|
||||
'xhtml11' => '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">',
|
||||
'xhtml1-strict' => '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">',
|
||||
'xhtml1-trans' => '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">',
|
||||
'xhtml1-frame' => '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Frameset//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-frameset.dtd">',
|
||||
'xhtml-basic11' => '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML Basic 1.1//EN" "http://www.w3.org/TR/xhtml-basic/xhtml-basic11.dtd">',
|
||||
'html5' => '<!DOCTYPE html>',
|
||||
'html4-strict' => '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">',
|
||||
'html4-trans' => '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">',
|
||||
'html4-frame' => '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Frameset//EN" "http://www.w3.org/TR/html4/frameset.dtd">',
|
||||
'mathml1' => '<!DOCTYPE math SYSTEM "http://www.w3.org/Math/DTD/mathml1/mathml.dtd">',
|
||||
'mathml2' => '<!DOCTYPE math PUBLIC "-//W3C//DTD MathML 2.0//EN" "http://www.w3.org/Math/DTD/mathml2/mathml2.dtd">',
|
||||
'svg10' => '<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.0//EN" "http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">',
|
||||
'svg11' => '<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">',
|
||||
'svg11-basic' => '<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1 Basic//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11-basic.dtd">',
|
||||
'svg11-tiny' => '<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1 Tiny//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11-tiny.dtd">',
|
||||
'xhtml-math-svg-xh' => '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1 plus MathML 2.0 plus SVG 1.1//EN" "http://www.w3.org/2002/04/xhtml-math-svg/xhtml-math-svg.dtd">',
|
||||
'xhtml-math-svg-sh' => '<!DOCTYPE svg:svg PUBLIC "-//W3C//DTD XHTML 1.1 plus MathML 2.0 plus SVG 1.1//EN" "http://www.w3.org/2002/04/xhtml-math-svg/xhtml-math-svg.dtd">',
|
||||
'xhtml-rdfa-1' => '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML+RDFa 1.0//EN" "http://www.w3.org/MarkUp/DTD/xhtml-rdfa-1.dtd">',
|
||||
'xhtml-rdfa-2' => '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML+RDFa 1.1//EN" "http://www.w3.org/MarkUp/DTD/xhtml-rdfa-2.dtd">'
|
||||
);
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
|
||||
<?php
|
||||
defined('BASEPATH') OR exit('No direct script access allowed');
|
||||
|
||||
/*
|
||||
| -------------------------------------------------------------------
|
||||
| Foreign Characters
|
||||
@@ -14,51 +16,88 @@ $foreign_characters = array(
|
||||
'/Ä/' => 'Ae',
|
||||
'/Ü/' => 'Ue',
|
||||
'/Ö/' => 'Oe',
|
||||
'/À|Á|Â|Ã|Ä|Å|Ǻ|Ā|Ă|Ą|Ǎ/' => 'A',
|
||||
'/à|á|â|ã|å|ǻ|ā|ă|ą|ǎ|ª/' => 'a',
|
||||
'/À|Á|Â|Ã|Ä|Å|Ǻ|Ā|Ă|Ą|Ǎ|Α|Ά|Ả|Ạ|Ầ|Ẫ|Ẩ|Ậ|Ằ|Ắ|Ẵ|Ẳ|Ặ|А/' => 'A',
|
||||
'/à|á|â|ã|å|ǻ|ā|ă|ą|ǎ|ª|α|ά|ả|ạ|ầ|ấ|ẫ|ẩ|ậ|ằ|ắ|ẵ|ẳ|ặ|а/' => 'a',
|
||||
'/Б/' => 'B',
|
||||
'/б/' => 'b',
|
||||
'/Ç|Ć|Ĉ|Ċ|Č/' => 'C',
|
||||
'/ç|ć|ĉ|ċ|č/' => 'c',
|
||||
'/Ð|Ď|Đ/' => 'D',
|
||||
'/ð|ď|đ/' => 'd',
|
||||
'/È|É|Ê|Ë|Ē|Ĕ|Ė|Ę|Ě/' => 'E',
|
||||
'/è|é|ê|ë|ē|ĕ|ė|ę|ě/' => 'e',
|
||||
'/Ĝ|Ğ|Ġ|Ģ/' => 'G',
|
||||
'/ĝ|ğ|ġ|ģ/' => 'g',
|
||||
'/Д/' => 'D',
|
||||
'/д/' => 'd',
|
||||
'/Ð|Ď|Đ|Δ/' => 'Dj',
|
||||
'/ð|ď|đ|δ/' => 'dj',
|
||||
'/È|É|Ê|Ë|Ē|Ĕ|Ė|Ę|Ě|Ε|Έ|Ẽ|Ẻ|Ẹ|Ề|Ế|Ễ|Ể|Ệ|Е|Э/' => 'E',
|
||||
'/è|é|ê|ë|ē|ĕ|ė|ę|ě|έ|ε|ẽ|ẻ|ẹ|ề|ế|ễ|ể|ệ|е|э/' => 'e',
|
||||
'/Ф/' => 'F',
|
||||
'/ф/' => 'f',
|
||||
'/Ĝ|Ğ|Ġ|Ģ|Γ|Г|Ґ/' => 'G',
|
||||
'/ĝ|ğ|ġ|ģ|γ|г|ґ/' => 'g',
|
||||
'/Ĥ|Ħ/' => 'H',
|
||||
'/ĥ|ħ/' => 'h',
|
||||
'/Ì|Í|Î|Ï|Ĩ|Ī|Ĭ|Ǐ|Į|İ/' => 'I',
|
||||
'/ì|í|î|ï|ĩ|ī|ĭ|ǐ|į|ı/' => 'i',
|
||||
'/Ì|Í|Î|Ï|Ĩ|Ī|Ĭ|Ǐ|Į|İ|Η|Ή|Ί|Ι|Ϊ|Ỉ|Ị|И|Ы/' => 'I',
|
||||
'/ì|í|î|ï|ĩ|ī|ĭ|ǐ|į|ı|η|ή|ί|ι|ϊ|ỉ|ị|и|ы|ї/' => 'i',
|
||||
'/Ĵ/' => 'J',
|
||||
'/ĵ/' => 'j',
|
||||
'/Ķ/' => 'K',
|
||||
'/ķ/' => 'k',
|
||||
'/Ĺ|Ļ|Ľ|Ŀ|Ł/' => 'L',
|
||||
'/ĺ|ļ|ľ|ŀ|ł/' => 'l',
|
||||
'/Ñ|Ń|Ņ|Ň/' => 'N',
|
||||
'/ñ|ń|ņ|ň|ʼn/' => 'n',
|
||||
'/Ò|Ó|Ô|Õ|Ō|Ŏ|Ǒ|Ő|Ơ|Ø|Ǿ/' => 'O',
|
||||
'/ò|ó|ô|õ|ō|ŏ|ǒ|ő|ơ|ø|ǿ|º/' => 'o',
|
||||
'/Ŕ|Ŗ|Ř/' => 'R',
|
||||
'/ŕ|ŗ|ř/' => 'r',
|
||||
'/Ś|Ŝ|Ş|Š/' => 'S',
|
||||
'/ś|ŝ|ş|š|ſ/' => 's',
|
||||
'/Ţ|Ť|Ŧ/' => 'T',
|
||||
'/ţ|ť|ŧ/' => 't',
|
||||
'/Ù|Ú|Û|Ũ|Ū|Ŭ|Ů|Ű|Ų|Ư|Ǔ|Ǖ|Ǘ|Ǚ|Ǜ/' => 'U',
|
||||
'/ù|ú|û|ũ|ū|ŭ|ů|ű|ų|ư|ǔ|ǖ|ǘ|ǚ|ǜ/' => 'u',
|
||||
'/Ý|Ÿ|Ŷ/' => 'Y',
|
||||
'/ý|ÿ|ŷ/' => 'y',
|
||||
'/Ķ|Κ|К/' => 'K',
|
||||
'/ķ|κ|к/' => 'k',
|
||||
'/Ĺ|Ļ|Ľ|Ŀ|Ł|Λ|Л/' => 'L',
|
||||
'/ĺ|ļ|ľ|ŀ|ł|λ|л/' => 'l',
|
||||
'/М/' => 'M',
|
||||
'/м/' => 'm',
|
||||
'/Ñ|Ń|Ņ|Ň|Ν|Н/' => 'N',
|
||||
'/ñ|ń|ņ|ň|ʼn|ν|н/' => 'n',
|
||||
'/Ò|Ó|Ô|Õ|Ō|Ŏ|Ǒ|Ő|Ơ|Ø|Ǿ|Ο|Ό|Ω|Ώ|Ỏ|Ọ|Ồ|Ố|Ỗ|Ổ|Ộ|Ờ|Ớ|Ỡ|Ở|Ợ|О/' => 'O',
|
||||
'/ò|ó|ô|õ|ō|ŏ|ǒ|ő|ơ|ø|ǿ|º|ο|ό|ω|ώ|ỏ|ọ|ồ|ố|ỗ|ổ|ộ|ờ|ớ|ỡ|ở|ợ|о/' => 'o',
|
||||
'/П/' => 'P',
|
||||
'/п/' => 'p',
|
||||
'/Ŕ|Ŗ|Ř|Ρ|Р/' => 'R',
|
||||
'/ŕ|ŗ|ř|ρ|р/' => 'r',
|
||||
'/Ś|Ŝ|Ş|Ș|Š|Σ|С/' => 'S',
|
||||
'/ś|ŝ|ş|ș|š|ſ|σ|ς|с/' => 's',
|
||||
'/Ț|Ţ|Ť|Ŧ|τ|Т/' => 'T',
|
||||
'/ț|ţ|ť|ŧ|т/' => 't',
|
||||
'/Þ|þ/' => 'th',
|
||||
'/Ù|Ú|Û|Ũ|Ū|Ŭ|Ů|Ű|Ų|Ư|Ǔ|Ǖ|Ǘ|Ǚ|Ǜ|Ũ|Ủ|Ụ|Ừ|Ứ|Ữ|Ử|Ự|У/' => 'U',
|
||||
'/ù|ú|û|ũ|ū|ŭ|ů|ű|ų|ư|ǔ|ǖ|ǘ|ǚ|ǜ|υ|ύ|ϋ|ủ|ụ|ừ|ứ|ữ|ử|ự|у/' => 'u',
|
||||
'/Ý|Ÿ|Ŷ|Υ|Ύ|Ϋ|Ỳ|Ỹ|Ỷ|Ỵ|Й/' => 'Y',
|
||||
'/ý|ÿ|ŷ|ỳ|ỹ|ỷ|ỵ|й/' => 'y',
|
||||
'/В/' => 'V',
|
||||
'/в/' => 'v',
|
||||
'/Ŵ/' => 'W',
|
||||
'/ŵ/' => 'w',
|
||||
'/Ź|Ż|Ž/' => 'Z',
|
||||
'/ź|ż|ž/' => 'z',
|
||||
'/Ź|Ż|Ž|Ζ|З/' => 'Z',
|
||||
'/ź|ż|ž|ζ|з/' => 'z',
|
||||
'/Æ|Ǽ/' => 'AE',
|
||||
'/ß/'=> 'ss',
|
||||
'/ß/' => 'ss',
|
||||
'/IJ/' => 'IJ',
|
||||
'/ij/' => 'ij',
|
||||
'/Œ/' => 'OE',
|
||||
'/ƒ/' => 'f'
|
||||
'/ƒ/' => 'f',
|
||||
'/ξ/' => 'ks',
|
||||
'/π/' => 'p',
|
||||
'/β/' => 'v',
|
||||
'/μ/' => 'm',
|
||||
'/ψ/' => 'ps',
|
||||
'/Ё/' => 'Yo',
|
||||
'/ё/' => 'yo',
|
||||
'/Є/' => 'Ye',
|
||||
'/є/' => 'ye',
|
||||
'/Ї/' => 'Yi',
|
||||
'/Ж/' => 'Zh',
|
||||
'/ж/' => 'zh',
|
||||
'/Х/' => 'Kh',
|
||||
'/х/' => 'kh',
|
||||
'/Ц/' => 'Ts',
|
||||
'/ц/' => 'ts',
|
||||
'/Ч/' => 'Ch',
|
||||
'/ч/' => 'ch',
|
||||
'/Ш/' => 'Sh',
|
||||
'/ш/' => 'sh',
|
||||
'/Щ/' => 'Shch',
|
||||
'/щ/' => 'shch',
|
||||
'/Ъ|ъ|Ь|ь/' => '',
|
||||
'/Ю/' => 'Yu',
|
||||
'/ю/' => 'yu',
|
||||
'/Я/' => 'Ya',
|
||||
'/я/' => 'ya'
|
||||
);
|
||||
|
||||
/* End of file foreign_chars.php */
|
||||
/* Location: ./application/config/foreign_chars.php */
|
||||
@@ -1,4 +1,6 @@
|
||||
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
|
||||
<?php
|
||||
defined('BASEPATH') OR exit('No direct script access allowed');
|
||||
|
||||
/*
|
||||
| -------------------------------------------------------------------------
|
||||
| Hooks
|
||||
@@ -6,14 +8,30 @@
|
||||
| This file lets you define "hooks" to extend CI without hacking the core
|
||||
| files. Please see the user guide for info:
|
||||
|
|
||||
| http://codeigniter.com/user_guide/general/hooks.html
|
||||
| https://codeigniter.com/user_guide/general/hooks.html
|
||||
|
|
||||
*/
|
||||
$hook['post_controller_constructor'] = array(
|
||||
'class' => '',
|
||||
'function' => 'load_config',
|
||||
'filename' => 'load_config.php',
|
||||
'filepath' => 'hooks'
|
||||
$hook['post_controller_constructor'][] = array(
|
||||
'class' => '',
|
||||
'function' => 'load_config',
|
||||
'filename' => 'load_config.php',
|
||||
'filepath' => 'hooks'
|
||||
);
|
||||
/* End of file hooks.php */
|
||||
/* Location: ./application/config/hooks.php */
|
||||
|
||||
// 'post_controller' indicated execution of hooks after controller is finished
|
||||
$hook['post_controller'] = array(
|
||||
'class' => '',
|
||||
'function' => 'db_log_queries',
|
||||
'filename' => 'db_log.php',
|
||||
'filepath' => 'hooks'
|
||||
);
|
||||
|
||||
$hook['pre_system'] = function() {
|
||||
$config_path = APPPATH . 'config/';
|
||||
try {
|
||||
$dotenv = new Dotenv\Dotenv($config_path);
|
||||
$dotenv->overload();
|
||||
} catch(Exception $e) {
|
||||
// continue, .env file not present
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>403 Forbidden</title>
|
||||
@@ -7,4 +8,4 @@
|
||||
<p>Directory access is forbidden.</p>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
</html>
|
||||
|
||||
19
application/config/memcached.php
Normal file
19
application/config/memcached.php
Normal file
@@ -0,0 +1,19 @@
|
||||
<?php
|
||||
defined('BASEPATH') OR exit('No direct script access allowed');
|
||||
|
||||
/*
|
||||
| -------------------------------------------------------------------------
|
||||
| Memcached settings
|
||||
| -------------------------------------------------------------------------
|
||||
| Your Memcached servers can be specified below.
|
||||
|
|
||||
| See: https://codeigniter.com/user_guide/libraries/caching.html#memcached
|
||||
|
|
||||
*/
|
||||
$config = array(
|
||||
'default' => array(
|
||||
'hostname' => '127.0.0.1',
|
||||
'port' => '11211',
|
||||
'weight' => '1',
|
||||
),
|
||||
);
|
||||
@@ -1,40 +1,84 @@
|
||||
<?php defined('BASEPATH') OR exit('No direct script access allowed');
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Enable/Disable Migrations
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| Migrations are disabled by default but should be enabled
|
||||
| whenever you intend to do a schema migration.
|
||||
|
|
||||
*/
|
||||
$config['migration_enabled'] = FALSE;
|
||||
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Migrations version
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| This is used to set migration version that the file system should be on.
|
||||
| If you run $this->migration->latest() this is the version that schema will
|
||||
| be upgraded / downgraded to.
|
||||
|
|
||||
*/
|
||||
$config['migration_version'] = 0;
|
||||
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Migrations Path
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| Path to your migrations folder.
|
||||
| Typically, it will be within your application path.
|
||||
| Also, writing permission is required within the migrations path.
|
||||
|
|
||||
*/
|
||||
$config['migration_path'] = APPPATH . 'migrations/';
|
||||
|
||||
|
||||
/* End of file migration.php */
|
||||
<?php
|
||||
defined('BASEPATH') OR exit('No direct script access allowed');
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Enable/Disable Migrations
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| Migrations are disabled by default for security reasons.
|
||||
| You should enable migrations whenever you intend to do a schema migration
|
||||
| and disable it back when you're done.
|
||||
|
|
||||
*/
|
||||
$config['migration_enabled'] = TRUE;
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Migration Type
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| Migration file names may be based on a sequential identifier or on
|
||||
| a timestamp. Options are:
|
||||
|
|
||||
| 'sequential' = Sequential migration naming (001_add_blog.php)
|
||||
| 'timestamp' = Timestamp migration naming (20121031104401_add_blog.php)
|
||||
| Use timestamp format YYYYMMDDHHIISS.
|
||||
|
|
||||
| Note: If this configuration value is missing the Migration library
|
||||
| defaults to 'sequential' for backward compatibility with CI2.
|
||||
|
|
||||
*/
|
||||
$config['migration_type'] = 'timestamp';
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Migrations table
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| This is the name of the table that will store the current migrations state.
|
||||
| When migrations runs it will store in a database table which migration
|
||||
| level the system is at. It then compares the migration level in this
|
||||
| table to the $config['migration_version'] if they are not the same it
|
||||
| will migrate up. This must be set.
|
||||
|
|
||||
*/
|
||||
$config['migration_table'] = 'migrations';
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Auto Migrate To Latest
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| If this is set to TRUE when you load the migrations class and have
|
||||
| $config['migration_enabled'] set to TRUE the system will auto migrate
|
||||
| to your latest migration (whatever $config['migration_version'] is
|
||||
| set to). This way you do not have to call migrations anywhere else
|
||||
| in your code to have the latest migration.
|
||||
|
|
||||
*/
|
||||
$config['migration_auto_latest'] = FALSE;
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Migrations version
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| This is used to set migration version that the file system should be on.
|
||||
| If you run $this->migration->current() this is the version that schema will
|
||||
| be upgraded / downgraded to.
|
||||
|
|
||||
*/
|
||||
$config['migration_version'] = 20171126100000;
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Migrations Path
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| Path to your migrations folder.
|
||||
| Typically, it will be within your application path.
|
||||
| Also, writing permission is required within the migrations path.
|
||||
|
|
||||
*/
|
||||
$config['migration_path'] = APPPATH.'migrations/';
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
|
||||
<?php
|
||||
defined('BASEPATH') OR exit('No direct script access allowed');
|
||||
|
||||
/*
|
||||
| -------------------------------------------------------------------
|
||||
| MIME TYPES
|
||||
@@ -7,100 +9,159 @@
|
||||
| Upload class to help identify allowed file types.
|
||||
|
|
||||
*/
|
||||
|
||||
$mimes = array( 'hqx' => 'application/mac-binhex40',
|
||||
'cpt' => 'application/mac-compactpro',
|
||||
'csv' => array('text/x-comma-separated-values', 'text/comma-separated-values', 'application/octet-stream', 'application/vnd.ms-excel', 'application/x-csv', 'text/x-csv', 'text/csv', 'application/csv', 'application/excel', 'application/vnd.msexcel'),
|
||||
'bin' => 'application/macbinary',
|
||||
'dms' => 'application/octet-stream',
|
||||
'lha' => 'application/octet-stream',
|
||||
'lzh' => 'application/octet-stream',
|
||||
'exe' => array('application/octet-stream', 'application/x-msdownload'),
|
||||
'class' => 'application/octet-stream',
|
||||
'psd' => 'application/x-photoshop',
|
||||
'so' => 'application/octet-stream',
|
||||
'sea' => 'application/octet-stream',
|
||||
'dll' => 'application/octet-stream',
|
||||
'oda' => 'application/oda',
|
||||
'pdf' => array('application/pdf', 'application/x-download'),
|
||||
'ai' => 'application/postscript',
|
||||
'eps' => 'application/postscript',
|
||||
'ps' => 'application/postscript',
|
||||
'smi' => 'application/smil',
|
||||
'smil' => 'application/smil',
|
||||
'mif' => 'application/vnd.mif',
|
||||
'xls' => array('application/excel', 'application/vnd.ms-excel', 'application/msexcel'),
|
||||
'ppt' => array('application/powerpoint', 'application/vnd.ms-powerpoint'),
|
||||
'wbxml' => 'application/wbxml',
|
||||
'wmlc' => 'application/wmlc',
|
||||
'dcr' => 'application/x-director',
|
||||
'dir' => 'application/x-director',
|
||||
'dxr' => 'application/x-director',
|
||||
'dvi' => 'application/x-dvi',
|
||||
'gtar' => 'application/x-gtar',
|
||||
'gz' => 'application/x-gzip',
|
||||
'php' => 'application/x-httpd-php',
|
||||
'php4' => 'application/x-httpd-php',
|
||||
'php3' => 'application/x-httpd-php',
|
||||
'phtml' => 'application/x-httpd-php',
|
||||
'phps' => 'application/x-httpd-php-source',
|
||||
'js' => 'application/x-javascript',
|
||||
'swf' => 'application/x-shockwave-flash',
|
||||
'sit' => 'application/x-stuffit',
|
||||
'tar' => 'application/x-tar',
|
||||
'tgz' => array('application/x-tar', 'application/x-gzip-compressed'),
|
||||
'xhtml' => 'application/xhtml+xml',
|
||||
'xht' => 'application/xhtml+xml',
|
||||
'zip' => array('application/x-zip', 'application/zip', 'application/x-zip-compressed'),
|
||||
'mid' => 'audio/midi',
|
||||
'midi' => 'audio/midi',
|
||||
'mpga' => 'audio/mpeg',
|
||||
'mp2' => 'audio/mpeg',
|
||||
'mp3' => array('audio/mpeg', 'audio/mpg', 'audio/mpeg3', 'audio/mp3'),
|
||||
'aif' => 'audio/x-aiff',
|
||||
'aiff' => 'audio/x-aiff',
|
||||
'aifc' => 'audio/x-aiff',
|
||||
'ram' => 'audio/x-pn-realaudio',
|
||||
'rm' => 'audio/x-pn-realaudio',
|
||||
'rpm' => 'audio/x-pn-realaudio-plugin',
|
||||
'ra' => 'audio/x-realaudio',
|
||||
'rv' => 'video/vnd.rn-realvideo',
|
||||
'wav' => array('audio/x-wav', 'audio/wave', 'audio/wav'),
|
||||
'bmp' => array('image/bmp', 'image/x-windows-bmp'),
|
||||
'gif' => 'image/gif',
|
||||
'jpeg' => array('image/jpeg', 'image/pjpeg'),
|
||||
'jpg' => array('image/jpeg', 'image/pjpeg'),
|
||||
'jpe' => array('image/jpeg', 'image/pjpeg'),
|
||||
'png' => array('image/png', 'image/x-png'),
|
||||
'tiff' => 'image/tiff',
|
||||
'tif' => 'image/tiff',
|
||||
'css' => 'text/css',
|
||||
'html' => 'text/html',
|
||||
'htm' => 'text/html',
|
||||
'shtml' => 'text/html',
|
||||
'txt' => 'text/plain',
|
||||
'text' => 'text/plain',
|
||||
'log' => array('text/plain', 'text/x-log'),
|
||||
'rtx' => 'text/richtext',
|
||||
'rtf' => 'text/rtf',
|
||||
'xml' => 'text/xml',
|
||||
'xsl' => 'text/xml',
|
||||
'mpeg' => 'video/mpeg',
|
||||
'mpg' => 'video/mpeg',
|
||||
'mpe' => 'video/mpeg',
|
||||
'qt' => 'video/quicktime',
|
||||
'mov' => 'video/quicktime',
|
||||
'avi' => 'video/x-msvideo',
|
||||
'movie' => 'video/x-sgi-movie',
|
||||
'doc' => 'application/msword',
|
||||
'docx' => array('application/vnd.openxmlformats-officedocument.wordprocessingml.document', 'application/zip'),
|
||||
'xlsx' => array('application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', 'application/zip'),
|
||||
'word' => array('application/msword', 'application/octet-stream'),
|
||||
'xl' => 'application/excel',
|
||||
'eml' => 'message/rfc822',
|
||||
'json' => array('application/json', 'text/json')
|
||||
);
|
||||
|
||||
|
||||
/* End of file mimes.php */
|
||||
/* Location: ./application/config/mimes.php */
|
||||
return array(
|
||||
'hqx' => array('application/mac-binhex40', 'application/mac-binhex', 'application/x-binhex40', 'application/x-mac-binhex40'),
|
||||
'cpt' => 'application/mac-compactpro',
|
||||
'csv' => array('text/x-comma-separated-values', 'text/comma-separated-values', 'application/octet-stream', 'application/vnd.ms-excel', 'application/x-csv', 'text/x-csv', 'text/csv', 'application/csv', 'application/excel', 'application/vnd.msexcel', 'text/plain'),
|
||||
'bin' => array('application/macbinary', 'application/mac-binary', 'application/octet-stream', 'application/x-binary', 'application/x-macbinary'),
|
||||
'dms' => 'application/octet-stream',
|
||||
'lha' => 'application/octet-stream',
|
||||
'lzh' => 'application/octet-stream',
|
||||
'exe' => array('application/octet-stream', 'application/x-msdownload'),
|
||||
'class' => 'application/octet-stream',
|
||||
'psd' => array('application/x-photoshop', 'image/vnd.adobe.photoshop'),
|
||||
'so' => 'application/octet-stream',
|
||||
'sea' => 'application/octet-stream',
|
||||
'dll' => 'application/octet-stream',
|
||||
'oda' => 'application/oda',
|
||||
'pdf' => array('application/pdf', 'application/force-download', 'application/x-download', 'binary/octet-stream'),
|
||||
'ai' => array('application/pdf', 'application/postscript'),
|
||||
'eps' => 'application/postscript',
|
||||
'ps' => 'application/postscript',
|
||||
'smi' => 'application/smil',
|
||||
'smil' => 'application/smil',
|
||||
'mif' => 'application/vnd.mif',
|
||||
'xls' => array('application/vnd.ms-excel', 'application/msexcel', 'application/x-msexcel', 'application/x-ms-excel', 'application/x-excel', 'application/x-dos_ms_excel', 'application/xls', 'application/x-xls', 'application/excel', 'application/download', 'application/vnd.ms-office', 'application/msword'),
|
||||
'ppt' => array('application/powerpoint', 'application/vnd.ms-powerpoint', 'application/vnd.ms-office', 'application/msword'),
|
||||
'pptx' => array('application/vnd.openxmlformats-officedocument.presentationml.presentation', 'application/x-zip', 'application/zip'),
|
||||
'wbxml' => 'application/wbxml',
|
||||
'wmlc' => 'application/wmlc',
|
||||
'dcr' => 'application/x-director',
|
||||
'dir' => 'application/x-director',
|
||||
'dxr' => 'application/x-director',
|
||||
'dvi' => 'application/x-dvi',
|
||||
'gtar' => 'application/x-gtar',
|
||||
'gz' => 'application/x-gzip',
|
||||
'gzip' => 'application/x-gzip',
|
||||
'php' => array('application/x-httpd-php', 'application/php', 'application/x-php', 'text/php', 'text/x-php', 'application/x-httpd-php-source'),
|
||||
'php4' => 'application/x-httpd-php',
|
||||
'php3' => 'application/x-httpd-php',
|
||||
'phtml' => 'application/x-httpd-php',
|
||||
'phps' => 'application/x-httpd-php-source',
|
||||
'js' => array('application/x-javascript', 'text/plain'),
|
||||
'swf' => 'application/x-shockwave-flash',
|
||||
'sit' => 'application/x-stuffit',
|
||||
'tar' => 'application/x-tar',
|
||||
'tgz' => array('application/x-tar', 'application/x-gzip-compressed'),
|
||||
'z' => 'application/x-compress',
|
||||
'xhtml' => 'application/xhtml+xml',
|
||||
'xht' => 'application/xhtml+xml',
|
||||
'zip' => array('application/x-zip', 'application/zip', 'application/x-zip-compressed', 'application/s-compressed', 'multipart/x-zip'),
|
||||
'rar' => array('application/x-rar', 'application/rar', 'application/x-rar-compressed'),
|
||||
'mid' => 'audio/midi',
|
||||
'midi' => 'audio/midi',
|
||||
'mpga' => 'audio/mpeg',
|
||||
'mp2' => 'audio/mpeg',
|
||||
'mp3' => array('audio/mpeg', 'audio/mpg', 'audio/mpeg3', 'audio/mp3'),
|
||||
'aif' => array('audio/x-aiff', 'audio/aiff'),
|
||||
'aiff' => array('audio/x-aiff', 'audio/aiff'),
|
||||
'aifc' => 'audio/x-aiff',
|
||||
'ram' => 'audio/x-pn-realaudio',
|
||||
'rm' => 'audio/x-pn-realaudio',
|
||||
'rpm' => 'audio/x-pn-realaudio-plugin',
|
||||
'ra' => 'audio/x-realaudio',
|
||||
'rv' => 'video/vnd.rn-realvideo',
|
||||
'wav' => array('audio/x-wav', 'audio/wave', 'audio/wav'),
|
||||
'bmp' => array('image/bmp', 'image/x-bmp', 'image/x-bitmap', 'image/x-xbitmap', 'image/x-win-bitmap', 'image/x-windows-bmp', 'image/ms-bmp', 'image/x-ms-bmp', 'application/bmp', 'application/x-bmp', 'application/x-win-bitmap'),
|
||||
'gif' => 'image/gif',
|
||||
'jpeg' => array('image/jpeg', 'image/pjpeg'),
|
||||
'jpg' => array('image/jpeg', 'image/pjpeg'),
|
||||
'jpe' => array('image/jpeg', 'image/pjpeg'),
|
||||
'jp2' => array('image/jp2', 'video/mj2', 'image/jpx', 'image/jpm'),
|
||||
'j2k' => array('image/jp2', 'video/mj2', 'image/jpx', 'image/jpm'),
|
||||
'jpf' => array('image/jp2', 'video/mj2', 'image/jpx', 'image/jpm'),
|
||||
'jpg2' => array('image/jp2', 'video/mj2', 'image/jpx', 'image/jpm'),
|
||||
'jpx' => array('image/jp2', 'video/mj2', 'image/jpx', 'image/jpm'),
|
||||
'jpm' => array('image/jp2', 'video/mj2', 'image/jpx', 'image/jpm'),
|
||||
'mj2' => array('image/jp2', 'video/mj2', 'image/jpx', 'image/jpm'),
|
||||
'mjp2' => array('image/jp2', 'video/mj2', 'image/jpx', 'image/jpm'),
|
||||
'png' => array('image/png', 'image/x-png'),
|
||||
'tiff' => 'image/tiff',
|
||||
'tif' => 'image/tiff',
|
||||
'css' => array('text/css', 'text/plain'),
|
||||
'html' => array('text/html', 'text/plain'),
|
||||
'htm' => array('text/html', 'text/plain'),
|
||||
'shtml' => array('text/html', 'text/plain'),
|
||||
'txt' => 'text/plain',
|
||||
'text' => 'text/plain',
|
||||
'log' => array('text/plain', 'text/x-log'),
|
||||
'rtx' => 'text/richtext',
|
||||
'rtf' => 'text/rtf',
|
||||
'xml' => array('application/xml', 'text/xml', 'text/plain'),
|
||||
'xsl' => array('application/xml', 'text/xsl', 'text/xml'),
|
||||
'mpeg' => 'video/mpeg',
|
||||
'mpg' => 'video/mpeg',
|
||||
'mpe' => 'video/mpeg',
|
||||
'qt' => 'video/quicktime',
|
||||
'mov' => 'video/quicktime',
|
||||
'avi' => array('video/x-msvideo', 'video/msvideo', 'video/avi', 'application/x-troff-msvideo'),
|
||||
'movie' => 'video/x-sgi-movie',
|
||||
'doc' => array('application/msword', 'application/vnd.ms-office'),
|
||||
'docx' => array('application/vnd.openxmlformats-officedocument.wordprocessingml.document', 'application/zip', 'application/msword', 'application/x-zip'),
|
||||
'dot' => array('application/msword', 'application/vnd.ms-office'),
|
||||
'dotx' => array('application/vnd.openxmlformats-officedocument.wordprocessingml.document', 'application/zip', 'application/msword'),
|
||||
'xlsx' => array('application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', 'application/zip', 'application/vnd.ms-excel', 'application/msword', 'application/x-zip'),
|
||||
'word' => array('application/msword', 'application/octet-stream'),
|
||||
'xl' => 'application/excel',
|
||||
'eml' => 'message/rfc822',
|
||||
'json' => array('application/json', 'text/json'),
|
||||
'pem' => array('application/x-x509-user-cert', 'application/x-pem-file', 'application/octet-stream'),
|
||||
'p10' => array('application/x-pkcs10', 'application/pkcs10'),
|
||||
'p12' => 'application/x-pkcs12',
|
||||
'p7a' => 'application/x-pkcs7-signature',
|
||||
'p7c' => array('application/pkcs7-mime', 'application/x-pkcs7-mime'),
|
||||
'p7m' => array('application/pkcs7-mime', 'application/x-pkcs7-mime'),
|
||||
'p7r' => 'application/x-pkcs7-certreqresp',
|
||||
'p7s' => 'application/pkcs7-signature',
|
||||
'crt' => array('application/x-x509-ca-cert', 'application/x-x509-user-cert', 'application/pkix-cert'),
|
||||
'crl' => array('application/pkix-crl', 'application/pkcs-crl'),
|
||||
'der' => 'application/x-x509-ca-cert',
|
||||
'kdb' => 'application/octet-stream',
|
||||
'pgp' => 'application/pgp',
|
||||
'gpg' => 'application/gpg-keys',
|
||||
'sst' => 'application/octet-stream',
|
||||
'csr' => 'application/octet-stream',
|
||||
'rsa' => 'application/x-pkcs7',
|
||||
'cer' => array('application/pkix-cert', 'application/x-x509-ca-cert'),
|
||||
'3g2' => 'video/3gpp2',
|
||||
'3gp' => array('video/3gp', 'video/3gpp'),
|
||||
'mp4' => 'video/mp4',
|
||||
'm4a' => 'audio/x-m4a',
|
||||
'f4v' => array('video/mp4', 'video/x-f4v'),
|
||||
'flv' => 'video/x-flv',
|
||||
'webm' => 'video/webm',
|
||||
'aac' => 'audio/x-acc',
|
||||
'm4u' => 'application/vnd.mpegurl',
|
||||
'm3u' => 'text/plain',
|
||||
'xspf' => 'application/xspf+xml',
|
||||
'vlc' => 'application/videolan',
|
||||
'wmv' => array('video/x-ms-wmv', 'video/x-ms-asf'),
|
||||
'au' => 'audio/x-au',
|
||||
'ac3' => 'audio/ac3',
|
||||
'flac' => 'audio/x-flac',
|
||||
'ogg' => array('audio/ogg', 'video/ogg', 'application/ogg'),
|
||||
'kmz' => array('application/vnd.google-earth.kmz', 'application/zip', 'application/x-zip'),
|
||||
'kml' => array('application/vnd.google-earth.kml+xml', 'application/xml', 'text/xml'),
|
||||
'ics' => 'text/calendar',
|
||||
'ical' => 'text/calendar',
|
||||
'zsh' => 'text/x-scriptzsh',
|
||||
'7zip' => array('application/x-compressed', 'application/x-zip-compressed', 'application/zip', 'multipart/x-zip'),
|
||||
'cdr' => array('application/cdr', 'application/coreldraw', 'application/x-cdr', 'application/x-coreldraw', 'image/cdr', 'image/x-cdr', 'zz-application/zz-winassoc-cdr'),
|
||||
'wma' => array('audio/x-ms-wma', 'video/x-ms-asf'),
|
||||
'jar' => array('application/java-archive', 'application/x-java-application', 'application/x-jar', 'application/x-compressed'),
|
||||
'svg' => array('image/svg+xml', 'application/xml', 'text/xml'),
|
||||
'vcf' => 'text/x-vcard',
|
||||
'srt' => array('text/srt', 'text/plain'),
|
||||
'vtt' => array('text/vtt', 'text/plain'),
|
||||
'ico' => array('image/x-icon', 'image/x-ico', 'image/vnd.microsoft.icon')
|
||||
);
|
||||
|
||||
24
application/config/pagination.php
Normal file
24
application/config/pagination.php
Normal file
@@ -0,0 +1,24 @@
|
||||
<?php
|
||||
defined('BASEPATH') OR exit('No direct script access allowed');
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Bootstrap 3 pagination links styling
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| Source code from http://stackoverflow.com/questions/20088779/bootstrap-3-pagination-with-codeigniter
|
||||
*/
|
||||
$config['full_tag_open'] = "<ul class='pagination pagination-sm'>";
|
||||
$config['full_tag_close'] ="</ul>";
|
||||
$config['num_tag_open'] = '<li>';
|
||||
$config['num_tag_close'] = '</li>';
|
||||
$config['cur_tag_open'] = "<li class='disabled'><li class='active'><a href='#'>";
|
||||
$config['cur_tag_close'] = "<span class='sr-only'></span></a></li>";
|
||||
$config['next_tag_open'] = "<li>";
|
||||
$config['next_tagl_close'] = "</li>";
|
||||
$config['prev_tag_open'] = "<li>";
|
||||
$config['prev_tagl_close'] = "</li>";
|
||||
$config['first_tag_open'] = "<li>";
|
||||
$config['first_tagl_close'] = "</li>";
|
||||
$config['last_tag_open'] = "<li>";
|
||||
$config['last_tagl_close'] = "</li>";
|
||||
@@ -1,4 +1,6 @@
|
||||
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
|
||||
<?php
|
||||
defined('BASEPATH') OR exit('No direct script access allowed');
|
||||
|
||||
/*
|
||||
| -------------------------------------------------------------------------
|
||||
| Profiler Sections
|
||||
@@ -7,11 +9,6 @@
|
||||
| data are displayed when the Profiler is enabled.
|
||||
| Please see the user guide for info:
|
||||
|
|
||||
| http://codeigniter.com/user_guide/general/profiling.html
|
||||
| https://codeigniter.com/user_guide/general/profiling.html
|
||||
|
|
||||
*/
|
||||
|
||||
|
||||
|
||||
/* End of file profiler.php */
|
||||
/* Location: ./application/config/profiler.php */
|
||||
@@ -1,4 +1,6 @@
|
||||
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
|
||||
<?php
|
||||
defined('BASEPATH') OR exit('No direct script access allowed');
|
||||
|
||||
/*
|
||||
| -------------------------------------------------------------------------
|
||||
| URI ROUTING
|
||||
@@ -17,13 +19,13 @@
|
||||
|
|
||||
| Please see the user guide for complete details:
|
||||
|
|
||||
| http://codeigniter.com/user_guide/general/routing.html
|
||||
| https://codeigniter.com/user_guide/general/routing.html
|
||||
|
|
||||
| -------------------------------------------------------------------------
|
||||
| RESERVED ROUTES
|
||||
| -------------------------------------------------------------------------
|
||||
|
|
||||
| There area two reserved routes:
|
||||
| There are three reserved routes:
|
||||
|
|
||||
| $route['default_controller'] = 'welcome';
|
||||
|
|
||||
@@ -33,38 +35,50 @@
|
||||
|
|
||||
| $route['404_override'] = 'errors/page_missing';
|
||||
|
|
||||
| This route will tell the Router what URI segments to use if those provided
|
||||
| in the URL cannot be matched to a valid route.
|
||||
| This route will tell the Router which controller/method to use if those
|
||||
| provided in the URL cannot be matched to a valid route.
|
||||
|
|
||||
| $route['translate_uri_dashes'] = FALSE;
|
||||
|
|
||||
| This is not exactly a route, but allows you to automatically route
|
||||
| controller and method names that contain dashes. '-' isn't a valid
|
||||
| class or method name character, so it requires translation.
|
||||
| When you set this option to TRUE, it will replace ALL dashes in the
|
||||
| controller and method URI segments.
|
||||
|
|
||||
| Examples: my-controller/index -> my_controller/index
|
||||
| my-controller/my-method -> my_controller/my_method
|
||||
*/
|
||||
|
||||
$route['default_controller'] = "login";
|
||||
$route['no_access/(:any)'] = "no_access/index/$1";
|
||||
$route['no_access/(:any)/(:any)'] = "no_access/index/$1/$2";
|
||||
$route['sales/index/(:any)'] = "sales/manage/$1";
|
||||
$route['sales/index/(:any)/(:any)'] = "sales/manage/$1/$2";
|
||||
$route['sales/index/(:any)/(:any)/(:any)'] = "sales/manage/$1/$2/$3";
|
||||
$route['reports/(summary_:any)/(:any)/(:any)'] = "reports/$1/$2/$3";
|
||||
$route['reports/summary_:any'] = "reports/date_input_excel_export";
|
||||
$route['reports/(graphical_:any)/(:any)/(:any)'] = "reports/$1/$2/$3";
|
||||
$route['reports/graphical_:any'] = "reports/date_input";
|
||||
$route['reports/(inventory_:any)/(:any)'] = "reports/$1/$2";
|
||||
$route['reports/inventory_:any'] = "reports/excel_export";
|
||||
$route['reports/inventory_summary'] = "reports/inventory_summary_input";
|
||||
$route['reports/(inventory_summary)/(:any)/(:any)/(:any)'] = "reports/$1/$2/$3/$4";
|
||||
$route['default_controller'] = 'login';
|
||||
$route['no_access/([^/]+)'] = 'no_access/index/$1';
|
||||
$route['no_access/([^/]+)/([^/]+)'] = 'no_access/index/$1/$2';
|
||||
|
||||
$route['reports/(detailed_sales)/(:any)/(:any)/(:any)'] = "reports/$1/$2/$3$/$4";
|
||||
$route['reports/detailed_sales'] = "reports/date_input_sales";
|
||||
$route['reports/(detailed_receivings)/(:any)/(:any)/(:any)'] = "reports/$1/$2/$3/$4";
|
||||
$route['reports/detailed_receivings'] = "reports/date_input_recv";
|
||||
$route['reports/(specific_:any)/(:any)/(:any)/(:any)'] = "reports/$1/$2/$3/$4";
|
||||
$route['reports/specific_customer'] = "reports/specific_customer_input";
|
||||
$route['reports/specific_employee'] = "reports/specific_employee_input";
|
||||
$route['reports/specific_discount'] = "reports/specific_discount_input";
|
||||
$route['sales/index/([^/]+)'] = 'sales/manage/$1';
|
||||
$route['sales/index/([^/]+)/([^/]+)'] = 'sales/manage/$1/$2';
|
||||
$route['sales/index/([^/]+)/([^/]+)/([^/]+)'] = 'sales/manage/$1/$2/$3';
|
||||
|
||||
$route['scaffolding_trigger'] = "";
|
||||
$route['reports/(summary_:any)/([^/]+)/([^/]+)'] = 'reports/$1/$2/$3/$4';
|
||||
$route['reports/summary_expenses_categories'] = 'reports/date_input_only';
|
||||
$route['reports/summary_:any'] = 'reports/date_input';
|
||||
|
||||
$route['404_override'] = "";
|
||||
$route['reports/(graphical_:any)/([^/]+)/([^/]+)'] = 'reports/$1/$2/$3/$4';
|
||||
$route['reports/graphical_summary_expenses_categories'] = 'reports/date_input_only';
|
||||
$route['reports/graphical_:any'] = 'reports/date_input';
|
||||
|
||||
/* End of file routes.php */
|
||||
/* Location: ./application/config/routes.php */
|
||||
$route['reports/(inventory_:any)/([^/]+)'] = 'reports/$1/$2';
|
||||
$route['reports/inventory_summary'] = 'reports/inventory_summary_input';
|
||||
$route['reports/(inventory_summary)/([^/]+)/([^/]+)/([^/]+)'] = 'reports/$1/$2';
|
||||
|
||||
$route['reports/(detailed_sales)/([^/]+)/([^/]+)/([^/]+)'] = 'reports/$1/$2/$3$/$4';
|
||||
$route['reports/detailed_sales'] = 'reports/date_input_sales';
|
||||
$route['reports/(detailed_receivings)/([^/]+)/([^/]+)/([^/]+)'] = 'reports/$1/$2/$3/$4';
|
||||
$route['reports/detailed_receivings'] = 'reports/date_input_recv';
|
||||
|
||||
$route['reports/(specific_:any)/([^/]+)/([^/]+)/([^/]+)'] = 'reports/$1/$2/$3/$4';
|
||||
$route['reports/specific_customer'] = 'reports/specific_customer_input';
|
||||
$route['reports/specific_employee'] = 'reports/specific_employee_input';
|
||||
$route['reports/specific_discount'] = 'reports/specific_discount_input';
|
||||
|
||||
$route['404_override'] = '';
|
||||
$route['translate_uri_dashes'] = FALSE;
|
||||
|
||||
@@ -1,17 +1,18 @@
|
||||
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
|
||||
<?php
|
||||
defined('BASEPATH') OR exit('No direct script access allowed');
|
||||
|
||||
/*
|
||||
| -------------------------------------------------------------------
|
||||
| SMILEYS
|
||||
| -------------------------------------------------------------------
|
||||
| This file contains an array of smileys for use with the emoticon helper.
|
||||
| Individual images can be used to replace multiple simileys. For example:
|
||||
| Individual images can be used to replace multiple smileys. For example:
|
||||
| :-) and :) use the same image replacement.
|
||||
|
|
||||
| Please see user guide for more info:
|
||||
| http://codeigniter.com/user_guide/helpers/smiley_helper.html
|
||||
| https://codeigniter.com/user_guide/helpers/smiley_helper.html
|
||||
|
|
||||
*/
|
||||
|
||||
$smileys = array(
|
||||
|
||||
// smiley image name width height alt
|
||||
@@ -57,10 +58,7 @@ $smileys = array(
|
||||
':coolcheese:' => array('shade_cheese.gif', '19', '19', 'cool cheese'),
|
||||
':vampire:' => array('vampire.gif', '19', '19', 'vampire'),
|
||||
':snake:' => array('snake.gif', '19', '19', 'snake'),
|
||||
':exclaim:' => array('exclaim.gif', '19', '19', 'excaim'),
|
||||
':question:' => array('question.gif', '19', '19', 'question') // no comma after last item
|
||||
':exclaim:' => array('exclaim.gif', '19', '19', 'exclaim'),
|
||||
':question:' => array('question.gif', '19', '19', 'question')
|
||||
|
||||
);
|
||||
|
||||
/* End of file smileys.php */
|
||||
/* Location: ./application/config/smileys.php */
|
||||
);
|
||||
|
||||
@@ -1,178 +1,214 @@
|
||||
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
|
||||
<?php
|
||||
defined('BASEPATH') OR exit('No direct script access allowed');
|
||||
|
||||
/*
|
||||
| -------------------------------------------------------------------
|
||||
| USER AGENT TYPES
|
||||
| -------------------------------------------------------------------
|
||||
| This file contains four arrays of user agent data. It is used by the
|
||||
| This file contains four arrays of user agent data. It is used by the
|
||||
| User Agent Class to help identify browser, platform, robot, and
|
||||
| mobile device data. The array keys are used to identify the device
|
||||
| mobile device data. The array keys are used to identify the device
|
||||
| and the array values are used to set the actual name of the item.
|
||||
|
|
||||
*/
|
||||
|
||||
$platforms = array (
|
||||
'windows nt 6.0' => 'Windows Longhorn',
|
||||
'windows nt 5.2' => 'Windows 2003',
|
||||
'windows nt 5.0' => 'Windows 2000',
|
||||
'windows nt 5.1' => 'Windows XP',
|
||||
'windows nt 4.0' => 'Windows NT 4.0',
|
||||
'winnt4.0' => 'Windows NT 4.0',
|
||||
'winnt 4.0' => 'Windows NT',
|
||||
'winnt' => 'Windows NT',
|
||||
'windows 98' => 'Windows 98',
|
||||
'win98' => 'Windows 98',
|
||||
'windows 95' => 'Windows 95',
|
||||
'win95' => 'Windows 95',
|
||||
'windows' => 'Unknown Windows OS',
|
||||
'os x' => 'Mac OS X',
|
||||
'ppc mac' => 'Power PC Mac',
|
||||
'freebsd' => 'FreeBSD',
|
||||
'ppc' => 'Macintosh',
|
||||
'linux' => 'Linux',
|
||||
'debian' => 'Debian',
|
||||
'sunos' => 'Sun Solaris',
|
||||
'beos' => 'BeOS',
|
||||
'apachebench' => 'ApacheBench',
|
||||
'aix' => 'AIX',
|
||||
'irix' => 'Irix',
|
||||
'osf' => 'DEC OSF',
|
||||
'hp-ux' => 'HP-UX',
|
||||
'netbsd' => 'NetBSD',
|
||||
'bsdi' => 'BSDi',
|
||||
'openbsd' => 'OpenBSD',
|
||||
'gnu' => 'GNU/Linux',
|
||||
'unix' => 'Unknown Unix OS'
|
||||
);
|
||||
$platforms = array(
|
||||
'windows nt 10.0' => 'Windows 10',
|
||||
'windows nt 6.3' => 'Windows 8.1',
|
||||
'windows nt 6.2' => 'Windows 8',
|
||||
'windows nt 6.1' => 'Windows 7',
|
||||
'windows nt 6.0' => 'Windows Vista',
|
||||
'windows nt 5.2' => 'Windows 2003',
|
||||
'windows nt 5.1' => 'Windows XP',
|
||||
'windows nt 5.0' => 'Windows 2000',
|
||||
'windows nt 4.0' => 'Windows NT 4.0',
|
||||
'winnt4.0' => 'Windows NT 4.0',
|
||||
'winnt 4.0' => 'Windows NT',
|
||||
'winnt' => 'Windows NT',
|
||||
'windows 98' => 'Windows 98',
|
||||
'win98' => 'Windows 98',
|
||||
'windows 95' => 'Windows 95',
|
||||
'win95' => 'Windows 95',
|
||||
'windows phone' => 'Windows Phone',
|
||||
'windows' => 'Unknown Windows OS',
|
||||
'android' => 'Android',
|
||||
'blackberry' => 'BlackBerry',
|
||||
'iphone' => 'iOS',
|
||||
'ipad' => 'iOS',
|
||||
'ipod' => 'iOS',
|
||||
'os x' => 'Mac OS X',
|
||||
'ppc mac' => 'Power PC Mac',
|
||||
'freebsd' => 'FreeBSD',
|
||||
'ppc' => 'Macintosh',
|
||||
'linux' => 'Linux',
|
||||
'debian' => 'Debian',
|
||||
'sunos' => 'Sun Solaris',
|
||||
'beos' => 'BeOS',
|
||||
'apachebench' => 'ApacheBench',
|
||||
'aix' => 'AIX',
|
||||
'irix' => 'Irix',
|
||||
'osf' => 'DEC OSF',
|
||||
'hp-ux' => 'HP-UX',
|
||||
'netbsd' => 'NetBSD',
|
||||
'bsdi' => 'BSDi',
|
||||
'openbsd' => 'OpenBSD',
|
||||
'gnu' => 'GNU/Linux',
|
||||
'unix' => 'Unknown Unix OS',
|
||||
'symbian' => 'Symbian OS'
|
||||
);
|
||||
|
||||
|
||||
// The order of this array should NOT be changed. Many browsers return
|
||||
// multiple browser types so we want to identify the sub-type first.
|
||||
$browsers = array(
|
||||
'Flock' => 'Flock',
|
||||
'Chrome' => 'Chrome',
|
||||
'Opera' => 'Opera',
|
||||
'MSIE' => 'Internet Explorer',
|
||||
'Internet Explorer' => 'Internet Explorer',
|
||||
'Shiira' => 'Shiira',
|
||||
'Firefox' => 'Firefox',
|
||||
'Chimera' => 'Chimera',
|
||||
'Phoenix' => 'Phoenix',
|
||||
'Firebird' => 'Firebird',
|
||||
'Camino' => 'Camino',
|
||||
'Netscape' => 'Netscape',
|
||||
'OmniWeb' => 'OmniWeb',
|
||||
'Safari' => 'Safari',
|
||||
'Mozilla' => 'Mozilla',
|
||||
'Konqueror' => 'Konqueror',
|
||||
'icab' => 'iCab',
|
||||
'Lynx' => 'Lynx',
|
||||
'Links' => 'Links',
|
||||
'hotjava' => 'HotJava',
|
||||
'amaya' => 'Amaya',
|
||||
'IBrowse' => 'IBrowse'
|
||||
);
|
||||
'OPR' => 'Opera',
|
||||
'Flock' => 'Flock',
|
||||
'Edge' => 'Spartan',
|
||||
'Chrome' => 'Chrome',
|
||||
// Opera 10+ always reports Opera/9.80 and appends Version/<real version> to the user agent string
|
||||
'Opera.*?Version' => 'Opera',
|
||||
'Opera' => 'Opera',
|
||||
'MSIE' => 'Internet Explorer',
|
||||
'Internet Explorer' => 'Internet Explorer',
|
||||
'Trident.* rv' => 'Internet Explorer',
|
||||
'Shiira' => 'Shiira',
|
||||
'Firefox' => 'Firefox',
|
||||
'Chimera' => 'Chimera',
|
||||
'Phoenix' => 'Phoenix',
|
||||
'Firebird' => 'Firebird',
|
||||
'Camino' => 'Camino',
|
||||
'Netscape' => 'Netscape',
|
||||
'OmniWeb' => 'OmniWeb',
|
||||
'Safari' => 'Safari',
|
||||
'Mozilla' => 'Mozilla',
|
||||
'Konqueror' => 'Konqueror',
|
||||
'icab' => 'iCab',
|
||||
'Lynx' => 'Lynx',
|
||||
'Links' => 'Links',
|
||||
'hotjava' => 'HotJava',
|
||||
'amaya' => 'Amaya',
|
||||
'IBrowse' => 'IBrowse',
|
||||
'Maxthon' => 'Maxthon',
|
||||
'Ubuntu' => 'Ubuntu Web Browser'
|
||||
);
|
||||
|
||||
$mobiles = array(
|
||||
// legacy array, old values commented out
|
||||
'mobileexplorer' => 'Mobile Explorer',
|
||||
// 'openwave' => 'Open Wave',
|
||||
// 'opera mini' => 'Opera Mini',
|
||||
// 'operamini' => 'Opera Mini',
|
||||
// 'elaine' => 'Palm',
|
||||
'palmsource' => 'Palm',
|
||||
// 'digital paths' => 'Palm',
|
||||
// 'avantgo' => 'Avantgo',
|
||||
// 'xiino' => 'Xiino',
|
||||
'palmscape' => 'Palmscape',
|
||||
// 'nokia' => 'Nokia',
|
||||
// 'ericsson' => 'Ericsson',
|
||||
// 'blackberry' => 'BlackBerry',
|
||||
// 'motorola' => 'Motorola'
|
||||
// legacy array, old values commented out
|
||||
'mobileexplorer' => 'Mobile Explorer',
|
||||
// 'openwave' => 'Open Wave',
|
||||
// 'opera mini' => 'Opera Mini',
|
||||
// 'operamini' => 'Opera Mini',
|
||||
// 'elaine' => 'Palm',
|
||||
'palmsource' => 'Palm',
|
||||
// 'digital paths' => 'Palm',
|
||||
// 'avantgo' => 'Avantgo',
|
||||
// 'xiino' => 'Xiino',
|
||||
'palmscape' => 'Palmscape',
|
||||
// 'nokia' => 'Nokia',
|
||||
// 'ericsson' => 'Ericsson',
|
||||
// 'blackberry' => 'BlackBerry',
|
||||
// 'motorola' => 'Motorola'
|
||||
|
||||
// Phones and Manufacturers
|
||||
'motorola' => "Motorola",
|
||||
'nokia' => "Nokia",
|
||||
'palm' => "Palm",
|
||||
'iphone' => "Apple iPhone",
|
||||
'ipad' => "iPad",
|
||||
'ipod' => "Apple iPod Touch",
|
||||
'sony' => "Sony Ericsson",
|
||||
'ericsson' => "Sony Ericsson",
|
||||
'blackberry' => "BlackBerry",
|
||||
'cocoon' => "O2 Cocoon",
|
||||
'blazer' => "Treo",
|
||||
'lg' => "LG",
|
||||
'amoi' => "Amoi",
|
||||
'xda' => "XDA",
|
||||
'mda' => "MDA",
|
||||
'vario' => "Vario",
|
||||
'htc' => "HTC",
|
||||
'samsung' => "Samsung",
|
||||
'sharp' => "Sharp",
|
||||
'sie-' => "Siemens",
|
||||
'alcatel' => "Alcatel",
|
||||
'benq' => "BenQ",
|
||||
'ipaq' => "HP iPaq",
|
||||
'mot-' => "Motorola",
|
||||
'playstation portable' => "PlayStation Portable",
|
||||
'hiptop' => "Danger Hiptop",
|
||||
'nec-' => "NEC",
|
||||
'panasonic' => "Panasonic",
|
||||
'philips' => "Philips",
|
||||
'sagem' => "Sagem",
|
||||
'sanyo' => "Sanyo",
|
||||
'spv' => "SPV",
|
||||
'zte' => "ZTE",
|
||||
'sendo' => "Sendo",
|
||||
// Phones and Manufacturers
|
||||
'motorola' => 'Motorola',
|
||||
'nokia' => 'Nokia',
|
||||
'palm' => 'Palm',
|
||||
'iphone' => 'Apple iPhone',
|
||||
'ipad' => 'iPad',
|
||||
'ipod' => 'Apple iPod Touch',
|
||||
'sony' => 'Sony Ericsson',
|
||||
'ericsson' => 'Sony Ericsson',
|
||||
'blackberry' => 'BlackBerry',
|
||||
'cocoon' => 'O2 Cocoon',
|
||||
'blazer' => 'Treo',
|
||||
'lg' => 'LG',
|
||||
'amoi' => 'Amoi',
|
||||
'xda' => 'XDA',
|
||||
'mda' => 'MDA',
|
||||
'vario' => 'Vario',
|
||||
'htc' => 'HTC',
|
||||
'samsung' => 'Samsung',
|
||||
'sharp' => 'Sharp',
|
||||
'sie-' => 'Siemens',
|
||||
'alcatel' => 'Alcatel',
|
||||
'benq' => 'BenQ',
|
||||
'ipaq' => 'HP iPaq',
|
||||
'mot-' => 'Motorola',
|
||||
'playstation portable' => 'PlayStation Portable',
|
||||
'playstation 3' => 'PlayStation 3',
|
||||
'playstation vita' => 'PlayStation Vita',
|
||||
'hiptop' => 'Danger Hiptop',
|
||||
'nec-' => 'NEC',
|
||||
'panasonic' => 'Panasonic',
|
||||
'philips' => 'Philips',
|
||||
'sagem' => 'Sagem',
|
||||
'sanyo' => 'Sanyo',
|
||||
'spv' => 'SPV',
|
||||
'zte' => 'ZTE',
|
||||
'sendo' => 'Sendo',
|
||||
'nintendo dsi' => 'Nintendo DSi',
|
||||
'nintendo ds' => 'Nintendo DS',
|
||||
'nintendo 3ds' => 'Nintendo 3DS',
|
||||
'wii' => 'Nintendo Wii',
|
||||
'open web' => 'Open Web',
|
||||
'openweb' => 'OpenWeb',
|
||||
|
||||
// Operating Systems
|
||||
'symbian' => "Symbian",
|
||||
'SymbianOS' => "SymbianOS",
|
||||
'elaine' => "Palm",
|
||||
'palm' => "Palm",
|
||||
'series60' => "Symbian S60",
|
||||
'windows ce' => "Windows CE",
|
||||
// Operating Systems
|
||||
'android' => 'Android',
|
||||
'symbian' => 'Symbian',
|
||||
'SymbianOS' => 'SymbianOS',
|
||||
'elaine' => 'Palm',
|
||||
'series60' => 'Symbian S60',
|
||||
'windows ce' => 'Windows CE',
|
||||
|
||||
// Browsers
|
||||
'obigo' => "Obigo",
|
||||
'netfront' => "Netfront Browser",
|
||||
'openwave' => "Openwave Browser",
|
||||
'mobilexplorer' => "Mobile Explorer",
|
||||
'operamini' => "Opera Mini",
|
||||
'opera mini' => "Opera Mini",
|
||||
// Browsers
|
||||
'obigo' => 'Obigo',
|
||||
'netfront' => 'Netfront Browser',
|
||||
'openwave' => 'Openwave Browser',
|
||||
'mobilexplorer' => 'Mobile Explorer',
|
||||
'operamini' => 'Opera Mini',
|
||||
'opera mini' => 'Opera Mini',
|
||||
'opera mobi' => 'Opera Mobile',
|
||||
'fennec' => 'Firefox Mobile',
|
||||
|
||||
// Other
|
||||
'digital paths' => "Digital Paths",
|
||||
'avantgo' => "AvantGo",
|
||||
'xiino' => "Xiino",
|
||||
'novarra' => "Novarra Transcoder",
|
||||
'vodafone' => "Vodafone",
|
||||
'docomo' => "NTT DoCoMo",
|
||||
'o2' => "O2",
|
||||
// Other
|
||||
'digital paths' => 'Digital Paths',
|
||||
'avantgo' => 'AvantGo',
|
||||
'xiino' => 'Xiino',
|
||||
'novarra' => 'Novarra Transcoder',
|
||||
'vodafone' => 'Vodafone',
|
||||
'docomo' => 'NTT DoCoMo',
|
||||
'o2' => 'O2',
|
||||
|
||||
// Fallback
|
||||
'mobile' => "Generic Mobile",
|
||||
'wireless' => "Generic Mobile",
|
||||
'j2me' => "Generic Mobile",
|
||||
'midp' => "Generic Mobile",
|
||||
'cldc' => "Generic Mobile",
|
||||
'up.link' => "Generic Mobile",
|
||||
'up.browser' => "Generic Mobile",
|
||||
'smartphone' => "Generic Mobile",
|
||||
'cellphone' => "Generic Mobile"
|
||||
);
|
||||
// Fallback
|
||||
'mobile' => 'Generic Mobile',
|
||||
'wireless' => 'Generic Mobile',
|
||||
'j2me' => 'Generic Mobile',
|
||||
'midp' => 'Generic Mobile',
|
||||
'cldc' => 'Generic Mobile',
|
||||
'up.link' => 'Generic Mobile',
|
||||
'up.browser' => 'Generic Mobile',
|
||||
'smartphone' => 'Generic Mobile',
|
||||
'cellphone' => 'Generic Mobile'
|
||||
);
|
||||
|
||||
// There are hundreds of bots but these are the most common.
|
||||
$robots = array(
|
||||
'googlebot' => 'Googlebot',
|
||||
'msnbot' => 'MSNBot',
|
||||
'slurp' => 'Inktomi Slurp',
|
||||
'yahoo' => 'Yahoo',
|
||||
'askjeeves' => 'AskJeeves',
|
||||
'fastcrawler' => 'FastCrawler',
|
||||
'infoseek' => 'InfoSeek Robot 1.0',
|
||||
'lycos' => 'Lycos'
|
||||
);
|
||||
|
||||
/* End of file user_agents.php */
|
||||
/* Location: ./application/config/user_agents.php */
|
||||
'googlebot' => 'Googlebot',
|
||||
'msnbot' => 'MSNBot',
|
||||
'baiduspider' => 'Baiduspider',
|
||||
'bingbot' => 'Bing',
|
||||
'slurp' => 'Inktomi Slurp',
|
||||
'yahoo' => 'Yahoo',
|
||||
'ask jeeves' => 'Ask Jeeves',
|
||||
'fastcrawler' => 'FastCrawler',
|
||||
'infoseek' => 'InfoSeek Robot 1.0',
|
||||
'lycos' => 'Lycos',
|
||||
'yandex' => 'YandexBot',
|
||||
'mediapartners-google' => 'MediaPartners Google',
|
||||
'CRAZYWEBCRAWLER' => 'Crazy Webcrawler',
|
||||
'adsbot-google' => 'AdsBot Google',
|
||||
'feedfetcher-google' => 'Feedfetcher Google',
|
||||
'curious george' => 'Curious George',
|
||||
'ia_archiver' => 'Alexa Crawler',
|
||||
'MJ12bot' => 'Majestic-12',
|
||||
'Uptimebot' => 'Uptimebot'
|
||||
);
|
||||
|
||||
983
application/controllers/Config.php
Normal file
983
application/controllers/Config.php
Normal file
@@ -0,0 +1,983 @@
|
||||
<?php if (!defined('BASEPATH')) exit('No direct script access allowed');
|
||||
|
||||
require_once("Secure_Controller.php");
|
||||
|
||||
class Config extends Secure_Controller
|
||||
{
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct('config');
|
||||
|
||||
$this->load->library('barcode_lib');
|
||||
$this->load->library('sale_lib');
|
||||
}
|
||||
|
||||
/*
|
||||
* This function loads all the licenses starting with the first one being OSPOS one
|
||||
*/
|
||||
private function _licenses()
|
||||
{
|
||||
$i = 0;
|
||||
$bower = FALSE;
|
||||
$composer = FALSE;
|
||||
$license = array();
|
||||
|
||||
$license[$i]['title'] = 'Open Source Point Of Sale ' . $this->config->item('application_version');
|
||||
|
||||
if(file_exists('license/LICENSE'))
|
||||
{
|
||||
$license[$i]['text'] = $this->xss_clean(file_get_contents('license/LICENSE', NULL, NULL, 0, 2000));
|
||||
}
|
||||
else
|
||||
{
|
||||
$license[$i]['text'] = 'LICENSE file must be in OSPOS license directory. You are not allowed to use OSPOS application until the distribution copy of LICENSE file is present.';
|
||||
}
|
||||
|
||||
// read all the files in the dir license
|
||||
$dir = new DirectoryIterator('license');
|
||||
|
||||
foreach($dir as $fileinfo)
|
||||
{
|
||||
// license files must be in couples: .version (name & version) & .license (license text)
|
||||
if($fileinfo->isFile())
|
||||
{
|
||||
if($fileinfo->getExtension() == 'version')
|
||||
{
|
||||
++$i;
|
||||
|
||||
$basename = 'license/' . $fileinfo->getBasename('.version');
|
||||
|
||||
$license[$i]['title'] = $this->xss_clean(file_get_contents($basename . '.version', NULL, NULL, 0, 100));
|
||||
|
||||
$license_text_file = $basename . '.license';
|
||||
|
||||
if(file_exists($license_text_file))
|
||||
{
|
||||
$license[$i]['text'] = $this->xss_clean(file_get_contents($license_text_file , NULL, NULL, 0, 2000));
|
||||
}
|
||||
else
|
||||
{
|
||||
$license[$i]['text'] = $license_text_file . ' file is missing';
|
||||
}
|
||||
}
|
||||
elseif($fileinfo->getBasename() == 'bower.LICENSES')
|
||||
{
|
||||
// set a flag to indicate that the JS Plugin bower.LICENSES file is available and needs to be attached at the end
|
||||
$bower = TRUE;
|
||||
}
|
||||
elseif($fileinfo->getBasename() == 'composer.LICENSES')
|
||||
{
|
||||
// set a flag to indicate that the composer.LICENSES file is available and needs to be attached at the end
|
||||
$composer = TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// attach the licenses from the LICENSES file generated by bower
|
||||
if($composer)
|
||||
{
|
||||
++$i;
|
||||
$license[$i]['title'] = 'Composer Libraries';
|
||||
$license[$i]['text'] = '';
|
||||
|
||||
$file = file_get_contents('license/composer.LICENSES');
|
||||
$array = json_decode($file, TRUE);
|
||||
|
||||
foreach($array as $key => $val)
|
||||
{
|
||||
if(is_array($val) && $key == 'dependencies')
|
||||
{
|
||||
foreach($val as $key1 => $val1)
|
||||
{
|
||||
if(is_array($val1))
|
||||
{
|
||||
$license[$i]['text'] .= 'component: ' . $key1 . "\n";
|
||||
|
||||
foreach($val1 as $key2 => $val2)
|
||||
{
|
||||
if(is_array($val2))
|
||||
{
|
||||
$license[$i]['text'] .= $key2 . ': ';
|
||||
|
||||
foreach($val2 as $key3 => $val3)
|
||||
{
|
||||
$license[$i]['text'] .= $val3 . ' ';
|
||||
}
|
||||
|
||||
$license[$i]['text'] .= "\n";
|
||||
}
|
||||
else
|
||||
{
|
||||
$license[$i]['text'] .= $key2 . ': ' . $val2 . "\n";
|
||||
}
|
||||
}
|
||||
|
||||
$license[$i]['text'] .= "\n";
|
||||
}
|
||||
else
|
||||
{
|
||||
$license[$i]['text'] .= $key1 . ': ' . $val1 . "\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$license[$i]['text'] = $this->xss_clean($license[$i]['text']);
|
||||
}
|
||||
|
||||
// attach the licenses from the LICENSES file generated by bower
|
||||
if($bower)
|
||||
{
|
||||
++$i;
|
||||
$license[$i]['title'] = 'JS Plugins';
|
||||
$license[$i]['text'] = '';
|
||||
|
||||
$file = file_get_contents('license/bower.LICENSES');
|
||||
$array = json_decode($file, TRUE);
|
||||
|
||||
foreach($array as $key => $val)
|
||||
{
|
||||
if(is_array($val))
|
||||
{
|
||||
$license[$i]['text'] .= 'component: ' . $key . "\n";
|
||||
|
||||
foreach($val as $key1 => $val1)
|
||||
{
|
||||
if(is_array($val1))
|
||||
{
|
||||
$license[$i]['text'] .= $key1 . ': ';
|
||||
|
||||
foreach($val1 as $key2 => $val2)
|
||||
{
|
||||
$license[$i]['text'] .= $val2 . ' ';
|
||||
}
|
||||
|
||||
$license[$i]['text'] .= "\n";
|
||||
}
|
||||
else
|
||||
{
|
||||
$license[$i]['text'] .= $key1 . ': ' . $val1 . "\n";
|
||||
}
|
||||
}
|
||||
|
||||
$license[$i]['text'] .= "\n";
|
||||
}
|
||||
}
|
||||
|
||||
$license[$i]['text'] = $this->xss_clean($license[$i]['text']);
|
||||
}
|
||||
|
||||
return $license;
|
||||
}
|
||||
|
||||
/*
|
||||
* This function loads all the available themes in the dist/bootswatch directory
|
||||
*/
|
||||
private function _themes()
|
||||
{
|
||||
$themes = array();
|
||||
|
||||
// read all themes in the dist folder
|
||||
$dir = new DirectoryIterator('dist/bootswatch');
|
||||
|
||||
foreach($dir as $dirinfo)
|
||||
{
|
||||
if($dirinfo->isDir() && !$dirinfo->isDot() && $dirinfo->getFileName() != 'fonts')
|
||||
{
|
||||
$file = $this->xss_clean($dirinfo->getFileName());
|
||||
$themes[$file] = $file;
|
||||
}
|
||||
}
|
||||
|
||||
asort($themes);
|
||||
|
||||
return $themes;
|
||||
}
|
||||
|
||||
public function index()
|
||||
{
|
||||
$data['stock_locations'] = $this->Stock_location->get_all()->result_array();
|
||||
$data['dinner_tables'] = $this->Dinner_table->get_all()->result_array();
|
||||
$data['tax_categories'] = $this->Tax->get_all_tax_categories()->result_array();
|
||||
$data['customer_rewards'] = $this->Customer_rewards->get_all()->result_array();
|
||||
$data['support_barcode'] = $this->barcode_lib->get_list_barcodes();
|
||||
$data['logo_exists'] = $this->config->item('company_logo') != '';
|
||||
$data['line_sequence_options'] = $this->sale_lib->get_line_sequence_options();
|
||||
$data['register_mode_options'] = $this->sale_lib->get_register_mode_options();
|
||||
$data['rounding_options'] = Rounding_mode::get_rounding_options();
|
||||
$data['tax_codes'] = $this->get_tax_code_options();
|
||||
$data['show_office_group'] = $this->Module->get_show_office_group();
|
||||
|
||||
$data = $this->xss_clean($data);
|
||||
|
||||
// load all the license statements, they are already XSS cleaned in the private function
|
||||
$data['licenses'] = $this->_licenses();
|
||||
// load all the themes, already XSS cleaned in the private function
|
||||
$data['themes'] = $this->_themes();
|
||||
|
||||
$data['mailchimp'] = array();
|
||||
if($this->_check_encryption())
|
||||
{
|
||||
$data['mailchimp']['api_key'] = $this->encryption->decrypt($this->config->item('mailchimp_api_key'));
|
||||
$data['mailchimp']['list_id'] = $this->encryption->decrypt($this->config->item('mailchimp_list_id'));
|
||||
}
|
||||
else
|
||||
{
|
||||
$data['mailchimp']['api_key'] = '';
|
||||
$data['mailchimp']['list_id'] = '';
|
||||
}
|
||||
|
||||
// load mailchimp lists associated to the given api key, already XSS cleaned in the private function
|
||||
$data['mailchimp']['lists'] = $this->_mailchimp();
|
||||
|
||||
$this->load->view("configs/manage", $data);
|
||||
}
|
||||
|
||||
public function get_tax_code_options()
|
||||
{
|
||||
$tax_codes = $this->Tax->get_all_tax_codes()->result_array();
|
||||
$tax_code_options = array();
|
||||
foreach($tax_codes as $tax_code)
|
||||
{
|
||||
$a = $tax_code['tax_code'];
|
||||
$b = $tax_code['tax_code_name'];
|
||||
$tax_code_options[$a] = $b;
|
||||
}
|
||||
return $tax_code_options;
|
||||
}
|
||||
|
||||
public function save_info()
|
||||
{
|
||||
$upload_success = $this->_handle_logo_upload();
|
||||
$upload_data = $this->upload->data();
|
||||
|
||||
$batch_save_data = array(
|
||||
'company' => $this->input->post('company'),
|
||||
'address' => $this->input->post('address'),
|
||||
'phone' => $this->input->post('phone'),
|
||||
'email' => $this->input->post('email'),
|
||||
'fax' => $this->input->post('fax'),
|
||||
'website' => $this->input->post('website'),
|
||||
'return_policy' => $this->input->post('return_policy')
|
||||
);
|
||||
|
||||
if(!empty($upload_data['orig_name']))
|
||||
{
|
||||
// XSS file image sanity check
|
||||
if($this->xss_clean($upload_data['raw_name'], TRUE) === TRUE)
|
||||
{
|
||||
$batch_save_data['company_logo'] = $upload_data['raw_name'] . $upload_data['file_ext'];
|
||||
}
|
||||
}
|
||||
|
||||
$result = $this->Appconfig->batch_save($batch_save_data);
|
||||
$success = $upload_success && $result ? TRUE : FALSE;
|
||||
$message = $this->lang->line('config_saved_' . ($success ? '' : 'un') . 'successfully');
|
||||
$message = $upload_success ? $message : strip_tags($this->upload->display_errors());
|
||||
|
||||
echo json_encode(array(
|
||||
'success' => $success,
|
||||
'message' => $message
|
||||
));
|
||||
}
|
||||
|
||||
public function save_general()
|
||||
{
|
||||
$batch_save_data = array(
|
||||
'theme' => $this->input->post('theme'),
|
||||
'default_sales_discount' => $this->input->post('default_sales_discount'),
|
||||
'receiving_calculate_average_price' => $this->input->post('receiving_calculate_average_price') != NULL,
|
||||
'lines_per_page' => $this->input->post('lines_per_page'),
|
||||
'notify_horizontal_position' => $this->input->post('notify_horizontal_position'),
|
||||
'notify_vertical_position' => $this->input->post('notify_vertical_position'),
|
||||
'gcaptcha_enable' => $this->input->post('gcaptcha_enable') != NULL,
|
||||
'gcaptcha_secret_key' => $this->input->post('gcaptcha_secret_key'),
|
||||
'gcaptcha_site_key' => $this->input->post('gcaptcha_site_key'),
|
||||
'suggestions_first_column' => $this->input->post('suggestions_first_column'),
|
||||
'suggestions_second_column' => $this->input->post('suggestions_second_column'),
|
||||
'suggestions_third_column' => $this->input->post('suggestions_third_column'),
|
||||
'giftcard_number' => $this->input->post('giftcard_number'),
|
||||
'derive_sale_quantity' => $this->input->post('derive_sale_quantity') != NULL,
|
||||
'custom1_name' => $this->input->post('custom1_name'),
|
||||
'custom2_name' => $this->input->post('custom2_name'),
|
||||
'custom3_name' => $this->input->post('custom3_name'),
|
||||
'custom4_name' => $this->input->post('custom4_name'),
|
||||
'custom5_name' => $this->input->post('custom5_name'),
|
||||
'custom6_name' => $this->input->post('custom6_name'),
|
||||
'custom7_name' => $this->input->post('custom7_name'),
|
||||
'custom8_name' => $this->input->post('custom8_name'),
|
||||
'custom9_name' => $this->input->post('custom9_name'),
|
||||
'custom10_name' => $this->input->post('custom10_name')
|
||||
);
|
||||
|
||||
$this->Module->set_show_office_group($this->input->post('show_office_group') != NULL);
|
||||
|
||||
$result = $this->Appconfig->batch_save($batch_save_data);
|
||||
$success = $result ? TRUE : FALSE;
|
||||
|
||||
echo json_encode(array(
|
||||
'success' => $success,
|
||||
'message' => $this->lang->line('config_saved_' . ($success ? '' : 'un') . 'successfully')
|
||||
));
|
||||
}
|
||||
|
||||
public function ajax_check_number_locale()
|
||||
{
|
||||
$number_locale = $this->input->post('number_locale');
|
||||
$fmt = new \NumberFormatter($number_locale, \NumberFormatter::CURRENCY);
|
||||
$currency_symbol = empty($this->input->post('currency_symbol')) ? $fmt->getSymbol(\NumberFormatter::CURRENCY_SYMBOL) : $this->input->post('currency_symbol');
|
||||
if($this->input->post('thousands_separator') == 'false')
|
||||
{
|
||||
$fmt->setAttribute(\NumberFormatter::GROUPING_SEPARATOR_SYMBOL, '');
|
||||
}
|
||||
$fmt->setSymbol(\NumberFormatter::CURRENCY_SYMBOL, $currency_symbol);
|
||||
$number_local_example = $fmt->format(1234567890.12300);
|
||||
echo json_encode(array(
|
||||
'success' => $number_local_example != FALSE,
|
||||
'number_locale_example' => $number_local_example,
|
||||
'currency_symbol' => $currency_symbol,
|
||||
'thousands_separator' => $fmt->getAttribute(\NumberFormatter::GROUPING_SEPARATOR_SYMBOL) != ''
|
||||
));
|
||||
}
|
||||
|
||||
public function save_locale()
|
||||
{
|
||||
$exploded = explode(":", $this->input->post('language'));
|
||||
$batch_save_data = array(
|
||||
'currency_symbol' => $this->input->post('currency_symbol'),
|
||||
'language_code' => $exploded[0],
|
||||
'language' => $exploded[1],
|
||||
'timezone' => $this->input->post('timezone'),
|
||||
'dateformat' => $this->input->post('dateformat'),
|
||||
'timeformat' => $this->input->post('timeformat'),
|
||||
'thousands_separator' => $this->input->post('thousands_separator'),
|
||||
'number_locale' => $this->input->post('number_locale'),
|
||||
'currency_decimals' => $this->input->post('currency_decimals'),
|
||||
'tax_decimals' => $this->input->post('tax_decimals'),
|
||||
'quantity_decimals' => $this->input->post('quantity_decimals'),
|
||||
'country_codes' => $this->input->post('country_codes'),
|
||||
'payment_options_order' => $this->input->post('payment_options_order'),
|
||||
'date_or_time_format' => $this->input->post('date_or_time_format'),
|
||||
'cash_decimals' => $this->input->post('cash_decimals'),
|
||||
'cash_rounding_code' => $this->input->post('cash_rounding_code'),
|
||||
'financial_year' => $this->input->post('financial_year')
|
||||
);
|
||||
|
||||
$result = $this->Appconfig->batch_save($batch_save_data);
|
||||
$success = $result ? TRUE : FALSE;
|
||||
|
||||
echo json_encode(array(
|
||||
'success' => $success,
|
||||
'message' => $this->lang->line('config_saved_' . ($success ? '' : 'un') . 'successfully')
|
||||
));
|
||||
}
|
||||
|
||||
public function save_email()
|
||||
{
|
||||
$password = '';
|
||||
|
||||
if($this->_check_encryption())
|
||||
{
|
||||
$password = $this->encryption->encrypt($this->input->post('smtp_pass'));
|
||||
}
|
||||
|
||||
$batch_save_data = array(
|
||||
'protocol' => $this->input->post('protocol'),
|
||||
'mailpath' => $this->input->post('mailpath'),
|
||||
'smtp_host' => $this->input->post('smtp_host'),
|
||||
'smtp_user' => $this->input->post('smtp_user'),
|
||||
'smtp_pass' => $password,
|
||||
'smtp_port' => $this->input->post('smtp_port'),
|
||||
'smtp_timeout' => $this->input->post('smtp_timeout'),
|
||||
'smtp_crypto' => $this->input->post('smtp_crypto')
|
||||
);
|
||||
|
||||
$result = $this->Appconfig->batch_save($batch_save_data);
|
||||
$success = $result ? TRUE : FALSE;
|
||||
|
||||
echo json_encode(array(
|
||||
'success' => $success,
|
||||
'message' => $this->lang->line('config_saved_' . ($success ? '' : 'un') . 'successfully')
|
||||
));
|
||||
}
|
||||
|
||||
public function save_message()
|
||||
{
|
||||
$password = '';
|
||||
|
||||
if($this->_check_encryption())
|
||||
{
|
||||
$password = $this->encryption->encrypt($this->input->post('msg_pwd'));
|
||||
}
|
||||
|
||||
$batch_save_data = array(
|
||||
'msg_msg' => $this->input->post('msg_msg'),
|
||||
'msg_uid' => $this->input->post('msg_uid'),
|
||||
'msg_pwd' => $password,
|
||||
'msg_src' => $this->input->post('msg_src')
|
||||
);
|
||||
|
||||
$result = $this->Appconfig->batch_save($batch_save_data);
|
||||
$success = $result ? TRUE : FALSE;
|
||||
|
||||
echo json_encode(array(
|
||||
'success' => $success,
|
||||
'message' => $this->lang->line('config_saved_' . ($success ? '' : 'un') . 'successfully')
|
||||
));
|
||||
}
|
||||
|
||||
/*
|
||||
* This function fetches all the available lists from Mailchimp for the given API key
|
||||
*/
|
||||
private function _mailchimp($api_key = '')
|
||||
{
|
||||
$this->load->library('mailchimp_lib', array('api_key' => $api_key));
|
||||
|
||||
$result = array();
|
||||
|
||||
if(($lists = $this->mailchimp_lib->getLists()) !== FALSE)
|
||||
{
|
||||
if(is_array($lists) && !empty($lists['lists']) && is_array($lists['lists']))
|
||||
{
|
||||
foreach($lists['lists'] as $list)
|
||||
{
|
||||
$list = $this->xss_clean($list);
|
||||
$result[$list['id']] = $list['name'] . ' [' . $list['stats']['member_count'] . ']';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/*
|
||||
AJAX call from mailchimp config form to fetch the Mailchimp lists when a valid API key is inserted
|
||||
*/
|
||||
public function ajax_check_mailchimp_api_key()
|
||||
{
|
||||
// load mailchimp lists associated to the given api key, already XSS cleaned in the private function
|
||||
$lists = $this->_mailchimp($this->input->post('mailchimp_api_key'));
|
||||
$success = count($lists) > 0 ? TRUE : FALSE;
|
||||
|
||||
echo json_encode(array(
|
||||
'success' => $success,
|
||||
'message' => $this->lang->line('config_mailchimp_key_' . ($success ? '' : 'un') . 'successfully'),
|
||||
'mailchimp_lists' => $lists
|
||||
));
|
||||
}
|
||||
|
||||
public function save_mailchimp()
|
||||
{
|
||||
$api_key = '';
|
||||
$list_id = '';
|
||||
|
||||
if($this->_check_encryption())
|
||||
{
|
||||
$api_key = $this->encryption->encrypt($this->input->post('mailchimp_api_key'));
|
||||
$list_id = $this->encryption->encrypt($this->input->post('mailchimp_list_id'));
|
||||
}
|
||||
|
||||
$batch_save_data = array(
|
||||
'mailchimp_api_key' => $api_key,
|
||||
'mailchimp_list_id' => $list_id
|
||||
);
|
||||
|
||||
$result = $this->Appconfig->batch_save($batch_save_data);
|
||||
$success = $result ? TRUE : FALSE;
|
||||
|
||||
echo json_encode(array(
|
||||
'success' => $success,
|
||||
'message' => $this->lang->line('config_saved_' . ($success ? '' : 'un') . 'successfully')
|
||||
));
|
||||
}
|
||||
|
||||
public function ajax_stock_locations()
|
||||
{
|
||||
$stock_locations = $this->Stock_location->get_all()->result_array();
|
||||
|
||||
$stock_locations = $this->xss_clean($stock_locations);
|
||||
|
||||
$this->load->view('partial/stock_locations', array('stock_locations' => $stock_locations));
|
||||
}
|
||||
|
||||
public function ajax_dinner_tables()
|
||||
{
|
||||
$dinner_tables = $this->Dinner_table->get_all()->result_array();
|
||||
|
||||
$dinner_tables = $this->xss_clean($dinner_tables);
|
||||
|
||||
$this->load->view('partial/dinner_tables', array('dinner_tables' => $dinner_tables));
|
||||
}
|
||||
|
||||
public function ajax_tax_categories()
|
||||
{
|
||||
$tax_categories = $this->Tax->get_all_tax_categories()->result_array();
|
||||
|
||||
$tax_categories = $this->xss_clean($tax_categories);
|
||||
|
||||
$this->load->view('partial/tax_categories', array('tax_categories' => $tax_categories));
|
||||
}
|
||||
|
||||
public function ajax_customer_rewards()
|
||||
{
|
||||
$customer_rewards = $this->Customer_rewards->get_all()->result_array();
|
||||
|
||||
$customer_rewards = $this->xss_clean($customer_rewards);
|
||||
|
||||
$this->load->view('partial/customer_rewards', array('customer_rewards' => $customer_rewards));
|
||||
}
|
||||
|
||||
private function _clear_session_state()
|
||||
{
|
||||
$this->sale_lib->clear_sale_location();
|
||||
$this->sale_lib->clear_table();
|
||||
$this->sale_lib->clear_all();
|
||||
$this->load->library('receiving_lib');
|
||||
$this->receiving_lib->clear_stock_source();
|
||||
$this->receiving_lib->clear_stock_destination();
|
||||
$this->receiving_lib->clear_all();
|
||||
}
|
||||
|
||||
public function save_locations()
|
||||
{
|
||||
$this->db->trans_start();
|
||||
|
||||
$not_to_delete = array();
|
||||
foreach($this->input->post() as $key => $value)
|
||||
{
|
||||
if(strstr($key, 'stock_location'))
|
||||
{
|
||||
$location_id = preg_replace("/.*?_(\d+)$/", "$1", $key);
|
||||
|
||||
// save or update
|
||||
$location_data = array('location_name' => $value);
|
||||
if($this->Stock_location->save($location_data, $location_id))
|
||||
{
|
||||
$location_id = $this->Stock_location->get_location_id($value);
|
||||
$not_to_delete[] = $location_id;
|
||||
$this->_clear_session_state();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// all locations not available in post will be deleted now
|
||||
$deleted_locations = $this->Stock_location->get_all()->result_array();
|
||||
|
||||
foreach($deleted_locations as $location => $location_data)
|
||||
{
|
||||
if(!in_array($location_data['location_id'], $not_to_delete))
|
||||
{
|
||||
$this->Stock_location->delete($location_data['location_id']);
|
||||
}
|
||||
}
|
||||
|
||||
$this->db->trans_complete();
|
||||
|
||||
$success = $this->db->trans_status();
|
||||
|
||||
echo json_encode(array(
|
||||
'success' => $success,
|
||||
'message' => $this->lang->line('config_saved_' . ($success ? '' : 'un') . 'successfully')
|
||||
));
|
||||
}
|
||||
|
||||
public function save_tables()
|
||||
{
|
||||
$this->db->trans_start();
|
||||
|
||||
$dinner_table_enable = $this->input->post('dinner_table_enable') != NULL;
|
||||
|
||||
$this->Appconfig->save('dinner_table_enable', $dinner_table_enable);
|
||||
|
||||
if($dinner_table_enable)
|
||||
{
|
||||
$not_to_delete = array();
|
||||
foreach($this->input->post() as $key => $value)
|
||||
{
|
||||
if(strstr($key, 'dinner_table') && $key != 'dinner_table_enable')
|
||||
{
|
||||
$dinner_table_id = preg_replace("/.*?_(\d+)$/", "$1", $key);
|
||||
$not_to_delete[] = $dinner_table_id;
|
||||
// save or update
|
||||
$table_data = array('name' => $value);
|
||||
if($this->Dinner_table->save($table_data, $dinner_table_id))
|
||||
{
|
||||
$this->_clear_session_state();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// all tables not available in post will be deleted now
|
||||
$deleted_tables = $this->Dinner_table->get_all()->result_array();
|
||||
|
||||
foreach($deleted_tables as $dinner_tables => $table)
|
||||
{
|
||||
if(!in_array($table['dinner_table_id'], $not_to_delete))
|
||||
{
|
||||
$this->Dinner_table->delete($table['dinner_table_id']);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$this->db->trans_complete();
|
||||
|
||||
$success = $this->db->trans_status();
|
||||
|
||||
echo json_encode(array(
|
||||
'success' => $success,
|
||||
'message' => $this->lang->line('config_saved_' . ($success ? '' : 'un') . 'successfully')
|
||||
));
|
||||
}
|
||||
|
||||
public function save_tax()
|
||||
{
|
||||
$this->db->trans_start();
|
||||
|
||||
$customer_sales_tax_support = $this->input->post('customer_sales_tax_support') != NULL;
|
||||
|
||||
$batch_save_data = array(
|
||||
'default_tax_1_rate' => parse_decimals($this->input->post('default_tax_1_rate')),
|
||||
'default_tax_1_name' => $this->input->post('default_tax_1_name'),
|
||||
'default_tax_2_rate' => parse_decimals($this->input->post('default_tax_2_rate')),
|
||||
'default_tax_2_name' => $this->input->post('default_tax_2_name'),
|
||||
'tax_included' => $this->input->post('tax_included') != NULL,
|
||||
'customer_sales_tax_support' => $customer_sales_tax_support,
|
||||
'default_origin_tax_code' => $this->input->post('default_origin_tax_code')
|
||||
);
|
||||
|
||||
$success = $this->Appconfig->batch_save($batch_save_data) ? TRUE : FALSE;
|
||||
$delete_rejected = FALSE;
|
||||
|
||||
if($customer_sales_tax_support)
|
||||
{
|
||||
$array_save = array();
|
||||
foreach($this->input->post() as $key => $value)
|
||||
{
|
||||
if(strstr($key, 'tax_category'))
|
||||
{
|
||||
$tax_category_id = preg_replace("/.*?_(\d+)$/", "$1", $key);
|
||||
$array_save[$tax_category_id]['tax_category'] = $value;
|
||||
}
|
||||
elseif(strstr($key, 'tax_group_sequence'))
|
||||
{
|
||||
$tax_category_id = preg_replace("/.*?_(\d+)$/", "$1", $key);
|
||||
$array_save[$tax_category_id]['tax_group_sequence'] = $value;
|
||||
}
|
||||
}
|
||||
|
||||
$not_to_delete = array();
|
||||
if(!empty($array_save))
|
||||
{
|
||||
foreach($array_save as $key => $value)
|
||||
{
|
||||
// save or update
|
||||
$category_data = array('tax_category' => $value['tax_category'], 'tax_group_sequence' => $value['tax_group_sequence']);
|
||||
$this->Tax->save_tax_category($category_data, $key);
|
||||
$not_to_delete[] = $key;
|
||||
}
|
||||
}
|
||||
|
||||
// all categories not available in post will be deleted now
|
||||
$deleted_categories = $this->Tax->get_all_tax_categories()->result_array();
|
||||
|
||||
foreach($deleted_categories as $tax_category => $category)
|
||||
{
|
||||
if(!in_array($category['tax_category_id'], $not_to_delete))
|
||||
{
|
||||
$usg1 = $this->Tax->get_tax_category_usage($category['tax_category_id']);
|
||||
$usg2 = $this->Item->get_tax_category_usage($category['tax_category_id']);
|
||||
if(($usg1 + $usg2) == 0)
|
||||
{
|
||||
$this->Tax->delete_tax_category($category['tax_category_id']);
|
||||
}
|
||||
else
|
||||
{
|
||||
$delete_rejected = TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$this->db->trans_complete();
|
||||
|
||||
$success &= $this->db->trans_status();
|
||||
|
||||
$message = '';
|
||||
if($success && $delete_rejected)
|
||||
{
|
||||
$message = $this->lang->line('config_tax_category_used');
|
||||
$success = FALSE;
|
||||
}
|
||||
else
|
||||
{
|
||||
$message = $this->lang->line('config_saved_' . ($success ? '' : 'un') . 'successfully');
|
||||
}
|
||||
|
||||
echo json_encode(array(
|
||||
'success' => $success,
|
||||
'message' => $message
|
||||
));
|
||||
}
|
||||
|
||||
public function save_rewards()
|
||||
{
|
||||
$this->db->trans_start();
|
||||
|
||||
$customer_reward_enable = $this->input->post('customer_reward_enable') != NULL;
|
||||
|
||||
$this->Appconfig->save('customer_reward_enable', $customer_reward_enable);
|
||||
|
||||
if($customer_reward_enable)
|
||||
{
|
||||
$not_to_delete = array();
|
||||
$array_save = array();
|
||||
foreach($this->input->post() as $key => $value)
|
||||
{
|
||||
if(strstr($key, 'customer_reward') && $key != 'customer_reward_enable')
|
||||
{
|
||||
$customer_reward_id = preg_replace("/.*?_(\d+)$/", "$1", $key);
|
||||
$not_to_delete[] = $customer_reward_id;
|
||||
$array_save[$customer_reward_id]['package_name'] = $value;
|
||||
}
|
||||
elseif(strstr($key, 'reward_points'))
|
||||
{
|
||||
$customer_reward_id = preg_replace("/.*?_(\d+)$/", "$1", $key);
|
||||
$array_save[$customer_reward_id]['points_percent'] = $value;
|
||||
}
|
||||
}
|
||||
|
||||
if(!empty($array_save))
|
||||
{
|
||||
foreach($array_save as $key => $value)
|
||||
{
|
||||
// save or update
|
||||
$package_data = array('package_name' => $value['package_name'], 'points_percent' => $value['points_percent']);
|
||||
$this->Customer_rewards->save($package_data, $key);
|
||||
}
|
||||
}
|
||||
|
||||
// all packages not available in post will be deleted now
|
||||
$deleted_packages = $this->Customer_rewards->get_all()->result_array();
|
||||
|
||||
foreach($deleted_packages as $customer_rewards => $reward_category)
|
||||
{
|
||||
if(!in_array($reward_category['package_id'], $not_to_delete))
|
||||
{
|
||||
$this->Customer_rewards->delete($reward_category['package_id']);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$this->db->trans_complete();
|
||||
|
||||
$success = $this->db->trans_status();
|
||||
|
||||
echo json_encode(array(
|
||||
'success' => $success,
|
||||
'message' => $this->lang->line('config_saved_' . ($success ? '' : 'un') . 'successfully')
|
||||
));
|
||||
}
|
||||
|
||||
public function save_barcode()
|
||||
{
|
||||
$batch_save_data = array(
|
||||
'barcode_type' => $this->input->post('barcode_type'),
|
||||
'barcode_width' => $this->input->post('barcode_width'),
|
||||
'barcode_height' => $this->input->post('barcode_height'),
|
||||
'barcode_font' => $this->input->post('barcode_font'),
|
||||
'barcode_font_size' => $this->input->post('barcode_font_size'),
|
||||
'barcode_first_row' => $this->input->post('barcode_first_row'),
|
||||
'barcode_second_row' => $this->input->post('barcode_second_row'),
|
||||
'barcode_third_row' => $this->input->post('barcode_third_row'),
|
||||
'barcode_num_in_row' => $this->input->post('barcode_num_in_row'),
|
||||
'barcode_page_width' => $this->input->post('barcode_page_width'),
|
||||
'barcode_page_cellspacing' => $this->input->post('barcode_page_cellspacing'),
|
||||
'barcode_generate_if_empty' => $this->input->post('barcode_generate_if_empty') != NULL,
|
||||
'allow_duplicate_barcodes' => $this->input->post('allow_duplicate_barcodes') != NULL,
|
||||
'barcode_content' => $this->input->post('barcode_content'),
|
||||
'barcode_formats' => json_encode($this->input->post('barcode_formats'))
|
||||
);
|
||||
|
||||
$result = $this->Appconfig->batch_save($batch_save_data);
|
||||
$success = $result ? TRUE : FALSE;
|
||||
|
||||
echo json_encode(array(
|
||||
'success' => $success,
|
||||
'message' => $this->lang->line('config_saved_' . ($success ? '' : 'un') . 'successfully')
|
||||
));
|
||||
}
|
||||
|
||||
public function save_receipt()
|
||||
{
|
||||
$batch_save_data = array (
|
||||
'receipt_template' => $this->input->post('receipt_template'),
|
||||
'receipt_font_size' => $this->input->post('receipt_font_size'),
|
||||
'email_receipt_check_behaviour' => $this->input->post('email_receipt_check_behaviour'),
|
||||
'print_receipt_check_behaviour' => $this->input->post('print_receipt_check_behaviour'),
|
||||
'receipt_show_company_name' => $this->input->post('receipt_show_company_name') != NULL,
|
||||
'receipt_show_taxes' => $this->input->post('receipt_show_taxes') != NULL,
|
||||
'receipt_show_total_discount' => $this->input->post('receipt_show_total_discount') != NULL,
|
||||
'receipt_show_description' => $this->input->post('receipt_show_description') != NULL,
|
||||
'receipt_show_serialnumber' => $this->input->post('receipt_show_serialnumber') != NULL,
|
||||
'print_silently' => $this->input->post('print_silently') != NULL,
|
||||
'print_header' => $this->input->post('print_header') != NULL,
|
||||
'print_footer' => $this->input->post('print_footer') != NULL,
|
||||
'print_top_margin' => $this->input->post('print_top_margin'),
|
||||
'print_left_margin' => $this->input->post('print_left_margin'),
|
||||
'print_bottom_margin' => $this->input->post('print_bottom_margin'),
|
||||
'print_right_margin' => $this->input->post('print_right_margin')
|
||||
);
|
||||
|
||||
$result = $this->Appconfig->batch_save($batch_save_data);
|
||||
$success = $result ? TRUE : FALSE;
|
||||
|
||||
echo json_encode(array(
|
||||
'success' => $success,
|
||||
'message' => $this->lang->line('config_saved_' . ($success ? '' : 'un') . 'successfully')
|
||||
));
|
||||
}
|
||||
|
||||
public function save_invoice()
|
||||
{
|
||||
$batch_save_data = array (
|
||||
'invoice_enable' => $this->input->post('invoice_enable') != NULL,
|
||||
'default_register_mode' => $this->input->post('default_register_mode'),
|
||||
'sales_invoice_format' => $this->input->post('sales_invoice_format'),
|
||||
'sales_quote_format' => $this->input->post('sales_quote_format'),
|
||||
'recv_invoice_format' => $this->input->post('recv_invoice_format'),
|
||||
'invoice_default_comments' => $this->input->post('invoice_default_comments'),
|
||||
'invoice_email_message' => $this->input->post('invoice_email_message'),
|
||||
'line_sequence' => $this->input->post('line_sequence'),
|
||||
'last_used_invoice_number' =>$this->input->post('last_used_invoice_number'),
|
||||
'last_used_quote_number' =>$this->input->post('last_used_quote_number'),
|
||||
'quote_default_comments' => $this->input->post('quote_default_comments'),
|
||||
'work_order_enable' => $this->input->post('work_order_enable') != NULL,
|
||||
'work_order_format' => $this->input->post('work_order_format'),
|
||||
'last_used_work_order_number' =>$this->input->post('last_used_work_order_number')
|
||||
);
|
||||
|
||||
$result = $this->Appconfig->batch_save($batch_save_data);
|
||||
$success = $result ? TRUE : FALSE;
|
||||
|
||||
// Update the register mode with the latest change so that if the user
|
||||
// switches immediately back to the register the mode reflects the change
|
||||
if($success == TRUE)
|
||||
{
|
||||
if($this->config->item('invoice_enable') == '1')
|
||||
{
|
||||
$this->sale_lib->set_mode($batch_save_data['default_register_mode']);
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->sale_lib->set_mode('sale');
|
||||
}
|
||||
}
|
||||
|
||||
echo json_encode(array(
|
||||
'success' => $success,
|
||||
'message' => $this->lang->line('config_saved_' . ($success ? '' : 'un') . 'successfully')
|
||||
));
|
||||
}
|
||||
|
||||
public function remove_logo()
|
||||
{
|
||||
$result = $this->Appconfig->batch_save(array('company_logo' => ''));
|
||||
|
||||
echo json_encode(array('success' => $result));
|
||||
}
|
||||
|
||||
private function _handle_logo_upload()
|
||||
{
|
||||
$this->load->helper('directory');
|
||||
|
||||
// load upload library
|
||||
$config = array('upload_path' => './uploads/',
|
||||
'allowed_types' => 'gif|jpg|png',
|
||||
'max_size' => '1024',
|
||||
'max_width' => '800',
|
||||
'max_height' => '680',
|
||||
'file_name' => 'company_logo');
|
||||
$this->load->library('upload', $config);
|
||||
$this->upload->do_upload('company_logo');
|
||||
|
||||
return strlen($this->upload->display_errors()) == 0 || !strcmp($this->upload->display_errors(), '<p>'.$this->lang->line('upload_no_file_selected').'</p>');
|
||||
}
|
||||
|
||||
private function _check_encryption()
|
||||
{
|
||||
$encryption_key = $this->config->item('encryption_key');
|
||||
|
||||
// check if the encryption_key config item is the default one
|
||||
if($encryption_key == '' || $encryption_key == 'YOUR KEY')
|
||||
{
|
||||
// Config path
|
||||
$config_path = APPPATH . 'config/config.php';
|
||||
|
||||
// Open the file
|
||||
$config = file_get_contents($config_path);
|
||||
|
||||
// $key will be assigned a 32-byte (256-bit) hex-encoded random key
|
||||
$key = bin2hex($this->encryption->create_key(32));
|
||||
|
||||
// set the encryption key in the config item
|
||||
$this->config->set_item('encryption_key', $key);
|
||||
|
||||
// replace the empty placeholder with a real randomly generated encryption key
|
||||
$config = preg_replace("/(.*encryption_key.*)('');/", "$1'$key';", $config);
|
||||
|
||||
$result = FALSE;
|
||||
|
||||
// Chmod the file
|
||||
@chmod($config_path, 0777);
|
||||
|
||||
// Verify file permissions
|
||||
if(is_writable($config_path))
|
||||
{
|
||||
// Write the new config.php file
|
||||
$handle = @fopen($config_path, 'w+');
|
||||
// Write the file
|
||||
$result = (fwrite($handle, $config) === FALSE) ? FALSE : TRUE;
|
||||
|
||||
fclose($handle);
|
||||
}
|
||||
|
||||
// Chmod the file
|
||||
@chmod($config_path, 0444);
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
public function backup_db()
|
||||
{
|
||||
$employee_id = $this->Employee->get_logged_in_employee_info()->person_id;
|
||||
if($this->Employee->has_module_grant('config', $employee_id))
|
||||
{
|
||||
$this->load->dbutil();
|
||||
|
||||
$prefs = array(
|
||||
'format' => 'zip',
|
||||
'filename' => 'ospos.sql'
|
||||
);
|
||||
|
||||
$backup = $this->dbutil->backup($prefs);
|
||||
|
||||
$file_name = 'ospos-' . date("Y-m-d-H-i-s") .'.zip';
|
||||
$save = 'uploads/' . $file_name;
|
||||
$this->load->helper('download');
|
||||
while(ob_get_level())
|
||||
{
|
||||
ob_end_clean();
|
||||
}
|
||||
|
||||
force_download($file_name, $backup);
|
||||
}
|
||||
else
|
||||
{
|
||||
redirect('no_access/config');
|
||||
}
|
||||
}
|
||||
}
|
||||
?>
|
||||
435
application/controllers/Customers.php
Normal file
435
application/controllers/Customers.php
Normal file
@@ -0,0 +1,435 @@
|
||||
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
|
||||
|
||||
require_once("Persons.php");
|
||||
|
||||
class Customers extends Persons
|
||||
{
|
||||
private $_list_id;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct('customers');
|
||||
|
||||
$this->load->library('mailchimp_lib');
|
||||
|
||||
$CI =& get_instance();
|
||||
|
||||
$this->_list_id = $CI->encryption->decrypt($CI->Appconfig->get('mailchimp_list_id'));
|
||||
}
|
||||
|
||||
public function index()
|
||||
{
|
||||
$data['table_headers'] = $this->xss_clean(get_customer_manage_table_headers());
|
||||
|
||||
$this->load->view('people/manage', $data);
|
||||
}
|
||||
|
||||
/*
|
||||
Gets one row for a customer manage table. This is called using AJAX to update one row.
|
||||
*/
|
||||
public function get_row($row_id)
|
||||
{
|
||||
$person = $this->Customer->get_info($row_id);
|
||||
|
||||
// retrieve the total amount the customer spent so far together with min, max and average values
|
||||
$stats = $this->Customer->get_stats($person->person_id);
|
||||
if(empty($stats))
|
||||
{
|
||||
//create object with empty properties.
|
||||
$stats = new stdClass;
|
||||
$stats->total = 0;
|
||||
$stats->min = 0;
|
||||
$stats->max = 0;
|
||||
$stats->average = 0;
|
||||
$stats->avg_discount = 0;
|
||||
$stats->quantity = 0;
|
||||
}
|
||||
|
||||
$data_row = $this->xss_clean(get_customer_data_row($person, $stats));
|
||||
|
||||
echo json_encode($data_row);
|
||||
}
|
||||
|
||||
/*
|
||||
Returns customer table data rows. This will be called with AJAX.
|
||||
*/
|
||||
public function search()
|
||||
{
|
||||
$search = $this->input->get('search');
|
||||
$limit = $this->input->get('limit');
|
||||
$offset = $this->input->get('offset');
|
||||
$sort = $this->input->get('sort');
|
||||
$order = $this->input->get('order');
|
||||
|
||||
$customers = $this->Customer->search($search, $limit, $offset, $sort, $order);
|
||||
$total_rows = $this->Customer->get_found_rows($search);
|
||||
|
||||
$data_rows = array();
|
||||
foreach($customers->result() as $person)
|
||||
{
|
||||
// retrieve the total amount the customer spent so far together with min, max and average values
|
||||
$stats = $this->Customer->get_stats($person->person_id);
|
||||
if(empty($stats))
|
||||
{
|
||||
//create object with empty properties.
|
||||
$stats = new stdClass;
|
||||
$stats->total = 0;
|
||||
$stats->min = 0;
|
||||
$stats->max = 0;
|
||||
$stats->average = 0;
|
||||
$stats->avg_discount = 0;
|
||||
$stats->quantity = 0;
|
||||
}
|
||||
|
||||
$data_rows[] = $this->xss_clean(get_customer_data_row($person, $stats));
|
||||
}
|
||||
|
||||
echo json_encode(array('total' => $total_rows, 'rows' => $data_rows));
|
||||
}
|
||||
|
||||
/*
|
||||
Gives search suggestions based on what is being searched for
|
||||
*/
|
||||
public function suggest()
|
||||
{
|
||||
$suggestions = $this->xss_clean($this->Customer->get_search_suggestions($this->input->get('term'), TRUE));
|
||||
|
||||
echo json_encode($suggestions);
|
||||
}
|
||||
|
||||
public function suggest_search()
|
||||
{
|
||||
$suggestions = $this->xss_clean($this->Customer->get_search_suggestions($this->input->post('term'), FALSE));
|
||||
|
||||
echo json_encode($suggestions);
|
||||
}
|
||||
|
||||
/*
|
||||
Loads the customer edit form
|
||||
*/
|
||||
public function view($customer_id = -1)
|
||||
{
|
||||
$customer_sales_tax_support = $this->config->item('customer_sales_tax_support');
|
||||
|
||||
$info = $this->Customer->get_info($customer_id);
|
||||
foreach(get_object_vars($info) as $property => $value)
|
||||
{
|
||||
$info->$property = $this->xss_clean($value);
|
||||
}
|
||||
$data['person_info'] = $info;
|
||||
$data['sales_tax_code_label'] = $info->sales_tax_code . ' ' . $this->Tax->get_info($info->sales_tax_code)->tax_code_name;
|
||||
$packages = array('' => $this->lang->line('items_none'));
|
||||
foreach($this->Customer_rewards->get_all()->result_array() as $row)
|
||||
{
|
||||
$packages[$this->xss_clean($row['package_id'])] = $this->xss_clean($row['package_name']);
|
||||
}
|
||||
$data['packages'] = $packages;
|
||||
$data['selected_package'] = $info->package_id;
|
||||
|
||||
if($customer_sales_tax_support == '1')
|
||||
{
|
||||
$data['customer_sales_tax_enabled'] = TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
$data['customer_sales_tax_enabled'] = FALSE;
|
||||
}
|
||||
|
||||
// retrieve the total amount the customer spent so far together with min, max and average values
|
||||
$stats = $this->Customer->get_stats($customer_id);
|
||||
if(!empty($stats))
|
||||
{
|
||||
foreach(get_object_vars($stats) as $property => $value)
|
||||
{
|
||||
$info->$property = $this->xss_clean($value);
|
||||
}
|
||||
$data['stats'] = $stats;
|
||||
}
|
||||
|
||||
// retrieve the info from Mailchimp only if there is an email address assigned
|
||||
if(!empty($info->email))
|
||||
{
|
||||
// collect mailchimp customer info
|
||||
if(($mailchimp_info = $this->mailchimp_lib->getMemberInfo($this->_list_id, $info->email)) !== FALSE)
|
||||
{
|
||||
$data['mailchimp_info'] = $this->xss_clean($mailchimp_info);
|
||||
|
||||
// collect customer mailchimp emails activities (stats)
|
||||
if(($activities = $this->mailchimp_lib->getMemberActivity($this->_list_id, $info->email)) !== FALSE)
|
||||
{
|
||||
if(array_key_exists('activity', $activities))
|
||||
{
|
||||
$open = 0;
|
||||
$unopen = 0;
|
||||
$click = 0;
|
||||
$total = 0;
|
||||
$lastopen = '';
|
||||
|
||||
foreach($activities['activity'] as $activity)
|
||||
{
|
||||
if($activity['action'] == 'sent')
|
||||
{
|
||||
++$unopen;
|
||||
}
|
||||
elseif($activity['action'] == 'open')
|
||||
{
|
||||
if(empty($lastopen))
|
||||
{
|
||||
$lastopen = substr($activity['timestamp'], 0, 10);
|
||||
}
|
||||
++$open;
|
||||
}
|
||||
elseif($activity['action'] == 'click')
|
||||
{
|
||||
if(empty($lastopen))
|
||||
{
|
||||
$lastopen = substr($activity['timestamp'], 0, 10);
|
||||
}
|
||||
++$click;
|
||||
}
|
||||
|
||||
++$total;
|
||||
}
|
||||
|
||||
$data['mailchimp_activity']['total'] = $total;
|
||||
$data['mailchimp_activity']['open'] = $open;
|
||||
$data['mailchimp_activity']['unopen'] = $unopen;
|
||||
$data['mailchimp_activity']['click'] = $click;
|
||||
$data['mailchimp_activity']['lastopen'] = $lastopen;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$this->load->view("customers/form", $data);
|
||||
}
|
||||
|
||||
/*
|
||||
Inserts/updates a customer
|
||||
*/
|
||||
public function save($customer_id = -1)
|
||||
{
|
||||
$first_name = $this->xss_clean($this->input->post('first_name'));
|
||||
$last_name = $this->xss_clean($this->input->post('last_name'));
|
||||
$email = $this->xss_clean(strtolower($this->input->post('email')));
|
||||
|
||||
// format first and last name properly
|
||||
$first_name = $this->nameize($first_name);
|
||||
$last_name = $this->nameize($last_name);
|
||||
|
||||
$person_data = array(
|
||||
'first_name' => $first_name,
|
||||
'last_name' => $last_name,
|
||||
'gender' => $this->input->post('gender'),
|
||||
'email' => $email,
|
||||
'phone_number' => $this->input->post('phone_number'),
|
||||
'address_1' => $this->input->post('address_1'),
|
||||
'address_2' => $this->input->post('address_2'),
|
||||
'city' => $this->input->post('city'),
|
||||
'state' => $this->input->post('state'),
|
||||
'zip' => $this->input->post('zip'),
|
||||
'country' => $this->input->post('country'),
|
||||
'comments' => $this->input->post('comments')
|
||||
);
|
||||
|
||||
$customer_data = array(
|
||||
'account_number' => $this->input->post('account_number') == '' ? NULL : $this->input->post('account_number'),
|
||||
'company_name' => $this->input->post('company_name') == '' ? NULL : $this->input->post('company_name'),
|
||||
'discount_percent' => $this->input->post('discount_percent') == '' ? 0.00 : $this->input->post('discount_percent'),
|
||||
'package_id' => $this->input->post('package_id') == '' ? NULL : $this->input->post('package_id'),
|
||||
'taxable' => $this->input->post('taxable') != NULL
|
||||
);
|
||||
|
||||
$tax_code = $this->input->post('sales_tax_code');
|
||||
if(!isset($tax_code))
|
||||
{
|
||||
$customer_data['sales_tax_code'] = '';
|
||||
}
|
||||
else
|
||||
{
|
||||
$customer_data['sales_tax_code'] = $tax_code;
|
||||
}
|
||||
|
||||
if($this->Customer->save_customer($person_data, $customer_data, $customer_id))
|
||||
{
|
||||
// save customer to Mailchimp selected list
|
||||
$this->mailchimp_lib->addOrUpdateMember($this->_list_id, $email, $first_name, $last_name, $this->input->post('mailchimp_status'), array('vip' => $this->input->post('mailchimp_vip') != NULL));
|
||||
|
||||
// New customer
|
||||
if($customer_id == -1)
|
||||
{
|
||||
echo json_encode(array('success' => TRUE,
|
||||
'message' => $this->lang->line('customers_successful_adding') . ' ' . $first_name . ' ' . $last_name,
|
||||
'id' => $this->xss_clean($customer_data['person_id'])));
|
||||
}
|
||||
else // Existing customer
|
||||
{
|
||||
echo json_encode(array('success' => TRUE,
|
||||
'message' => $this->lang->line('customers_successful_updating') . ' ' . $first_name . ' ' . $last_name,
|
||||
'id' => $customer_id));
|
||||
}
|
||||
}
|
||||
else // Failure
|
||||
{
|
||||
echo json_encode(array('success' => FALSE,
|
||||
'message' => $this->lang->line('customers_error_adding_updating') . ' ' . $first_name . ' ' . $last_name,
|
||||
'id' => -1));
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
AJAX call to verify if an email address already exists
|
||||
*/
|
||||
public function ajax_check_email()
|
||||
{
|
||||
$exists = $this->Customer->check_email_exists(strtolower($this->input->post('email')), $this->input->post('person_id'));
|
||||
|
||||
echo !$exists ? 'true' : 'false';
|
||||
}
|
||||
|
||||
/*
|
||||
AJAX call to verify if an account number already exists
|
||||
*/
|
||||
public function ajax_check_account_number()
|
||||
{
|
||||
$exists = $this->Customer->check_account_number_exists($this->input->post('account_number'), $this->input->post('person_id'));
|
||||
|
||||
echo !$exists ? 'true' : 'false';
|
||||
}
|
||||
|
||||
/*
|
||||
This deletes customers from the customers table
|
||||
*/
|
||||
public function delete()
|
||||
{
|
||||
$customers_to_delete = $this->input->post('ids');
|
||||
$customers_info = $this->Customer->get_multiple_info($customers_to_delete);
|
||||
|
||||
if($this->Customer->delete_list($customers_to_delete))
|
||||
{
|
||||
foreach($customers_info->result() as $info)
|
||||
{
|
||||
// remove customer from Mailchimp selected list
|
||||
$this->mailchimp_lib->removeMember($this->_list_id, $info->email);
|
||||
}
|
||||
|
||||
echo json_encode(array('success' => TRUE,
|
||||
'message' => $this->lang->line('customers_successful_deleted') . ' ' . count($customers_to_delete) . ' ' . $this->lang->line('customers_one_or_multiple')));
|
||||
}
|
||||
else
|
||||
{
|
||||
echo json_encode(array('success' => FALSE, 'message' => $this->lang->line('customers_cannot_be_deleted')));
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
Customers import from excel spreadsheet
|
||||
*/
|
||||
public function excel()
|
||||
{
|
||||
$name = 'import_customers.csv';
|
||||
$data = file_get_contents('../' . $name);
|
||||
force_download($name, $data);
|
||||
}
|
||||
|
||||
public function excel_import()
|
||||
{
|
||||
$this->load->view('customers/form_excel_import', NULL);
|
||||
}
|
||||
|
||||
public function do_excel_import()
|
||||
{
|
||||
if($_FILES['file_path']['error'] != UPLOAD_ERR_OK)
|
||||
{
|
||||
echo json_encode(array('success' => FALSE, 'message' => $this->lang->line('customers_excel_import_failed')));
|
||||
}
|
||||
else
|
||||
{
|
||||
if(($handle = fopen($_FILES['file_path']['tmp_name'], 'r')) !== FALSE)
|
||||
{
|
||||
// Skip the first row as it's the table description
|
||||
fgetcsv($handle);
|
||||
$i = 1;
|
||||
|
||||
$failCodes = array();
|
||||
|
||||
while(($data = fgetcsv($handle)) !== FALSE)
|
||||
{
|
||||
// XSS file data sanity check
|
||||
$data = $this->xss_clean($data);
|
||||
|
||||
if(sizeof($data) >= 15)
|
||||
{
|
||||
$email = strtolower($data[3]);
|
||||
$person_data = array(
|
||||
'first_name' => $data[0],
|
||||
'last_name' => $data[1],
|
||||
'gender' => $data[2],
|
||||
'email' => $email,
|
||||
'phone_number' => $data[4],
|
||||
'address_1' => $data[5],
|
||||
'address_2' => $data[6],
|
||||
'city' => $data[7],
|
||||
'state' => $data[8],
|
||||
'zip' => $data[9],
|
||||
'country' => $data[10],
|
||||
'comments' => $data[11]
|
||||
);
|
||||
|
||||
$customer_data = array(
|
||||
'company_name' => $data[12],
|
||||
'discount_percent' => $data[14],
|
||||
'taxable' => $data[15] == '' ? 0 : 1
|
||||
);
|
||||
$account_number = $data[13];
|
||||
|
||||
// don't duplicate people with same email
|
||||
$invalidated = $this->Customer->check_email_exists($email);
|
||||
|
||||
if($account_number != '')
|
||||
{
|
||||
$customer_data['account_number'] = $account_number;
|
||||
$invalidated &= $this->Customer->check_account_number_exists($account_number);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$invalidated = TRUE;
|
||||
}
|
||||
|
||||
if($invalidated)
|
||||
{
|
||||
$failCodes[] = $i;
|
||||
}
|
||||
elseif($this->Customer->save_customer($person_data, $customer_data))
|
||||
{
|
||||
// save customer to Mailchimp selected list
|
||||
$this->mailchimp_lib->addOrUpdateMember($this->_list_id, $person_data['email'], $person_data['first_name'], '', $person_data['last_name']);
|
||||
}
|
||||
else
|
||||
{
|
||||
$failCodes[] = $i;
|
||||
}
|
||||
|
||||
++$i;
|
||||
}
|
||||
|
||||
if(count($failCodes) > 0)
|
||||
{
|
||||
$message = $this->lang->line('customers_excel_import_partially_failed') . ' (' . count($failCodes) . '): ' . implode(', ', $failCodes);
|
||||
|
||||
echo json_encode(array('success' => FALSE, 'message' => $message));
|
||||
}
|
||||
else
|
||||
{
|
||||
echo json_encode(array('success' => TRUE, 'message' => $this->lang->line('customers_excel_import_success')));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
echo json_encode(array('success' => FALSE, 'message' => $this->lang->line('customers_excel_import_nodata_wrongformat')));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
?>
|
||||
187
application/controllers/Employees.php
Normal file
187
application/controllers/Employees.php
Normal file
@@ -0,0 +1,187 @@
|
||||
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
|
||||
|
||||
require_once("Persons.php");
|
||||
|
||||
class Employees extends Persons
|
||||
{
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct('employees');
|
||||
}
|
||||
|
||||
/*
|
||||
Returns employee table data rows. This will be called with AJAX.
|
||||
*/
|
||||
public function search()
|
||||
{
|
||||
$search = $this->input->get('search');
|
||||
$limit = $this->input->get('limit');
|
||||
$offset = $this->input->get('offset');
|
||||
$sort = $this->input->get('sort');
|
||||
$order = $this->input->get('order');
|
||||
|
||||
$employees = $this->Employee->search($search, $limit, $offset, $sort, $order);
|
||||
$total_rows = $this->Employee->get_found_rows($search);
|
||||
|
||||
$data_rows = array();
|
||||
foreach($employees->result() as $person)
|
||||
{
|
||||
$data_rows[] = $this->xss_clean(get_person_data_row($person));
|
||||
}
|
||||
|
||||
echo json_encode(array('total' => $total_rows, 'rows' => $data_rows));
|
||||
}
|
||||
|
||||
/*
|
||||
Gives search suggestions based on what is being searched for
|
||||
*/
|
||||
public function suggest_search()
|
||||
{
|
||||
$suggestions = $this->xss_clean($this->Employee->get_search_suggestions($this->input->post('term')));
|
||||
|
||||
echo json_encode($suggestions);
|
||||
}
|
||||
|
||||
/*
|
||||
Loads the employee edit form
|
||||
*/
|
||||
public function view($employee_id = -1)
|
||||
{
|
||||
$person_info = $this->Employee->get_info($employee_id);
|
||||
foreach(get_object_vars($person_info) as $property => $value)
|
||||
{
|
||||
$person_info->$property = $this->xss_clean($value);
|
||||
}
|
||||
$data['person_info'] = $person_info;
|
||||
|
||||
$modules = array();
|
||||
foreach($this->Module->get_all_modules()->result() as $module)
|
||||
{
|
||||
$module->module_id = $this->xss_clean($module->module_id);
|
||||
$module->grant = $this->xss_clean($this->Employee->has_grant($module->module_id, $person_info->person_id));
|
||||
$module->menu_group = $this->xss_clean($this->Employee->get_menu_group($module->module_id, $person_info->person_id));
|
||||
|
||||
$modules[] = $module;
|
||||
}
|
||||
$data['all_modules'] = $modules;
|
||||
|
||||
$permissions = array();
|
||||
foreach($this->Module->get_all_subpermissions()->result() as $permission)
|
||||
{
|
||||
$permission->module_id = $this->xss_clean($permission->module_id);
|
||||
$permission->permission_id = $this->xss_clean($permission->permission_id);
|
||||
$permission->grant = $this->xss_clean($this->Employee->has_grant($permission->permission_id, $person_info->person_id));
|
||||
|
||||
$permissions[] = $permission;
|
||||
}
|
||||
$data['all_subpermissions'] = $permissions;
|
||||
|
||||
$this->load->view('employees/form', $data);
|
||||
}
|
||||
|
||||
/*
|
||||
Inserts/updates an employee
|
||||
*/
|
||||
public function save($employee_id = -1)
|
||||
{
|
||||
$first_name = $this->xss_clean($this->input->post('first_name'));
|
||||
$last_name = $this->xss_clean($this->input->post('last_name'));
|
||||
$email = $this->xss_clean(strtolower($this->input->post('email')));
|
||||
|
||||
// format first and last name properly
|
||||
$first_name = $this->nameize($first_name);
|
||||
$last_name = $this->nameize($last_name);
|
||||
|
||||
$person_data = array(
|
||||
'first_name' => $first_name,
|
||||
'last_name' => $last_name,
|
||||
'gender' => $this->input->post('gender'),
|
||||
'email' => $email,
|
||||
'phone_number' => $this->input->post('phone_number'),
|
||||
'address_1' => $this->input->post('address_1'),
|
||||
'address_2' => $this->input->post('address_2'),
|
||||
'city' => $this->input->post('city'),
|
||||
'state' => $this->input->post('state'),
|
||||
'zip' => $this->input->post('zip'),
|
||||
'country' => $this->input->post('country'),
|
||||
'comments' => $this->input->post('comments'),
|
||||
);
|
||||
|
||||
$grants_array = array();
|
||||
foreach($this->Module->get_all_permissions()->result() as $permission)
|
||||
{
|
||||
$grants = array();
|
||||
$grant = $this->input->post('grant_'.$permission->permission_id) != NULL ? $this->input->post('grant_'.$permission->permission_id) : '';
|
||||
if($grant == $permission->permission_id)
|
||||
{
|
||||
$grants['permission_id'] = $permission->permission_id;
|
||||
$grants['menu_group'] = $this->input->post('menu_group_'.$permission->permission_id) != NULL ? $this->input->post('menu_group_'.$permission->permission_id) : '--';
|
||||
$grants_array[] = $grants;
|
||||
}
|
||||
}
|
||||
|
||||
//Password has been changed OR first time password set
|
||||
if($this->input->post('password') != '')
|
||||
{
|
||||
$exploded = explode(":", $this->input->post('language'));
|
||||
$employee_data = array(
|
||||
'username' => $this->input->post('username'),
|
||||
'password' => password_hash($this->input->post('password'), PASSWORD_DEFAULT),
|
||||
'hash_version' => 2,
|
||||
'language_code' => $exploded[0],
|
||||
'language' => $exploded[1]
|
||||
);
|
||||
}
|
||||
else //Password not changed
|
||||
{
|
||||
$exploded = explode(":", $this->input->post('language'));
|
||||
$employee_data = array(
|
||||
'username' => $this->input->post('username'),
|
||||
'language_code' => $exploded[0],
|
||||
'language' => $exploded[1]
|
||||
);
|
||||
}
|
||||
|
||||
if($this->Employee->save_employee($person_data, $employee_data, $grants_array, $employee_id))
|
||||
{
|
||||
// New employee
|
||||
if($employee_id == -1)
|
||||
{
|
||||
echo json_encode(array('success' => TRUE,
|
||||
'message' => $this->lang->line('employees_successful_adding') . ' ' . $first_name . ' ' . $last_name,
|
||||
'id' => $this->xss_clean($employee_data['person_id'])));
|
||||
}
|
||||
else // Existing employee
|
||||
{
|
||||
echo json_encode(array('success' => TRUE,
|
||||
'message' => $this->lang->line('employees_successful_updating') . ' ' . $first_name . ' ' . $last_name,
|
||||
'id' => $employee_id));
|
||||
}
|
||||
}
|
||||
else // Failure
|
||||
{
|
||||
echo json_encode(array('success' => FALSE,
|
||||
'message' => $this->lang->line('employees_error_adding_updating') . ' ' . $first_name . ' ' . $last_name,
|
||||
'id' => -1));
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
This deletes employees from the employees table
|
||||
*/
|
||||
public function delete()
|
||||
{
|
||||
$employees_to_delete = $this->xss_clean($this->input->post('ids'));
|
||||
|
||||
if($this->Employee->delete_list($employees_to_delete))
|
||||
{
|
||||
echo json_encode(array('success' => TRUE,'message' => $this->lang->line('employees_successful_deleted') . ' ' .
|
||||
count($employees_to_delete) . ' ' . $this->lang->line('employees_one_or_multiple')));
|
||||
}
|
||||
else
|
||||
{
|
||||
echo json_encode(array('success' => FALSE, 'message' => $this->lang->line('employees_cannot_be_deleted')));
|
||||
}
|
||||
}
|
||||
}
|
||||
?>
|
||||
176
application/controllers/Expenses.php
Normal file
176
application/controllers/Expenses.php
Normal file
@@ -0,0 +1,176 @@
|
||||
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
|
||||
|
||||
require_once("Secure_Controller.php");
|
||||
|
||||
class Expenses extends Secure_Controller
|
||||
{
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct('expenses');
|
||||
}
|
||||
|
||||
public function index()
|
||||
{
|
||||
$data['table_headers'] = $this->xss_clean(get_expenses_manage_table_headers());
|
||||
|
||||
// filters that will be loaded in the multiselect dropdown
|
||||
$data['filters'] = array('only_cash' => $this->lang->line('expenses_cash_filter'),
|
||||
'only_due' => $this->lang->line('expenses_due_filter'),
|
||||
'only_check' => $this->lang->line('expenses_check_filter'),
|
||||
'only_credit' => $this->lang->line('expenses_credit_filter'),
|
||||
'only_debit' => $this->lang->line('expenses_debit_filter'),
|
||||
'is_deleted' => $this->lang->line('expenses_is_deleted'));
|
||||
|
||||
$this->load->view('expenses/manage', $data);
|
||||
}
|
||||
|
||||
public function search()
|
||||
{
|
||||
$payments = 0;
|
||||
$search = $this->input->get('search');
|
||||
$limit = $this->input->get('limit');
|
||||
$offset = $this->input->get('offset');
|
||||
$sort = $this->input->get('sort');
|
||||
$order = $this->input->get('order');
|
||||
$filters = array(
|
||||
'start_date' => $this->input->get('start_date'),
|
||||
'end_date' => $this->input->get('end_date'),
|
||||
'only_cash' => FALSE,
|
||||
'only_due' => FALSE,
|
||||
'only_check' => FALSE,
|
||||
'only_credit' => FALSE,
|
||||
'only_debit' => FALSE,
|
||||
'is_deleted' => FALSE);
|
||||
|
||||
// check if any filter is set in the multiselect dropdown
|
||||
$filledup = array_fill_keys($this->input->get('filters'), TRUE);
|
||||
$filters = array_merge($filters, $filledup);
|
||||
$expenses = $this->Expense->search($search, $filters, $limit, $offset, $sort, $order);
|
||||
$total_rows = $this->Expense->get_found_rows($search, $filters);
|
||||
$payments = $this->Expense->get_payments_summary($search, $filters);
|
||||
$payment_summary = get_expenses_manage_payments_summary($payments, $expenses);
|
||||
$data_rows = array();
|
||||
foreach($expenses->result() as $expense)
|
||||
{
|
||||
$data_rows[] = $this->xss_clean(get_expenses_data_row($expense));
|
||||
}
|
||||
|
||||
if($total_rows > 0)
|
||||
{
|
||||
$data_rows[] = $this->xss_clean(get_expenses_data_last_row($expenses));
|
||||
}
|
||||
|
||||
echo json_encode(array('total' => $total_rows, 'rows' => $data_rows, 'payment_summary' => $payment_summary));
|
||||
}
|
||||
|
||||
public function view($expense_id = -1)
|
||||
{
|
||||
$data = array();
|
||||
|
||||
$data['employees'] = array();
|
||||
foreach($this->Employee->get_all()->result() as $employee)
|
||||
{
|
||||
foreach(get_object_vars($employee) as $property => $value)
|
||||
{
|
||||
$employee->$property = $this->xss_clean($value);
|
||||
}
|
||||
|
||||
$data['employees'][$employee->person_id] = $employee->first_name . ' ' . $employee->last_name;
|
||||
}
|
||||
|
||||
$data['expenses_info'] = $this->Expense->get_info($expense_id);
|
||||
|
||||
$data['expense_categories'] = array();
|
||||
foreach($this->Expense_category->get_all(0, 0, TRUE)->result_array() as $row)
|
||||
{
|
||||
$expense_categories[$row['expense_category_id']] = $row['category_name'];
|
||||
}
|
||||
$data['expense_categories'] = $expense_categories;
|
||||
|
||||
$expense_id = $data['expenses_info']->expense_id;
|
||||
|
||||
if(empty($expense_id))
|
||||
{
|
||||
$data['expenses_info']->date = date('Y-m-d H:i:s');
|
||||
$data['expenses_info']->employee_id = $this->Employee->get_logged_in_employee_info()->person_id;
|
||||
}
|
||||
|
||||
$data['payments'] = array();
|
||||
foreach($this->Expense->get_expense_payment($expense_id)->result() as $payment)
|
||||
{
|
||||
foreach(get_object_vars($payment) as $property => $value)
|
||||
{
|
||||
$payment->$property = $this->xss_clean($value);
|
||||
}
|
||||
|
||||
$data['payments'][] = $payment;
|
||||
}
|
||||
|
||||
// don't allow gift card to be a payment option in a sale transaction edit because it's a complex change
|
||||
$data['payment_options'] = $this->xss_clean($this->Expense->get_payment_options(FALSE));
|
||||
|
||||
$this->load->view("expenses/form", $data);
|
||||
}
|
||||
|
||||
public function get_row($row_id)
|
||||
{
|
||||
$expense_info = $this->Expense->get_info($row_id);
|
||||
$data_row = $this->xss_clean(get_expenses_data_row($expense_info));
|
||||
|
||||
echo json_encode($data_row);
|
||||
}
|
||||
|
||||
public function save($expense_id = -1)
|
||||
{
|
||||
$newdate = $this->input->post('date');
|
||||
|
||||
$date_formatter = date_create_from_format($this->config->item('dateformat') . ' ' . $this->config->item('timeformat'), $newdate);
|
||||
|
||||
$expense_data = array(
|
||||
'date' => $date_formatter->format('Y-m-d H:i:s'),
|
||||
'supplier_name' => $this->input->post('supplier_name'),
|
||||
'supplier_tax_code' => $this->input->post('supplier_tax_code'),
|
||||
'amount' => $this->input->post('amount'),
|
||||
'tax_amount' => $this->input->post('tax_amount'),
|
||||
'payment_type' => $this->input->post('payment_type'),
|
||||
'expense_category_id' => $this->input->post('expense_category_id'),
|
||||
'description' => $this->input->post('description'),
|
||||
'employee_id' => $this->input->post('employee_id'),
|
||||
'deleted' => $this->input->post('deleted') != NULL
|
||||
);
|
||||
|
||||
if($this->Expense->save($expense_data, $expense_id))
|
||||
{
|
||||
$expense_data = $this->xss_clean($expense_data);
|
||||
|
||||
//New expense_id
|
||||
if($expense_id == -1)
|
||||
{
|
||||
echo json_encode(array('success' => TRUE, 'message' => $this->lang->line('expenses_successful_adding'), 'id' => $expense_data['expense_id']));
|
||||
}
|
||||
else // Existing Expense
|
||||
{
|
||||
echo json_encode(array('success' => TRUE, 'message' => $this->lang->line('expenses_successful_updating'), 'id' => $expense_id));
|
||||
}
|
||||
}
|
||||
else//failure
|
||||
{
|
||||
echo json_encode(array('success' => FALSE, 'message' => $this->lang->line('expenses_error_adding_updating'), 'id' => -1));
|
||||
}
|
||||
}
|
||||
|
||||
public function delete()
|
||||
{
|
||||
$expenses_to_delete = $this->input->post('ids');
|
||||
|
||||
if($this->Expense->delete_list($expenses_to_delete))
|
||||
{
|
||||
echo json_encode(array('success' => TRUE, 'message' => $this->lang->line('expenses_successful_deleted') . ' ' . count($expenses_to_delete) . ' ' . $this->lang->line('expenses_one_or_multiple'), 'ids' => $expenses_to_delete));
|
||||
}
|
||||
else
|
||||
{
|
||||
echo json_encode(array('success' => FALSE, 'message' => $this->lang->line('expenses_cannot_be_deleted'), 'ids' => $expenses_to_delete));
|
||||
}
|
||||
}
|
||||
}
|
||||
?>
|
||||
97
application/controllers/Expenses_categories.php
Normal file
97
application/controllers/Expenses_categories.php
Normal file
@@ -0,0 +1,97 @@
|
||||
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
|
||||
|
||||
require_once("Secure_Controller.php");
|
||||
|
||||
class Expenses_categories extends Secure_Controller
|
||||
{
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct('expenses_categories');
|
||||
}
|
||||
|
||||
public function index()
|
||||
{
|
||||
$data['table_headers'] = $this->xss_clean(get_expense_category_manage_table_headers());
|
||||
|
||||
$this->load->view('expenses_categories/manage', $data);
|
||||
}
|
||||
|
||||
/*
|
||||
Returns expense_category_manage table data rows. This will be called with AJAX.
|
||||
*/
|
||||
public function search()
|
||||
{
|
||||
$search = $this->input->get('search');
|
||||
$limit = $this->input->get('limit');
|
||||
$offset = $this->input->get('offset');
|
||||
$sort = $this->input->get('sort');
|
||||
$order = $this->input->get('order');
|
||||
|
||||
$expense_categories = $this->Expense_category->search($search, $limit, $offset, $sort, $order);
|
||||
$total_rows = $this->Expense_category->get_found_rows($search);
|
||||
|
||||
$data_rows = array();
|
||||
foreach($expense_categories->result() as $expense_category)
|
||||
{
|
||||
$data_rows[] = $this->xss_clean(get_expense_category_data_row($expense_category));
|
||||
}
|
||||
|
||||
echo json_encode(array('total' => $total_rows, 'rows' => $data_rows));
|
||||
}
|
||||
|
||||
public function get_row($row_id)
|
||||
{
|
||||
$data_row = $this->xss_clean(get_expense_category_data_row($this->Expense_category->get_info($row_id)));
|
||||
|
||||
echo json_encode($data_row);
|
||||
}
|
||||
|
||||
public function view($expense_category_id = -1)
|
||||
{
|
||||
$data['category_info'] = $this->Expense_category->get_info($expense_category_id);
|
||||
|
||||
$this->load->view("expenses_categories/form", $data);
|
||||
}
|
||||
|
||||
public function save($expense_category_id = -1)
|
||||
{
|
||||
$expense_category_data = array(
|
||||
'category_name' => $this->input->post('category_name'),
|
||||
'category_description' => $this->input->post('category_description')
|
||||
);
|
||||
|
||||
if($this->Expense_category->save($expense_category_data, $expense_category_id))
|
||||
{
|
||||
$expense_category_data = $this->xss_clean($expense_category_data);
|
||||
|
||||
// New expense_category_id
|
||||
if($expense_category_id == -1)
|
||||
{
|
||||
echo json_encode(array('success' => TRUE, 'message' => $this->lang->line('expenses_categories_successful_adding'), 'id' => $expense_category_data['expense_category_id']));
|
||||
}
|
||||
else // Existing Expense Category
|
||||
{
|
||||
echo json_encode(array('success' => TRUE, 'message' => $this->lang->line('expenses_categories_successful_updating'), 'id' => $expense_category_id));
|
||||
}
|
||||
}
|
||||
else//failure
|
||||
{
|
||||
echo json_encode(array('success' => FALSE, 'message' => $this->lang->line('expenses_categories_error_adding_updating') . ' ' . $expense_category_data['category_name'], 'id' => -1));
|
||||
}
|
||||
}
|
||||
|
||||
public function delete()
|
||||
{
|
||||
$expense_category_to_delete = $this->input->post('ids');
|
||||
|
||||
if($this->Expense_category->delete_list($expense_category_to_delete))
|
||||
{
|
||||
echo json_encode(array('success' => TRUE, 'message' => $this->lang->line('expenses_categories_successful_deleted') . ' ' . count($expense_category_to_delete) . ' ' . $this->lang->line('expenses_categories_one_or_multiple')));
|
||||
}
|
||||
else
|
||||
{
|
||||
echo json_encode(array('success' => FALSE, 'message' => $this->lang->line('expenses_categories_cannot_be_deleted')));
|
||||
}
|
||||
}
|
||||
}
|
||||
?>
|
||||
152
application/controllers/Giftcards.php
Normal file
152
application/controllers/Giftcards.php
Normal file
@@ -0,0 +1,152 @@
|
||||
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
|
||||
|
||||
require_once("Secure_Controller.php");
|
||||
|
||||
class Giftcards extends Secure_Controller
|
||||
{
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct('giftcards');
|
||||
}
|
||||
|
||||
public function index()
|
||||
{
|
||||
$data['table_headers'] = $this->xss_clean(get_giftcards_manage_table_headers());
|
||||
|
||||
$this->load->view('giftcards/manage', $data);
|
||||
}
|
||||
|
||||
/*
|
||||
Returns Giftcards table data rows. This will be called with AJAX.
|
||||
*/
|
||||
public function search()
|
||||
{
|
||||
$search = $this->input->get('search');
|
||||
$limit = $this->input->get('limit');
|
||||
$offset = $this->input->get('offset');
|
||||
$sort = $this->input->get('sort');
|
||||
$order = $this->input->get('order');
|
||||
|
||||
$giftcards = $this->Giftcard->search($search, $limit, $offset, $sort, $order);
|
||||
$total_rows = $this->Giftcard->get_found_rows($search);
|
||||
|
||||
$data_rows = array();
|
||||
foreach($giftcards->result() as $giftcard)
|
||||
{
|
||||
$data_rows[] = $this->xss_clean(get_giftcard_data_row($giftcard));
|
||||
}
|
||||
|
||||
echo json_encode(array('total' => $total_rows, 'rows' => $data_rows));
|
||||
}
|
||||
|
||||
/*
|
||||
Gives search suggestions based on what is being searched for
|
||||
*/
|
||||
|
||||
public function suggest()
|
||||
{
|
||||
$suggestions = $this->xss_clean($this->Giftcard->get_search_suggestions($this->input->get('term'), TRUE));
|
||||
|
||||
echo json_encode($suggestions);
|
||||
}
|
||||
|
||||
public function suggest_search()
|
||||
{
|
||||
$suggestions = $this->xss_clean($this->Giftcard->get_search_suggestions($this->input->post('term')));
|
||||
|
||||
echo json_encode($suggestions);
|
||||
}
|
||||
|
||||
public function get_row($row_id)
|
||||
{
|
||||
$data_row = $this->xss_clean(get_giftcard_data_row($this->Giftcard->get_info($row_id)));
|
||||
|
||||
echo json_encode($data_row);
|
||||
}
|
||||
|
||||
public function view($giftcard_id = -1)
|
||||
{
|
||||
$giftcard_info = $this->Giftcard->get_info($giftcard_id);
|
||||
|
||||
$data['selected_person_name'] = ($giftcard_id > 0 && isset($giftcard_info->person_id)) ? $giftcard_info->first_name . ' ' . $giftcard_info->last_name : '';
|
||||
$data['selected_person_id'] = $giftcard_info->person_id;
|
||||
if($this->config->item('giftcard_number') == "random")
|
||||
{
|
||||
$data['giftcard_number'] = $giftcard_id > 0 ? $giftcard_info->giftcard_number : '';
|
||||
}
|
||||
else
|
||||
{
|
||||
$max_giftnumber = isset($this->Giftcard->get_max_number()->giftcard_number) ? $this->Giftcard->get_max_number()->giftcard_number : 0;
|
||||
$data['giftcard_number'] = $giftcard_id > 0 ? $giftcard_info->giftcard_number : $max_giftnumber + 1;
|
||||
}
|
||||
$data['giftcard_id'] = $giftcard_id;
|
||||
$data['giftcard_value'] = $giftcard_info->value;
|
||||
|
||||
$data = $this->xss_clean($data);
|
||||
|
||||
$this->load->view("giftcards/form", $data);
|
||||
}
|
||||
|
||||
public function save($giftcard_id = -1)
|
||||
{
|
||||
$giftcard_number = $this->input->post('giftcard_number');
|
||||
|
||||
if($giftcard_id == -1 && trim($giftcard_number) == '')
|
||||
{
|
||||
$giftcard_number = $this->Giftcard->generate_unique_giftcard_name($this->input->post('giftcard_amount'));
|
||||
}
|
||||
|
||||
$giftcard_data = array(
|
||||
'record_time' => date('Y-m-d H:i:s'),
|
||||
'giftcard_number' => $giftcard_number,
|
||||
'value' => parse_decimals($this->input->post('giftcard_amount')),
|
||||
'person_id' => $this->input->post('person_id') == '' ? NULL : $this->input->post('person_id')
|
||||
);
|
||||
|
||||
if($this->Giftcard->save($giftcard_data, $giftcard_id))
|
||||
{
|
||||
$giftcard_data = $this->xss_clean($giftcard_data);
|
||||
|
||||
//New giftcard
|
||||
if($giftcard_id == -1)
|
||||
{
|
||||
echo json_encode(array('success' => TRUE, 'message' => $this->lang->line('giftcards_successful_adding') . ' ' .
|
||||
$giftcard_data['giftcard_number'], 'id' => $giftcard_data['giftcard_id']));
|
||||
}
|
||||
else //Existing giftcard
|
||||
{
|
||||
echo json_encode(array('success' => TRUE, 'message' => $this->lang->line('giftcards_successful_updating') . ' ' .
|
||||
$giftcard_data['giftcard_number'], 'id' => $giftcard_id));
|
||||
}
|
||||
}
|
||||
else //failure
|
||||
{
|
||||
$giftcard_data = $this->xss_clean($giftcard_data);
|
||||
|
||||
echo json_encode(array('success' => FALSE, 'message' => $this->lang->line('giftcards_error_adding_updating') . ' ' .
|
||||
$giftcard_data['giftcard_number'], 'id' => -1));
|
||||
}
|
||||
}
|
||||
|
||||
public function ajax_check_number_giftcard()
|
||||
{
|
||||
$parsed_value = parse_decimals($this->input->post('giftcard_amount'));
|
||||
echo json_encode(array('success' => $parsed_value !== FALSE, 'giftcard_amount' => $parsed_value));
|
||||
}
|
||||
|
||||
public function delete()
|
||||
{
|
||||
$giftcards_to_delete = $this->xss_clean($this->input->post('ids'));
|
||||
|
||||
if($this->Giftcard->delete_list($giftcards_to_delete))
|
||||
{
|
||||
echo json_encode(array('success' => TRUE, 'message' => $this->lang->line('giftcards_successful_deleted') . ' ' .
|
||||
count($giftcards_to_delete).' '.$this->lang->line('giftcards_one_or_multiple')));
|
||||
}
|
||||
else
|
||||
{
|
||||
echo json_encode(array('success' => FALSE, 'message' => $this->lang->line('giftcards_cannot_be_deleted')));
|
||||
}
|
||||
}
|
||||
}
|
||||
?>
|
||||
72
application/controllers/Home.php
Normal file
72
application/controllers/Home.php
Normal file
@@ -0,0 +1,72 @@
|
||||
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
|
||||
|
||||
require_once("Secure_Controller.php");
|
||||
|
||||
class Home extends Secure_Controller
|
||||
{
|
||||
function __construct()
|
||||
{
|
||||
parent::__construct(NULL, NULL, 'home');
|
||||
}
|
||||
|
||||
public function index()
|
||||
{
|
||||
$this->load->view('home/home');
|
||||
}
|
||||
|
||||
public function logout()
|
||||
{
|
||||
$this->Employee->logout();
|
||||
}
|
||||
|
||||
/*
|
||||
Loads the change employee password form
|
||||
*/
|
||||
public function change_password($employee_id = -1)
|
||||
{
|
||||
$person_info = $this->Employee->get_info($employee_id);
|
||||
foreach(get_object_vars($person_info) as $property => $value)
|
||||
{
|
||||
$person_info->$property = $this->xss_clean($value);
|
||||
}
|
||||
$data['person_info'] = $person_info;
|
||||
|
||||
$this->load->view('home/form_change_password', $data);
|
||||
}
|
||||
|
||||
/*
|
||||
Change employee password
|
||||
*/
|
||||
public function save($employee_id = -1)
|
||||
{
|
||||
if($this->input->post('current_password') != '' && $employee_id != -1)
|
||||
{
|
||||
if($this->Employee->check_password($this->input->post('username'), $this->input->post('current_password')))
|
||||
{
|
||||
$employee_data = array(
|
||||
'username' => $this->input->post('username'),
|
||||
'password' => password_hash($this->input->post('password'), PASSWORD_DEFAULT),
|
||||
'hash_version' => 2
|
||||
);
|
||||
|
||||
if($this->Employee->change_password($employee_data, $employee_id))
|
||||
{
|
||||
echo json_encode(array('success' => TRUE, 'message' => $this->lang->line('employees_successful_change_password'), 'id' => $employee_id));
|
||||
}
|
||||
else//failure
|
||||
{
|
||||
echo json_encode(array('success' => FALSE, 'message' => $this->lang->line('employees_unsuccessful_change_password'), 'id' => -1));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
echo json_encode(array('success' => FALSE, 'message' => $this->lang->line('employees_current_password_invalid'), 'id' => -1));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
echo json_encode(array('success' => FALSE, 'message' => $this->lang->line('employees_current_password_invalid'), 'id' => -1));
|
||||
}
|
||||
}
|
||||
}
|
||||
?>
|
||||
227
application/controllers/Item_kits.php
Normal file
227
application/controllers/Item_kits.php
Normal file
@@ -0,0 +1,227 @@
|
||||
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
|
||||
|
||||
require_once("Secure_Controller.php");
|
||||
|
||||
class Item_kits extends Secure_Controller
|
||||
{
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct('item_kits');
|
||||
}
|
||||
|
||||
/*
|
||||
Add the total cost and retail price to a passed items kit retrieving the data from each singular item part of the kit
|
||||
*/
|
||||
private function _add_totals_to_item_kit($item_kit)
|
||||
{
|
||||
$item_kit->total_cost_price = 0;
|
||||
$item_kit->total_unit_price = 0;
|
||||
|
||||
foreach($this->Item_kit_items->get_info($item_kit->item_kit_id) as $item_kit_item)
|
||||
{
|
||||
$item_info = $this->Item->get_info($item_kit_item['item_id']);
|
||||
foreach(get_object_vars($item_info) as $property => $value)
|
||||
{
|
||||
$item_info->$property = $this->xss_clean($value);
|
||||
}
|
||||
|
||||
$item_kit->total_cost_price += $item_info->cost_price * $item_kit_item['quantity'];
|
||||
$item_kit->total_unit_price += $item_info->unit_price * $item_kit_item['quantity'];
|
||||
}
|
||||
|
||||
return $item_kit;
|
||||
}
|
||||
|
||||
public function index()
|
||||
{
|
||||
$data['table_headers'] = $this->xss_clean(get_item_kits_manage_table_headers());
|
||||
|
||||
$this->load->view('item_kits/manage', $data);
|
||||
}
|
||||
|
||||
/*
|
||||
Returns Item kits table data rows. This will be called with AJAX.
|
||||
*/
|
||||
public function search()
|
||||
{
|
||||
$search = $this->input->get('search');
|
||||
$limit = $this->input->get('limit');
|
||||
$offset = $this->input->get('offset');
|
||||
$sort = $this->input->get('sort');
|
||||
$order = $this->input->get('order');
|
||||
|
||||
$item_kits = $this->Item_kit->search($search, $limit, $offset, $sort, $order);
|
||||
$total_rows = $this->Item_kit->get_found_rows($search);
|
||||
|
||||
$data_rows = array();
|
||||
foreach($item_kits->result() as $item_kit)
|
||||
{
|
||||
// calculate the total cost and retail price of the Kit so it can be printed out in the manage table
|
||||
$item_kit = $this->_add_totals_to_item_kit($item_kit);
|
||||
$data_rows[] = $this->xss_clean(get_item_kit_data_row($item_kit));
|
||||
}
|
||||
|
||||
echo json_encode(array('total' => $total_rows, 'rows' => $data_rows));
|
||||
}
|
||||
|
||||
public function suggest_search()
|
||||
{
|
||||
$suggestions = $this->xss_clean($this->Item_kit->get_search_suggestions($this->input->post('term')));
|
||||
|
||||
echo json_encode($suggestions);
|
||||
}
|
||||
|
||||
public function get_row($row_id)
|
||||
{
|
||||
// calculate the total cost and retail price of the Kit so it can be added to the table refresh
|
||||
$item_kit = $this->_add_totals_to_item_kit($this->Item_kit->get_info($row_id));
|
||||
|
||||
echo json_encode(get_item_kit_data_row($item_kit));
|
||||
}
|
||||
|
||||
public function view($item_kit_id = -1)
|
||||
{
|
||||
$info = $this->Item_kit->get_info($item_kit_id);
|
||||
|
||||
if($item_kit_id == -1)
|
||||
{
|
||||
$info->price_option = '0';
|
||||
$info->print_option = PRINT_ALL;
|
||||
$info->kit_item_id = 0;
|
||||
}
|
||||
foreach(get_object_vars($info) as $property => $value)
|
||||
{
|
||||
$info->$property = $this->xss_clean($value);
|
||||
}
|
||||
|
||||
$data['item_kit_info'] = $info;
|
||||
|
||||
$items = array();
|
||||
foreach($this->Item_kit_items->get_info($item_kit_id) as $item_kit_item)
|
||||
{
|
||||
$item['kit_sequence'] = $this->xss_clean($item_kit_item['kit_sequence']);
|
||||
$item['name'] = $this->xss_clean($this->Item->get_info($item_kit_item['item_id'])->name);
|
||||
$item['item_id'] = $this->xss_clean($item_kit_item['item_id']);
|
||||
$item['quantity'] = $this->xss_clean($item_kit_item['quantity']);
|
||||
|
||||
$items[] = $item;
|
||||
}
|
||||
|
||||
$data['item_kit_items'] = $items;
|
||||
|
||||
$data['selected_kit_item_id'] = $info->kit_item_id;
|
||||
$data['selected_kit_item'] = ($item_kit_id > 0 && isset($info->kit_item_id)) ? $info->item_name : '';
|
||||
|
||||
$this->load->view("item_kits/form", $data);
|
||||
}
|
||||
|
||||
public function save($item_kit_id = -1)
|
||||
{
|
||||
$item_kit_data = array(
|
||||
'name' => $this->input->post('name'),
|
||||
'item_id' => $this->input->post('kit_item_id'),
|
||||
'kit_discount_percent' => $this->input->post('kit_discount_percent'),
|
||||
'price_option' => $this->input->post('price_option'),
|
||||
'print_option' => $this->input->post('print_option'),
|
||||
'description' => $this->input->post('description')
|
||||
);
|
||||
|
||||
if($this->Item_kit->save($item_kit_data, $item_kit_id))
|
||||
{
|
||||
$success = TRUE;
|
||||
$new_item = FALSE;
|
||||
//New item kit
|
||||
if($item_kit_id == -1)
|
||||
{
|
||||
$item_kit_id = $item_kit_data['item_kit_id'];
|
||||
$new_item = TRUE;
|
||||
}
|
||||
|
||||
if($this->input->post('item_kit_qty') != NULL)
|
||||
{
|
||||
$item_kit_items = array();
|
||||
foreach($this->input->post('item_kit_qty') as $item_id => $quantity)
|
||||
{
|
||||
$seq = $this->input->post('item_kit_seq[' . $item_id . ']');
|
||||
$item_kit_items[] = array(
|
||||
'item_id' => $item_id,
|
||||
'quantity' => $quantity,
|
||||
'kit_sequence' => $seq
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
$success = $this->Item_kit_items->save($item_kit_items, $item_kit_id);
|
||||
|
||||
$item_kit_data = $this->xss_clean($item_kit_data);
|
||||
|
||||
if($new_item)
|
||||
{
|
||||
echo json_encode(array('success' => $success,
|
||||
'message' => $this->lang->line('item_kits_successful_adding').' '.$item_kit_data['name'], 'id' => $item_kit_id));
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
echo json_encode(array('success' => $success,
|
||||
'message' => $this->lang->line('item_kits_successful_updating').' '.$item_kit_data['name'], 'id' => $item_kit_id));
|
||||
}
|
||||
}
|
||||
else//failure
|
||||
{
|
||||
$item_kit_data = $this->xss_clean($item_kit_data);
|
||||
|
||||
echo json_encode(array('success' => FALSE,
|
||||
'message' => $this->lang->line('item_kits_error_adding_updating').' '.$item_kit_data['name'], 'id' => -1));
|
||||
}
|
||||
}
|
||||
|
||||
public function delete()
|
||||
{
|
||||
$item_kits_to_delete = $this->xss_clean($this->input->post('ids'));
|
||||
|
||||
if($this->Item_kit->delete_list($item_kits_to_delete))
|
||||
{
|
||||
echo json_encode(array('success' => TRUE,
|
||||
'message' => $this->lang->line('item_kits_successful_deleted').' '.count($item_kits_to_delete).' '.$this->lang->line('item_kits_one_or_multiple')));
|
||||
}
|
||||
else
|
||||
{
|
||||
echo json_encode(array('success' => FALSE,
|
||||
'message' => $this->lang->line('item_kits_cannot_be_deleted')));
|
||||
}
|
||||
}
|
||||
|
||||
public function generate_barcodes($item_kit_ids)
|
||||
{
|
||||
$this->load->library('barcode_lib');
|
||||
$result = array();
|
||||
|
||||
$item_kit_ids = explode(':', $item_kit_ids);
|
||||
foreach($item_kit_ids as $item_kid_id)
|
||||
{
|
||||
// calculate the total cost and retail price of the Kit so it can be added to the barcode text at the bottom
|
||||
$item_kit = $this->_add_totals_to_item_kit($this->Item_kit->get_info($item_kid_id));
|
||||
|
||||
$item_kid_id = 'KIT '. urldecode($item_kid_id);
|
||||
|
||||
$result[] = array('name' => $item_kit->name, 'item_id' => $item_kid_id, 'item_number' => $item_kid_id,
|
||||
'cost_price' => $item_kit->total_cost_price, 'unit_price' => $item_kit->total_unit_price);
|
||||
}
|
||||
|
||||
$data['items'] = $result;
|
||||
$barcode_config = $this->barcode_lib->get_barcode_config();
|
||||
// in case the selected barcode type is not Code39 or Code128 we set by default Code128
|
||||
// the rationale for this is that EAN codes cannot have strings as seed, so 'KIT ' is not allowed
|
||||
if($barcode_config['barcode_type'] != 'Code39' && $barcode_config['barcode_type'] != 'Code128')
|
||||
{
|
||||
$barcode_config['barcode_type'] = 'Code128';
|
||||
}
|
||||
$data['barcode_config'] = $barcode_config;
|
||||
|
||||
// display barcodes
|
||||
$this->load->view("barcodes/barcode_sheet", $data);
|
||||
}
|
||||
}
|
||||
?>
|
||||
857
application/controllers/Items.php
Normal file
857
application/controllers/Items.php
Normal file
@@ -0,0 +1,857 @@
|
||||
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
|
||||
|
||||
require_once("Secure_Controller.php");
|
||||
|
||||
class Items extends Secure_Controller
|
||||
{
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct('items');
|
||||
|
||||
$this->load->library('item_lib');
|
||||
}
|
||||
|
||||
public function index()
|
||||
{
|
||||
$data['table_headers'] = $this->xss_clean(get_items_manage_table_headers());
|
||||
|
||||
$data['stock_location'] = $this->xss_clean($this->item_lib->get_item_location());
|
||||
$data['stock_locations'] = $this->xss_clean($this->Stock_location->get_allowed_locations());
|
||||
|
||||
// filters that will be loaded in the multiselect dropdown
|
||||
$data['filters'] = array('empty_upc' => $this->lang->line('items_empty_upc_items'),
|
||||
'low_inventory' => $this->lang->line('items_low_inventory_items'),
|
||||
'is_serialized' => $this->lang->line('items_serialized_items'),
|
||||
'no_description' => $this->lang->line('items_no_description_items'),
|
||||
'search_custom' => $this->lang->line('items_search_custom_items'),
|
||||
'is_deleted' => $this->lang->line('items_is_deleted'));
|
||||
|
||||
$this->load->view('items/manage', $data);
|
||||
}
|
||||
|
||||
/*
|
||||
Returns Items table data rows. This will be called with AJAX.
|
||||
*/
|
||||
public function search()
|
||||
{
|
||||
$search = $this->input->get('search');
|
||||
$limit = $this->input->get('limit');
|
||||
$offset = $this->input->get('offset');
|
||||
$sort = $this->input->get('sort');
|
||||
$order = $this->input->get('order');
|
||||
|
||||
$this->item_lib->set_item_location($this->input->get('stock_location'));
|
||||
|
||||
$filters = array('start_date' => $this->input->get('start_date'),
|
||||
'end_date' => $this->input->get('end_date'),
|
||||
'stock_location_id' => $this->item_lib->get_item_location(),
|
||||
'empty_upc' => FALSE,
|
||||
'low_inventory' => FALSE,
|
||||
'is_serialized' => FALSE,
|
||||
'no_description' => FALSE,
|
||||
'search_custom' => FALSE,
|
||||
'is_deleted' => FALSE);
|
||||
|
||||
// check if any filter is set in the multiselect dropdown
|
||||
$filledup = array_fill_keys($this->input->get('filters'), TRUE);
|
||||
$filters = array_merge($filters, $filledup);
|
||||
|
||||
$items = $this->Item->search($search, $filters, $limit, $offset, $sort, $order);
|
||||
|
||||
$total_rows = $this->Item->get_found_rows($search, $filters);
|
||||
|
||||
$data_rows = array();
|
||||
foreach($items->result() as $item)
|
||||
{
|
||||
$data_rows[] = $this->xss_clean(get_item_data_row($item));
|
||||
if($item->pic_filename!='')
|
||||
{
|
||||
$this->_update_pic_filename($item);
|
||||
}
|
||||
}
|
||||
|
||||
echo json_encode(array('total' => $total_rows, 'rows' => $data_rows));
|
||||
}
|
||||
|
||||
public function pic_thumb($pic_filename)
|
||||
{
|
||||
$this->load->helper('file');
|
||||
$this->load->library('image_lib');
|
||||
|
||||
// in this context, $pic_filename always has .ext
|
||||
$ext = pathinfo($pic_filename, PATHINFO_EXTENSION);
|
||||
$images = glob('./uploads/item_pics/' . $pic_filename);
|
||||
|
||||
// make sure we pick only the file name, without extension
|
||||
$base_path = './uploads/item_pics/' . pathinfo($pic_filename, PATHINFO_FILENAME);
|
||||
if(sizeof($images) > 0)
|
||||
{
|
||||
$image_path = $images[0];
|
||||
$thumb_path = $base_path . $this->image_lib->thumb_marker . '.' . $ext;
|
||||
if(sizeof($images) < 2)
|
||||
{
|
||||
$config['image_library'] = 'gd2';
|
||||
$config['source_image'] = $image_path;
|
||||
$config['maintain_ratio'] = TRUE;
|
||||
$config['create_thumb'] = TRUE;
|
||||
$config['width'] = 52;
|
||||
$config['height'] = 32;
|
||||
$this->image_lib->initialize($config);
|
||||
$image = $this->image_lib->resize();
|
||||
$thumb_path = $this->image_lib->full_dst_path;
|
||||
}
|
||||
$this->output->set_content_type(get_mime_by_extension($thumb_path));
|
||||
$this->output->set_output(file_get_contents($thumb_path));
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
Gives search suggestions based on what is being searched for
|
||||
*/
|
||||
public function suggest_search()
|
||||
{
|
||||
$suggestions = $this->xss_clean($this->Item->get_search_suggestions($this->input->post_get('term'),
|
||||
array('search_custom' => $this->input->post('search_custom'), 'is_deleted' => $this->input->post('is_deleted') != NULL), FALSE));
|
||||
|
||||
echo json_encode($suggestions);
|
||||
}
|
||||
|
||||
public function suggest()
|
||||
{
|
||||
$suggestions = $this->xss_clean($this->Item->get_search_suggestions($this->input->post_get('term'),
|
||||
array('search_custom' => FALSE, 'is_deleted' => FALSE), TRUE));
|
||||
|
||||
echo json_encode($suggestions);
|
||||
}
|
||||
|
||||
public function suggest_kits()
|
||||
{
|
||||
$suggestions = $this->xss_clean($this->Item->get_kit_search_suggestions($this->input->post_get('term'),
|
||||
array('search_custom' => FALSE, 'is_deleted' => FALSE), TRUE));
|
||||
|
||||
echo json_encode($suggestions);
|
||||
}
|
||||
|
||||
/*
|
||||
Gives search suggestions based on what is being searched for
|
||||
*/
|
||||
public function suggest_category()
|
||||
{
|
||||
$suggestions = $this->xss_clean($this->Item->get_category_suggestions($this->input->get('term')));
|
||||
|
||||
echo json_encode($suggestions);
|
||||
}
|
||||
|
||||
/*
|
||||
Gives search suggestions based on what is being searched for
|
||||
*/
|
||||
public function suggest_location()
|
||||
{
|
||||
$suggestions = $this->xss_clean($this->Item->get_location_suggestions($this->input->get('term')));
|
||||
|
||||
echo json_encode($suggestions);
|
||||
}
|
||||
|
||||
/*
|
||||
Gives search suggestions based on what is being searched for
|
||||
*/
|
||||
public function suggest_custom()
|
||||
{
|
||||
$suggestions = $this->xss_clean($this->Item->get_custom_suggestions($this->input->post('term'), $this->input->post('field_no')));
|
||||
|
||||
echo json_encode($suggestions);
|
||||
}
|
||||
|
||||
public function get_row($item_ids)
|
||||
{
|
||||
$item_infos = $this->Item->get_multiple_info(explode(":", $item_ids), $this->item_lib->get_item_location());
|
||||
|
||||
$result = array();
|
||||
foreach($item_infos->result() as $item_info)
|
||||
{
|
||||
$result[$item_info->item_id] = $this->xss_clean(get_item_data_row($item_info));
|
||||
}
|
||||
|
||||
echo json_encode($result);
|
||||
}
|
||||
|
||||
public function view($item_id = -1)
|
||||
{
|
||||
$data['item_tax_info'] = $this->xss_clean($this->Item_taxes->get_info($item_id));
|
||||
$data['default_tax_1_rate'] = '';
|
||||
$data['default_tax_2_rate'] = '';
|
||||
$data['item_kits_enabled'] = $this->Employee->has_grant('item_kits', $this->Employee->get_logged_in_employee_info()->person_id);
|
||||
|
||||
$item_info = $this->Item->get_info($item_id);
|
||||
foreach(get_object_vars($item_info) as $property => $value)
|
||||
{
|
||||
$item_info->$property = $this->xss_clean($value);
|
||||
}
|
||||
|
||||
if($item_id == -1)
|
||||
{
|
||||
$data['default_tax_1_rate'] = $this->config->item('default_tax_1_rate');
|
||||
$data['default_tax_2_rate'] = $this->config->item('default_tax_2_rate');
|
||||
|
||||
$item_info->receiving_quantity = 1;
|
||||
$item_info->reorder_level = 1;
|
||||
$item_info->item_type = ITEM; // standard
|
||||
$item_info->stock_type = HAS_STOCK;
|
||||
$item_info->tax_category_id = 1; // Standard
|
||||
}
|
||||
|
||||
$data['item_info'] = $item_info;
|
||||
|
||||
$suppliers = array('' => $this->lang->line('items_none'));
|
||||
foreach($this->Supplier->get_all()->result_array() as $row)
|
||||
{
|
||||
$suppliers[$this->xss_clean($row['person_id'])] = $this->xss_clean($row['company_name']);
|
||||
}
|
||||
$data['suppliers'] = $suppliers;
|
||||
$data['selected_supplier'] = $item_info->supplier_id;
|
||||
|
||||
$customer_sales_tax_support = $this->config->item('customer_sales_tax_support');
|
||||
if($customer_sales_tax_support == '1')
|
||||
{
|
||||
$data['customer_sales_tax_enabled'] = TRUE;
|
||||
$tax_categories = array();
|
||||
foreach($this->Tax->get_all_tax_categories()->result_array() as $row)
|
||||
{
|
||||
$tax_categories[$this->xss_clean($row['tax_category_id'])] = $this->xss_clean($row['tax_category']);
|
||||
}
|
||||
$data['tax_categories'] = $tax_categories;
|
||||
$data['selected_tax_category'] = $item_info->tax_category_id;
|
||||
}
|
||||
else
|
||||
{
|
||||
$data['customer_sales_tax_enabled'] = FALSE;
|
||||
$data['tax_categories'] = array();
|
||||
$data['selected_tax_category'] = '';
|
||||
}
|
||||
|
||||
$data['logo_exists'] = $item_info->pic_filename != '';
|
||||
$ext = pathinfo($item_info->pic_filename, PATHINFO_EXTENSION);
|
||||
if($ext == '')
|
||||
{
|
||||
// if file extension is not found guess it (legacy)
|
||||
$images = glob('./uploads/item_pics/' . $item_info->pic_filename . '.*');
|
||||
}
|
||||
else
|
||||
{
|
||||
// else just pick that file
|
||||
$images = glob('./uploads/item_pics/' . $item_info->pic_filename);
|
||||
}
|
||||
$data['image_path'] = sizeof($images) > 0 ? base_url($images[0]) : '';
|
||||
$stock_locations = $this->Stock_location->get_undeleted_all()->result_array();
|
||||
foreach($stock_locations as $location)
|
||||
{
|
||||
$location = $this->xss_clean($location);
|
||||
|
||||
$quantity = $this->xss_clean($this->Item_quantity->get_item_quantity($item_id, $location['location_id'])->quantity);
|
||||
$quantity = ($item_id == -1) ? 0 : $quantity;
|
||||
$location_array[$location['location_id']] = array('location_name' => $location['location_name'], 'quantity' => $quantity);
|
||||
$data['stock_locations'] = $location_array;
|
||||
}
|
||||
|
||||
$this->load->view('items/form', $data);
|
||||
}
|
||||
|
||||
public function inventory($item_id = -1)
|
||||
{
|
||||
$item_info = $this->Item->get_info($item_id);
|
||||
foreach(get_object_vars($item_info) as $property => $value)
|
||||
{
|
||||
$item_info->$property = $this->xss_clean($value);
|
||||
}
|
||||
$data['item_info'] = $item_info;
|
||||
|
||||
$data['stock_locations'] = array();
|
||||
$stock_locations = $this->Stock_location->get_undeleted_all()->result_array();
|
||||
foreach($stock_locations as $location)
|
||||
{
|
||||
$location = $this->xss_clean($location);
|
||||
$quantity = $this->xss_clean($this->Item_quantity->get_item_quantity($item_id, $location['location_id'])->quantity);
|
||||
|
||||
$data['stock_locations'][$location['location_id']] = $location['location_name'];
|
||||
$data['item_quantities'][$location['location_id']] = $quantity;
|
||||
}
|
||||
|
||||
$this->load->view('items/form_inventory', $data);
|
||||
}
|
||||
|
||||
public function count_details($item_id = -1)
|
||||
{
|
||||
$item_info = $this->Item->get_info($item_id);
|
||||
foreach(get_object_vars($item_info) as $property => $value)
|
||||
{
|
||||
$item_info->$property = $this->xss_clean($value);
|
||||
}
|
||||
$data['item_info'] = $item_info;
|
||||
|
||||
$data['stock_locations'] = array();
|
||||
$stock_locations = $this->Stock_location->get_undeleted_all()->result_array();
|
||||
foreach($stock_locations as $location)
|
||||
{
|
||||
$location = $this->xss_clean($location);
|
||||
$quantity = $this->xss_clean($this->Item_quantity->get_item_quantity($item_id, $location['location_id'])->quantity);
|
||||
|
||||
$data['stock_locations'][$location['location_id']] = $location['location_name'];
|
||||
$data['item_quantities'][$location['location_id']] = $quantity;
|
||||
}
|
||||
|
||||
$this->load->view('items/form_count_details', $data);
|
||||
}
|
||||
|
||||
public function generate_barcodes($item_ids)
|
||||
{
|
||||
$this->load->library('barcode_lib');
|
||||
|
||||
$item_ids = explode(':', $item_ids);
|
||||
$result = $this->Item->get_multiple_info($item_ids, $this->item_lib->get_item_location())->result_array();
|
||||
$config = $this->barcode_lib->get_barcode_config();
|
||||
|
||||
$data['barcode_config'] = $config;
|
||||
|
||||
// check the list of items to see if any item_number field is empty
|
||||
foreach($result as &$item)
|
||||
{
|
||||
$item = $this->xss_clean($item);
|
||||
|
||||
// update the barcode field if empty / NULL with the newly generated barcode
|
||||
if(empty($item['item_number']) && $this->config->item('barcode_generate_if_empty'))
|
||||
{
|
||||
// get the newly generated barcode
|
||||
$barcode_instance = Barcode_lib::barcode_instance($item, $config);
|
||||
$item['item_number'] = $barcode_instance->getData();
|
||||
|
||||
$save_item = array('item_number' => $item['item_number']);
|
||||
|
||||
// update the item in the database in order to save the barcode field
|
||||
$this->Item->save($save_item, $item['item_id']);
|
||||
}
|
||||
}
|
||||
$data['items'] = $result;
|
||||
|
||||
// display barcodes
|
||||
$this->load->view('barcodes/barcode_sheet', $data);
|
||||
}
|
||||
|
||||
public function bulk_edit()
|
||||
{
|
||||
$suppliers = array('' => $this->lang->line('items_none'));
|
||||
foreach($this->Supplier->get_all()->result_array() as $row)
|
||||
{
|
||||
$row = $this->xss_clean($row);
|
||||
|
||||
$suppliers[$row['person_id']] = $row['company_name'];
|
||||
}
|
||||
$data['suppliers'] = $suppliers;
|
||||
$data['allow_alt_description_choices'] = array(
|
||||
'' => $this->lang->line('items_do_nothing'),
|
||||
1 => $this->lang->line('items_change_all_to_allow_alt_desc'),
|
||||
0 => $this->lang->line('items_change_all_to_not_allow_allow_desc'));
|
||||
|
||||
$data['serialization_choices'] = array(
|
||||
'' => $this->lang->line('items_do_nothing'),
|
||||
1 => $this->lang->line('items_change_all_to_serialized'),
|
||||
0 => $this->lang->line('items_change_all_to_unserialized'));
|
||||
|
||||
$this->load->view('items/form_bulk', $data);
|
||||
}
|
||||
|
||||
public function save($item_id = -1)
|
||||
{
|
||||
$upload_success = $this->_handle_image_upload();
|
||||
$upload_data = $this->upload->data();
|
||||
|
||||
//Save item data
|
||||
$item_data = array(
|
||||
'name' => $this->input->post('name'),
|
||||
'description' => $this->input->post('description'),
|
||||
'category' => $this->input->post('category'),
|
||||
'item_type' => $this->input->post('item_type') == NULL ? ITEM : $this->input->post('item_type'),
|
||||
'stock_type' => $this->input->post('stock_type') == NULL ? HAS_STOCK : $this->input->post('stock_type'),
|
||||
'supplier_id' => $this->input->post('supplier_id') == '' ? NULL : $this->input->post('supplier_id'),
|
||||
'item_number' => $this->input->post('item_number') == '' ? NULL : $this->input->post('item_number'),
|
||||
'cost_price' => parse_decimals($this->input->post('cost_price')),
|
||||
'unit_price' => parse_decimals($this->input->post('unit_price')),
|
||||
'reorder_level' => parse_decimals($this->input->post('reorder_level')),
|
||||
'receiving_quantity' => parse_decimals($this->input->post('receiving_quantity')),
|
||||
'allow_alt_description' => $this->input->post('allow_alt_description') != NULL,
|
||||
'is_serialized' => $this->input->post('is_serialized') != NULL,
|
||||
'deleted' => $this->input->post('is_deleted') != NULL,
|
||||
'custom1' => $this->input->post('custom1') == NULL ? '' : $this->input->post('custom1'),
|
||||
'custom2' => $this->input->post('custom2') == NULL ? '' : $this->input->post('custom2'),
|
||||
'custom3' => $this->input->post('custom3') == NULL ? '' : $this->input->post('custom3'),
|
||||
'custom4' => $this->input->post('custom4') == NULL ? '' : $this->input->post('custom4'),
|
||||
'custom5' => $this->input->post('custom5') == NULL ? '' : $this->input->post('custom5'),
|
||||
'custom6' => $this->input->post('custom6') == NULL ? '' : $this->input->post('custom6'),
|
||||
'custom7' => $this->input->post('custom7') == NULL ? '' : $this->input->post('custom7'),
|
||||
'custom8' => $this->input->post('custom8') == NULL ? '' : $this->input->post('custom8'),
|
||||
'custom9' => $this->input->post('custom9') == NULL ? '' : $this->input->post('custom9'),
|
||||
'custom10' => $this->input->post('custom10') == NULL ? '' : $this->input->post('custom10')
|
||||
);
|
||||
|
||||
$x = $this->input->post('tax_category_id');
|
||||
if(!isset($x))
|
||||
{
|
||||
$item_data['tax_category_id'] = '';
|
||||
}
|
||||
else
|
||||
{
|
||||
$item_data['tax_category_id'] = $this->input->post('tax_category_id');
|
||||
}
|
||||
|
||||
if(!empty($upload_data['orig_name']))
|
||||
{
|
||||
// XSS file image sanity check
|
||||
if($this->xss_clean($upload_data['raw_name'], TRUE) === TRUE)
|
||||
{
|
||||
$item_data['pic_filename'] = $upload_data['raw_name'];
|
||||
}
|
||||
}
|
||||
|
||||
$employee_id = $this->Employee->get_logged_in_employee_info()->person_id;
|
||||
$cur_item_info = $this->Item->get_info($item_id);
|
||||
|
||||
if($this->Item->save($item_data, $item_id))
|
||||
{
|
||||
$success = TRUE;
|
||||
$new_item = FALSE;
|
||||
//New item
|
||||
if($item_id == -1)
|
||||
{
|
||||
$item_id = $item_data['item_id'];
|
||||
$new_item = TRUE;
|
||||
}
|
||||
|
||||
$items_taxes_data = array();
|
||||
$tax_names = $this->input->post('tax_names');
|
||||
$tax_percents = $this->input->post('tax_percents');
|
||||
$count = count($tax_percents);
|
||||
for ($k = 0; $k < $count; ++$k)
|
||||
{
|
||||
$tax_percentage = parse_decimals($tax_percents[$k]);
|
||||
if(is_numeric($tax_percentage))
|
||||
{
|
||||
$items_taxes_data[] = array('name' => $tax_names[$k], 'percent' => $tax_percentage);
|
||||
}
|
||||
}
|
||||
$success &= $this->Item_taxes->save($items_taxes_data, $item_id);
|
||||
|
||||
//Save item quantity
|
||||
$stock_locations = $this->Stock_location->get_undeleted_all()->result_array();
|
||||
foreach($stock_locations as $location)
|
||||
{
|
||||
$updated_quantity = parse_decimals($this->input->post('quantity_' . $location['location_id']));
|
||||
$location_detail = array('item_id' => $item_id,
|
||||
'location_id' => $location['location_id'],
|
||||
'quantity' => $updated_quantity);
|
||||
$item_quantity = $this->Item_quantity->get_item_quantity($item_id, $location['location_id']);
|
||||
if($item_quantity->quantity != $updated_quantity || $new_item)
|
||||
{
|
||||
$success &= $this->Item_quantity->save($location_detail, $item_id, $location['location_id']);
|
||||
|
||||
$inv_data = array(
|
||||
'trans_date' => date('Y-m-d H:i:s'),
|
||||
'trans_items' => $item_id,
|
||||
'trans_user' => $employee_id,
|
||||
'trans_location' => $location['location_id'],
|
||||
'trans_comment' => $this->lang->line('items_manually_editing_of_quantity'),
|
||||
'trans_inventory' => $updated_quantity - $item_quantity->quantity
|
||||
);
|
||||
|
||||
$success &= $this->Inventory->insert($inv_data);
|
||||
}
|
||||
}
|
||||
|
||||
if($success && $upload_success)
|
||||
{
|
||||
$message = $this->xss_clean($this->lang->line('items_successful_' . ($new_item ? 'adding' : 'updating')) . ' ' . $item_data['name']);
|
||||
|
||||
echo json_encode(array('success' => TRUE, 'message' => $message, 'id' => $item_id));
|
||||
}
|
||||
else
|
||||
{
|
||||
$message = $this->xss_clean($upload_success ? $this->lang->line('items_error_adding_updating') . ' ' . $item_data['name'] : strip_tags($this->upload->display_errors()));
|
||||
|
||||
echo json_encode(array('success' => FALSE, 'message' => $message, 'id' => $item_id));
|
||||
}
|
||||
}
|
||||
else // failure
|
||||
{
|
||||
$message = $this->xss_clean($this->lang->line('items_error_adding_updating') . ' ' . $item_data['name']);
|
||||
|
||||
echo json_encode(array('success' => FALSE, 'message' => $message, 'id' => -1));
|
||||
}
|
||||
}
|
||||
|
||||
public function check_item_number()
|
||||
{
|
||||
$exists = $this->Item->item_number_exists($this->input->post('item_number'), $this->input->post('item_id'));
|
||||
echo !$exists ? 'true' : 'false';
|
||||
}
|
||||
|
||||
/*
|
||||
If adding a new item check to see if an item kit with the same name as the item already exists.
|
||||
*/
|
||||
public function check_kit_exists()
|
||||
{
|
||||
if($this->input->post('item_number') === -1)
|
||||
{
|
||||
$exists = $this->Item_kit->item_kit_exists_for_name($this->input->post('name'));
|
||||
}
|
||||
else
|
||||
{
|
||||
$exists = FALSE;
|
||||
}
|
||||
echo !$exists ? 'true' : 'false';
|
||||
}
|
||||
|
||||
private function _handle_image_upload()
|
||||
{
|
||||
/* Let files be uploaded with their original name */
|
||||
|
||||
// load upload library
|
||||
$config = array('upload_path' => './uploads/item_pics/',
|
||||
'allowed_types' => 'gif|jpg|png',
|
||||
'max_size' => '100',
|
||||
'max_width' => '640',
|
||||
'max_height' => '480'
|
||||
);
|
||||
$this->load->library('upload', $config);
|
||||
$this->upload->do_upload('item_image');
|
||||
|
||||
return strlen($this->upload->display_errors()) == 0 || !strcmp($this->upload->display_errors(), '<p>'.$this->lang->line('upload_no_file_selected').'</p>');
|
||||
}
|
||||
|
||||
public function remove_logo($item_id)
|
||||
{
|
||||
$item_data = array('pic_filename' => NULL);
|
||||
$result = $this->Item->save($item_data, $item_id);
|
||||
|
||||
echo json_encode(array('success' => $result));
|
||||
}
|
||||
|
||||
public function save_inventory($item_id = -1)
|
||||
{
|
||||
$employee_id = $this->Employee->get_logged_in_employee_info()->person_id;
|
||||
$cur_item_info = $this->Item->get_info($item_id);
|
||||
$location_id = $this->input->post('stock_location');
|
||||
$inv_data = array(
|
||||
'trans_date' => date('Y-m-d H:i:s'),
|
||||
'trans_items' => $item_id,
|
||||
'trans_user' => $employee_id,
|
||||
'trans_location' => $location_id,
|
||||
'trans_comment' => $this->input->post('trans_comment'),
|
||||
'trans_inventory' => parse_decimals($this->input->post('newquantity'))
|
||||
);
|
||||
|
||||
$this->Inventory->insert($inv_data);
|
||||
|
||||
//Update stock quantity
|
||||
$item_quantity = $this->Item_quantity->get_item_quantity($item_id, $location_id);
|
||||
$item_quantity_data = array(
|
||||
'item_id' => $item_id,
|
||||
'location_id' => $location_id,
|
||||
'quantity' => $item_quantity->quantity + parse_decimals($this->input->post('newquantity'))
|
||||
);
|
||||
|
||||
if($this->Item_quantity->save($item_quantity_data, $item_id, $location_id))
|
||||
{
|
||||
$message = $this->xss_clean($this->lang->line('items_successful_updating') . ' ' . $cur_item_info->name);
|
||||
|
||||
echo json_encode(array('success' => TRUE, 'message' => $message, 'id' => $item_id));
|
||||
}
|
||||
else//failure
|
||||
{
|
||||
$message = $this->xss_clean($this->lang->line('items_error_adding_updating') . ' ' . $cur_item_info->name);
|
||||
|
||||
echo json_encode(array('success' => FALSE, 'message' => $message, 'id' => -1));
|
||||
}
|
||||
}
|
||||
|
||||
public function bulk_update()
|
||||
{
|
||||
$items_to_update = $this->input->post('item_ids');
|
||||
$item_data = array();
|
||||
|
||||
foreach($_POST as $key => $value)
|
||||
{
|
||||
//This field is nullable, so treat it differently
|
||||
if($key == 'supplier_id' && $value != '')
|
||||
{
|
||||
$item_data["$key"] = $value;
|
||||
}
|
||||
elseif($value != '' && !(in_array($key, array('item_ids', 'tax_names', 'tax_percents'))))
|
||||
{
|
||||
$item_data["$key"] = $value;
|
||||
}
|
||||
}
|
||||
|
||||
//Item data could be empty if tax information is being updated
|
||||
if(empty($item_data) || $this->Item->update_multiple($item_data, $items_to_update))
|
||||
{
|
||||
$items_taxes_data = array();
|
||||
$tax_names = $this->input->post('tax_names');
|
||||
$tax_percents = $this->input->post('tax_percents');
|
||||
$tax_updated = FALSE;
|
||||
$count = count($tax_percents);
|
||||
for ($k = 0; $k < $count; ++$k)
|
||||
{
|
||||
if(!empty($tax_names[$k]) && is_numeric($tax_percents[$k]))
|
||||
{
|
||||
$tax_updated = TRUE;
|
||||
|
||||
$items_taxes_data[] = array('name' => $tax_names[$k], 'percent' => $tax_percents[$k]);
|
||||
}
|
||||
}
|
||||
|
||||
if($tax_updated)
|
||||
{
|
||||
$this->Item_taxes->save_multiple($items_taxes_data, $items_to_update);
|
||||
}
|
||||
|
||||
echo json_encode(array('success' => TRUE, 'message' => $this->lang->line('items_successful_bulk_edit'), 'id' => $this->xss_clean($items_to_update)));
|
||||
}
|
||||
else
|
||||
{
|
||||
echo json_encode(array('success' => FALSE, 'message' => $this->lang->line('items_error_updating_multiple')));
|
||||
}
|
||||
}
|
||||
|
||||
public function delete()
|
||||
{
|
||||
$items_to_delete = $this->input->post('ids');
|
||||
|
||||
if($this->Item->delete_list($items_to_delete))
|
||||
{
|
||||
$message = $this->lang->line('items_successful_deleted') . ' ' . count($items_to_delete) . ' ' . $this->lang->line('items_one_or_multiple');
|
||||
echo json_encode(array('success' => TRUE, 'message' => $message));
|
||||
}
|
||||
else
|
||||
{
|
||||
echo json_encode(array('success' => FALSE, 'message' => $this->lang->line('items_cannot_be_deleted')));
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
Items import from excel spreadsheet
|
||||
*/
|
||||
public function excel()
|
||||
{
|
||||
$name = 'import_items.csv';
|
||||
$data = file_get_contents('../' . $name);
|
||||
force_download($name, $data);
|
||||
}
|
||||
|
||||
public function excel_import()
|
||||
{
|
||||
$this->load->view('items/form_excel_import', NULL);
|
||||
}
|
||||
|
||||
public function do_excel_import()
|
||||
{
|
||||
if($_FILES['file_path']['error'] != UPLOAD_ERR_OK)
|
||||
{
|
||||
echo json_encode(array('success' => FALSE, 'message' => $this->lang->line('items_excel_import_failed')));
|
||||
}
|
||||
else
|
||||
{
|
||||
if(($handle = fopen($_FILES['file_path']['tmp_name'], 'r')) !== FALSE)
|
||||
{
|
||||
// Skip the first row as it's the table description
|
||||
fgetcsv($handle);
|
||||
$i = 1;
|
||||
|
||||
$failCodes = array();
|
||||
|
||||
while(($data = fgetcsv($handle)) !== FALSE)
|
||||
{
|
||||
// XSS file data sanity check
|
||||
$data = $this->xss_clean($data);
|
||||
|
||||
/* haven't touched this so old templates will work, or so I guess... */
|
||||
if(sizeof($data) >= 23)
|
||||
{
|
||||
$item_data = array(
|
||||
'name' => $data[1],
|
||||
'description' => $data[11],
|
||||
'category' => $data[2],
|
||||
'cost_price' => $data[4],
|
||||
'unit_price' => $data[5],
|
||||
'reorder_level' => $data[10],
|
||||
'supplier_id' => $this->Supplier->exists($data[3]) ? $data[3] : NULL,
|
||||
'allow_alt_description' => $data[12] != '' ? '1' : '0',
|
||||
'is_serialized' => $data[13] != '' ? '1' : '0',
|
||||
'custom1' => $data[14],
|
||||
'custom2' => $data[15],
|
||||
'custom3' => $data[16],
|
||||
'custom4' => $data[17],
|
||||
'custom5' => $data[18],
|
||||
'custom6' => $data[19],
|
||||
'custom7' => $data[20],
|
||||
'custom8' => $data[21],
|
||||
'custom9' => $data[22],
|
||||
'custom10' => $data[23]
|
||||
);
|
||||
|
||||
/* we could do something like this, however, the effectiveness of
|
||||
this is rather limited, since for now, you have to upload files manually
|
||||
into that directory, so you really can do whatever you want, this probably
|
||||
needs further discussion */
|
||||
|
||||
$pic_file = $data[24];
|
||||
/*if(strcmp('.htaccess', $pic_file)==0)
|
||||
{
|
||||
$pic_file='';
|
||||
}*/
|
||||
$item_data['pic_filename'] = $pic_file;
|
||||
|
||||
$item_number = $data[0];
|
||||
$invalidated = FALSE;
|
||||
if($item_number != '')
|
||||
{
|
||||
$item_data['item_number'] = $item_number;
|
||||
$invalidated = $this->Item->item_number_exists($item_number);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$invalidated = TRUE;
|
||||
}
|
||||
|
||||
if(!$invalidated && $this->Item->save($item_data))
|
||||
{
|
||||
$items_taxes_data = NULL;
|
||||
//tax 1
|
||||
if(is_numeric($data[7]) && $data[6] != '')
|
||||
{
|
||||
$items_taxes_data[] = array('name' => $data[6], 'percent' => $data[7] );
|
||||
}
|
||||
|
||||
//tax 2
|
||||
if(is_numeric($data[9]) && $data[8] != '')
|
||||
{
|
||||
$items_taxes_data[] = array('name' => $data[8], 'percent' => $data[9] );
|
||||
}
|
||||
|
||||
// save tax values
|
||||
if(count($items_taxes_data) > 0)
|
||||
{
|
||||
$this->Item_taxes->save($items_taxes_data, $item_data['item_id']);
|
||||
}
|
||||
|
||||
// quantities & inventory Info
|
||||
$employee_id = $this->Employee->get_logged_in_employee_info()->person_id;
|
||||
$emp_info = $this->Employee->get_info($employee_id);
|
||||
$comment ='Qty CSV Imported';
|
||||
|
||||
$cols = count($data);
|
||||
|
||||
// array to store information if location got a quantity
|
||||
$allowed_locations = $this->Stock_location->get_allowed_locations();
|
||||
for($col = 25; $col < $cols; $col = $col + 2)
|
||||
{
|
||||
$location_id = $data[$col];
|
||||
if(array_key_exists($location_id, $allowed_locations))
|
||||
{
|
||||
$item_quantity_data = array(
|
||||
'item_id' => $item_data['item_id'],
|
||||
'location_id' => $location_id,
|
||||
'quantity' => $data[$col + 1],
|
||||
);
|
||||
$this->Item_quantity->save($item_quantity_data, $item_data['item_id'], $location_id);
|
||||
|
||||
$excel_data = array(
|
||||
'trans_items' => $item_data['item_id'],
|
||||
'trans_user' => $employee_id,
|
||||
'trans_comment' => $comment,
|
||||
'trans_location' => $data[$col],
|
||||
'trans_inventory' => $data[$col + 1]
|
||||
);
|
||||
|
||||
$this->Inventory->insert($excel_data);
|
||||
unset($allowed_locations[$location_id]);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* now iterate through the array and check for which location_id no entry into item_quantities was made yet
|
||||
* those get an entry with quantity as 0.
|
||||
* unfortunately a bit duplicate code from above...
|
||||
*/
|
||||
foreach($allowed_locations as $location_id => $location_name)
|
||||
{
|
||||
$item_quantity_data = array(
|
||||
'item_id' => $item_data['item_id'],
|
||||
'location_id' => $location_id,
|
||||
'quantity' => 0,
|
||||
);
|
||||
$this->Item_quantity->save($item_quantity_data, $item_data['item_id'], $data[$col]);
|
||||
|
||||
$excel_data = array(
|
||||
'trans_items' => $item_data['item_id'],
|
||||
'trans_user' => $employee_id,
|
||||
'trans_comment' => $comment,
|
||||
'trans_location' => $location_id,
|
||||
'trans_inventory' => 0
|
||||
);
|
||||
|
||||
$this->Inventory->insert($excel_data);
|
||||
}
|
||||
}
|
||||
else //insert or update item failure
|
||||
{
|
||||
$failCodes[] = $i;
|
||||
}
|
||||
|
||||
++$i;
|
||||
}
|
||||
|
||||
if(count($failCodes) > 0)
|
||||
{
|
||||
$message = $this->lang->line('items_excel_import_partially_failed') . ' (' . count($failCodes) . '): ' . implode(', ', $failCodes);
|
||||
|
||||
echo json_encode(array('success' => FALSE, 'message' => $message));
|
||||
}
|
||||
else
|
||||
{
|
||||
echo json_encode(array('success' => TRUE, 'message' => $this->lang->line('items_excel_import_success')));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
echo json_encode(array('success' => FALSE, 'message' => $this->lang->line('items_excel_import_nodata_wrongformat')));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Guess whether file extension is not in the table field,
|
||||
* if it isn't, then it's an old-format (formerly pic_id) field,
|
||||
* so we guess the right filename and update the table
|
||||
* @param $item the item to update
|
||||
*/
|
||||
private function _update_pic_filename($item)
|
||||
{
|
||||
$filename = pathinfo($item->pic_filename, PATHINFO_FILENAME);
|
||||
|
||||
// if the field is empty there's nothing to check
|
||||
if(!empty($filename))
|
||||
{
|
||||
$ext = pathinfo($item->pic_filename, PATHINFO_EXTENSION);
|
||||
if(empty($ext))
|
||||
{
|
||||
$images = glob('./uploads/item_pics/' . $item->pic_filename . '.*');
|
||||
if(sizeof($images) > 0)
|
||||
{
|
||||
$new_pic_filename = pathinfo($images[0], PATHINFO_BASENAME);
|
||||
$item_data = array('pic_filename' => $new_pic_filename);
|
||||
$this->Item->save($item_data, $item->item_id);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
?>
|
||||
104
application/controllers/Login.php
Normal file
104
application/controllers/Login.php
Normal file
@@ -0,0 +1,104 @@
|
||||
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
|
||||
|
||||
class Login extends CI_Controller
|
||||
{
|
||||
public function index()
|
||||
{
|
||||
if($this->Employee->is_logged_in())
|
||||
{
|
||||
redirect('home');
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->form_validation->set_error_delimiters('<div class="error">', '</div>');
|
||||
|
||||
$this->form_validation->set_rules('username', 'lang:login_username', 'required|callback_login_check');
|
||||
|
||||
if($this->config->item('gcaptcha_enable'))
|
||||
{
|
||||
$this->form_validation->set_rules('g-recaptcha-response', 'lang:login_gcaptcha', 'required|callback_gcaptcha_check');
|
||||
}
|
||||
|
||||
if($this->form_validation->run() == FALSE)
|
||||
{
|
||||
$this->load->view('login');
|
||||
}
|
||||
else
|
||||
{
|
||||
redirect('home');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function login_check($username)
|
||||
{
|
||||
$password = $this->input->post('password');
|
||||
|
||||
if(!$this->_installation_check())
|
||||
{
|
||||
$this->form_validation->set_message('login_check', $this->lang->line('login_invalid_installation'));
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if(!$this->Employee->login($username, $password))
|
||||
{
|
||||
$this->form_validation->set_message('login_check', $this->lang->line('login_invalid_username_and_password'));
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// trigger any required upgrade before starting the application
|
||||
$this->load->library('migration');
|
||||
$this->migration->latest();
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
public function gcaptcha_check($recaptchaResponse)
|
||||
{
|
||||
$url = 'https://www.google.com/recaptcha/api/siteverify?secret=' . $this->config->item('gcaptcha_secret_key') . '&response=' . $recaptchaResponse . '&remoteip=' . $this->input->ip_address();
|
||||
|
||||
$ch = curl_init();
|
||||
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
|
||||
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
|
||||
curl_setopt($ch, CURLOPT_URL, $url);
|
||||
$result = curl_exec($ch);
|
||||
curl_close($ch);
|
||||
|
||||
$status = json_decode($result, TRUE);
|
||||
|
||||
if(empty($status['success']))
|
||||
{
|
||||
$this->form_validation->set_message('gcaptcha_check', $this->lang->line('login_invalid_gcaptcha'));
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
private function _installation_check()
|
||||
{
|
||||
// get PHP extensions and check that the required ones are installed
|
||||
$extensions = implode(', ', get_loaded_extensions());
|
||||
$keys = array('bcmath', 'intl', 'gd', 'openssl', 'mbstring', 'curl');
|
||||
$pattern = '/';
|
||||
foreach($keys as $key)
|
||||
{
|
||||
$pattern .= '(?=.*\b' . preg_quote($key, '/') . '\b)';
|
||||
}
|
||||
$pattern .= '/i';
|
||||
$result = preg_match($pattern, $extensions);
|
||||
|
||||
if(!$result)
|
||||
{
|
||||
error_log('Check your php.ini');
|
||||
error_log('PHP installed extensions: ' . $extensions);
|
||||
error_log('PHP required extensions: ' . implode(', ', $keys));
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
?>
|
||||
65
application/controllers/Messages.php
Normal file
65
application/controllers/Messages.php
Normal file
@@ -0,0 +1,65 @@
|
||||
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
|
||||
|
||||
require_once("Secure_Controller.php");
|
||||
|
||||
class Messages extends Secure_Controller
|
||||
{
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct('messages');
|
||||
|
||||
$this->load->library('sms_lib');
|
||||
}
|
||||
|
||||
public function index()
|
||||
{
|
||||
$this->load->view('messages/sms');
|
||||
}
|
||||
|
||||
public function view($person_id = -1)
|
||||
{
|
||||
$info = $this->Person->get_info($person_id);
|
||||
foreach(get_object_vars($info) as $property => $value)
|
||||
{
|
||||
$info->$property = $this->xss_clean($value);
|
||||
}
|
||||
$data['person_info'] = $info;
|
||||
|
||||
$this->load->view('messages/form_sms', $data);
|
||||
}
|
||||
|
||||
public function send()
|
||||
{
|
||||
$phone = $this->input->post('phone');
|
||||
$message = $this->input->post('message');
|
||||
|
||||
$response = $this->sms_lib->sendSMS($phone, $message);
|
||||
|
||||
if($response)
|
||||
{
|
||||
echo json_encode(array('success' => TRUE, 'message' => $this->lang->line('messages_successfully_sent') . ' ' . $phone));
|
||||
}
|
||||
else
|
||||
{
|
||||
echo json_encode(array('success' => FALSE, 'message' => $this->lang->line('messages_unsuccessfully_sent') . ' ' . $phone));
|
||||
}
|
||||
}
|
||||
|
||||
public function send_form($person_id = -1)
|
||||
{
|
||||
$phone = $this->input->post('phone');
|
||||
$message = $this->input->post('message');
|
||||
|
||||
$response = $this->sms_lib->sendSMS($phone, $message);
|
||||
|
||||
if($response)
|
||||
{
|
||||
echo json_encode(array('success' => TRUE, 'message' => $this->lang->line('messages_successfully_sent') . ' ' . $phone, 'person_id' => $this->xss_clean($person_id)));
|
||||
}
|
||||
else
|
||||
{
|
||||
echo json_encode(array('success' => FALSE, 'message' => $this->lang->line('messages_unsuccessfully_sent') . ' ' . $phone, 'person_id' => -1));
|
||||
}
|
||||
}
|
||||
}
|
||||
?>
|
||||
15
application/controllers/No_access.php
Normal file
15
application/controllers/No_access.php
Normal file
@@ -0,0 +1,15 @@
|
||||
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
|
||||
|
||||
class No_Access extends CI_Controller
|
||||
{
|
||||
public function index($module_id = '', $permission_id = '')
|
||||
{
|
||||
$data['module_name'] = $this->Module->get_module_name($module_id);
|
||||
$data['permission_id'] = $permission_id;
|
||||
|
||||
$data = $this->security->xss_clean($data);
|
||||
|
||||
$this->load->view('no_access', $data);
|
||||
}
|
||||
}
|
||||
?>
|
||||
22
application/controllers/Office.php
Normal file
22
application/controllers/Office.php
Normal file
@@ -0,0 +1,22 @@
|
||||
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
|
||||
|
||||
require_once("Secure_Controller.php");
|
||||
|
||||
class Office extends Secure_Controller
|
||||
{
|
||||
function __construct()
|
||||
{
|
||||
parent::__construct('office', NULL, 'office');
|
||||
}
|
||||
|
||||
public function index()
|
||||
{
|
||||
$this->load->view('home/office');
|
||||
}
|
||||
|
||||
public function logout()
|
||||
{
|
||||
$this->Employee->logout();
|
||||
}
|
||||
}
|
||||
?>
|
||||
55
application/controllers/Persons.php
Normal file
55
application/controllers/Persons.php
Normal file
@@ -0,0 +1,55 @@
|
||||
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
|
||||
|
||||
require_once("Secure_Controller.php");
|
||||
|
||||
abstract class Persons extends Secure_Controller
|
||||
{
|
||||
public function __construct($module_id = NULL)
|
||||
{
|
||||
parent::__construct($module_id);
|
||||
}
|
||||
|
||||
public function index()
|
||||
{
|
||||
$data['table_headers'] = $this->xss_clean(get_people_manage_table_headers());
|
||||
|
||||
$this->load->view('people/manage', $data);
|
||||
}
|
||||
|
||||
/*
|
||||
Gives search suggestions based on what is being searched for
|
||||
*/
|
||||
public function suggest()
|
||||
{
|
||||
$suggestions = $this->xss_clean($this->Person->get_search_suggestions($this->input->post('term')));
|
||||
|
||||
echo json_encode($suggestions);
|
||||
}
|
||||
|
||||
/*
|
||||
Gets one row for a person manage table. This is called using AJAX to update one row.
|
||||
*/
|
||||
public function get_row($row_id)
|
||||
{
|
||||
$data_row = $this->xss_clean(get_person_data_row($this->Person->get_info($row_id)));
|
||||
|
||||
echo json_encode($data_row);
|
||||
}
|
||||
|
||||
/*
|
||||
Capitalize segments of a name, and put the rest into lower case.
|
||||
You can pass the characters you want to use as delimiters as exceptions.
|
||||
The function supports UTF-8 string.
|
||||
|
||||
Example:
|
||||
i.e. <?php echo nameize("john o'grady-smith"); ?>
|
||||
|
||||
returns John O'Grady-Smith
|
||||
*/
|
||||
|
||||
protected function nameize($string)
|
||||
{
|
||||
return str_name_case($string);
|
||||
}
|
||||
}
|
||||
?>
|
||||
402
application/controllers/Receivings.php
Normal file
402
application/controllers/Receivings.php
Normal file
@@ -0,0 +1,402 @@
|
||||
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
|
||||
|
||||
require_once("Secure_Controller.php");
|
||||
|
||||
class Receivings extends Secure_Controller
|
||||
{
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct('receivings');
|
||||
|
||||
$this->load->library('receiving_lib');
|
||||
$this->load->library('barcode_lib');
|
||||
}
|
||||
|
||||
public function index()
|
||||
{
|
||||
$this->_reload();
|
||||
}
|
||||
|
||||
public function item_search()
|
||||
{
|
||||
$suggestions = $this->Item->get_search_suggestions($this->input->get('term'), array('search_custom' => FALSE, 'is_deleted' => FALSE), TRUE);
|
||||
$suggestions = array_merge($suggestions, $this->Item_kit->get_search_suggestions($this->input->get('term')));
|
||||
|
||||
$suggestions = $this->xss_clean($suggestions);
|
||||
|
||||
echo json_encode($suggestions);
|
||||
}
|
||||
|
||||
public function stock_item_search()
|
||||
{
|
||||
$suggestions = $this->Item->get_stock_search_suggestions($this->input->get('term'), array('search_custom' => FALSE, 'is_deleted' => FALSE), TRUE);
|
||||
$suggestions = array_merge($suggestions, $this->Item_kit->get_search_suggestions($this->input->get('term')));
|
||||
|
||||
$suggestions = $this->xss_clean($suggestions);
|
||||
|
||||
echo json_encode($suggestions);
|
||||
}
|
||||
|
||||
public function select_supplier()
|
||||
{
|
||||
$supplier_id = $this->input->post('supplier');
|
||||
if($this->Supplier->exists($supplier_id))
|
||||
{
|
||||
$this->receiving_lib->set_supplier($supplier_id);
|
||||
}
|
||||
|
||||
$this->_reload();
|
||||
}
|
||||
|
||||
public function change_mode()
|
||||
{
|
||||
$stock_destination = $this->input->post('stock_destination');
|
||||
$stock_source = $this->input->post('stock_source');
|
||||
|
||||
if((!$stock_source || $stock_source == $this->receiving_lib->get_stock_source()) &&
|
||||
(!$stock_destination || $stock_destination == $this->receiving_lib->get_stock_destination()))
|
||||
{
|
||||
$this->receiving_lib->clear_reference();
|
||||
$mode = $this->input->post('mode');
|
||||
$this->receiving_lib->set_mode($mode);
|
||||
}
|
||||
elseif($this->Stock_location->is_allowed_location($stock_source, 'receivings'))
|
||||
{
|
||||
$this->receiving_lib->set_stock_source($stock_source);
|
||||
$this->receiving_lib->set_stock_destination($stock_destination);
|
||||
}
|
||||
|
||||
$this->_reload();
|
||||
}
|
||||
|
||||
public function set_comment()
|
||||
{
|
||||
$this->receiving_lib->set_comment($this->input->post('comment'));
|
||||
}
|
||||
|
||||
public function set_print_after_sale()
|
||||
{
|
||||
$this->receiving_lib->set_print_after_sale($this->input->post('recv_print_after_sale'));
|
||||
}
|
||||
|
||||
public function set_reference()
|
||||
{
|
||||
$this->receiving_lib->set_reference($this->input->post('recv_reference'));
|
||||
}
|
||||
|
||||
public function add()
|
||||
{
|
||||
$data = array();
|
||||
|
||||
$mode = $this->receiving_lib->get_mode();
|
||||
$item_id_or_number_or_item_kit_or_receipt = $this->input->post('item');
|
||||
$this->barcode_lib->parse_barcode_fields($quantity, $item_id_or_number_or_item_kit_or_receipt);
|
||||
$quantity = ($mode == 'receive' || $mode == 'requisition') ? $quantity : -$quantity;
|
||||
$item_location = $this->receiving_lib->get_stock_source();
|
||||
|
||||
if($mode == 'return' && $this->Receiving->is_valid_receipt($item_id_or_number_or_item_kit_or_receipt))
|
||||
{
|
||||
$this->receiving_lib->return_entire_receiving($item_id_or_number_or_item_kit_or_receipt);
|
||||
}
|
||||
elseif($this->Item_kit->is_valid_item_kit($item_id_or_number_or_item_kit_or_receipt))
|
||||
{
|
||||
$this->receiving_lib->add_item_kit($item_id_or_number_or_item_kit_or_receipt, $item_location);
|
||||
}
|
||||
elseif(!$this->receiving_lib->add_item($item_id_or_number_or_item_kit_or_receipt, $quantity, $item_location))
|
||||
{
|
||||
$data['error'] = $this->lang->line('receivings_unable_to_add_item');
|
||||
}
|
||||
|
||||
$this->_reload($data);
|
||||
}
|
||||
|
||||
public function edit_item($item_id)
|
||||
{
|
||||
$data = array();
|
||||
|
||||
$this->form_validation->set_rules('price', 'lang:items_price', 'required|callback_numeric');
|
||||
$this->form_validation->set_rules('quantity', 'lang:items_quantity', 'required|callback_numeric');
|
||||
$this->form_validation->set_rules('discount', 'lang:items_discount', 'required|callback_numeric');
|
||||
|
||||
$description = $this->input->post('description');
|
||||
$serialnumber = $this->input->post('serialnumber');
|
||||
$price = parse_decimals($this->input->post('price'));
|
||||
$quantity = parse_decimals($this->input->post('quantity'));
|
||||
$discount = parse_decimals($this->input->post('discount'));
|
||||
$item_location = $this->input->post('location');
|
||||
|
||||
if($this->form_validation->run() != FALSE)
|
||||
{
|
||||
$this->receiving_lib->edit_item($item_id, $description, $serialnumber, $quantity, $discount, $price);
|
||||
}
|
||||
else
|
||||
{
|
||||
$data['error']=$this->lang->line('receivings_error_editing_item');
|
||||
}
|
||||
|
||||
$this->_reload($data);
|
||||
}
|
||||
|
||||
public function edit($receiving_id)
|
||||
{
|
||||
$data = array();
|
||||
|
||||
$data['suppliers'] = array('' => 'No Supplier');
|
||||
foreach($this->Supplier->get_all()->result() as $supplier)
|
||||
{
|
||||
$data['suppliers'][$supplier->person_id] = $this->xss_clean($supplier->first_name . ' ' . $supplier->last_name);
|
||||
}
|
||||
|
||||
$data['employees'] = array();
|
||||
foreach($this->Employee->get_all()->result() as $employee)
|
||||
{
|
||||
$data['employees'][$employee->person_id] = $this->xss_clean($employee->first_name . ' '. $employee->last_name);
|
||||
}
|
||||
|
||||
$receiving_info = $this->xss_clean($this->Receiving->get_info($receiving_id)->row_array());
|
||||
$data['selected_supplier_name'] = !empty($receiving_info['supplier_id']) ? $receiving_info['company_name'] : '';
|
||||
$data['selected_supplier_id'] = $receiving_info['supplier_id'];
|
||||
$data['receiving_info'] = $receiving_info;
|
||||
|
||||
$this->load->view('receivings/form', $data);
|
||||
}
|
||||
|
||||
public function delete_item($item_number)
|
||||
{
|
||||
$this->receiving_lib->delete_item($item_number);
|
||||
|
||||
$this->_reload();
|
||||
}
|
||||
|
||||
public function delete($receiving_id = -1, $update_inventory = TRUE)
|
||||
{
|
||||
$employee_id = $this->Employee->get_logged_in_employee_info()->person_id;
|
||||
$receiving_ids = $receiving_id == -1 ? $this->input->post('ids') : array($receiving_id);
|
||||
|
||||
if($this->Receiving->delete_list($receiving_ids, $employee_id, $update_inventory))
|
||||
{
|
||||
echo json_encode(array('success' => TRUE, 'message' => $this->lang->line('receivings_successfully_deleted') . ' ' .
|
||||
count($receiving_ids) . ' ' . $this->lang->line('receivings_one_or_multiple'), 'ids' => $receiving_ids));
|
||||
}
|
||||
else
|
||||
{
|
||||
echo json_encode(array('success' => FALSE, 'message' => $this->lang->line('receivings_cannot_be_deleted')));
|
||||
}
|
||||
}
|
||||
|
||||
public function remove_supplier()
|
||||
{
|
||||
$this->receiving_lib->clear_reference();
|
||||
$this->receiving_lib->remove_supplier();
|
||||
|
||||
$this->_reload();
|
||||
}
|
||||
|
||||
public function complete()
|
||||
{
|
||||
$data = array();
|
||||
|
||||
$data['cart'] = $this->receiving_lib->get_cart();
|
||||
$data['total'] = $this->receiving_lib->get_total();
|
||||
$data['transaction_time'] = date($this->config->item('dateformat') . ' ' . $this->config->item('timeformat'));
|
||||
$data['mode'] = $this->receiving_lib->get_mode();
|
||||
$data['comment'] = $this->receiving_lib->get_comment();
|
||||
$data['reference'] = $this->receiving_lib->get_reference();
|
||||
$data['payment_type'] = $this->input->post('payment_type');
|
||||
$data['show_stock_locations'] = $this->Stock_location->show_locations('receivings');
|
||||
$data['stock_location'] = $this->receiving_lib->get_stock_source();
|
||||
if($this->input->post('amount_tendered') != NULL)
|
||||
{
|
||||
$data['amount_tendered'] = $this->input->post('amount_tendered');
|
||||
$data['amount_change'] = to_currency($data['amount_tendered'] - $data['total']);
|
||||
}
|
||||
|
||||
$employee_id = $this->Employee->get_logged_in_employee_info()->person_id;
|
||||
$employee_info = $this->Employee->get_info($employee_id);
|
||||
$data['employee'] = $employee_info->first_name . ' ' . $employee_info->last_name;
|
||||
|
||||
$supplier_info = '';
|
||||
$supplier_id = $this->receiving_lib->get_supplier();
|
||||
if($supplier_id != -1)
|
||||
{
|
||||
$supplier_info = $this->Supplier->get_info($supplier_id);
|
||||
$data['supplier'] = $supplier_info->company_name;
|
||||
$data['first_name'] = $supplier_info->first_name;
|
||||
$data['last_name'] = $supplier_info->last_name;
|
||||
$data['supplier_email'] = $supplier_info->email;
|
||||
$data['supplier_address'] = $supplier_info->address_1;
|
||||
if(!empty($supplier_info->zip) or !empty($supplier_info->city))
|
||||
{
|
||||
$data['supplier_location'] = $supplier_info->zip . ' ' . $supplier_info->city;
|
||||
}
|
||||
else
|
||||
{
|
||||
$data['supplier_location'] = '';
|
||||
}
|
||||
}
|
||||
|
||||
//SAVE receiving to database
|
||||
$data['receiving_id'] = 'RECV ' . $this->Receiving->save($data['cart'], $supplier_id, $employee_id, $data['comment'], $data['reference'], $data['payment_type'], $data['stock_location']);
|
||||
|
||||
$data = $this->xss_clean($data);
|
||||
|
||||
if($data['receiving_id'] == 'RECV -1')
|
||||
{
|
||||
$data['error_message'] = $this->lang->line('receivings_transaction_failed');
|
||||
}
|
||||
else
|
||||
{
|
||||
$data['barcode'] = $this->barcode_lib->generate_receipt_barcode($data['receiving_id']);
|
||||
}
|
||||
|
||||
$data['print_after_sale'] = $this->receiving_lib->is_print_after_sale();
|
||||
|
||||
$this->load->view("receivings/receipt",$data);
|
||||
|
||||
$this->receiving_lib->clear_all();
|
||||
}
|
||||
|
||||
public function requisition_complete()
|
||||
{
|
||||
if($this->receiving_lib->get_stock_source() != $this->receiving_lib->get_stock_destination())
|
||||
{
|
||||
foreach($this->receiving_lib->get_cart() as $item)
|
||||
{
|
||||
$this->receiving_lib->delete_item($item['line']);
|
||||
$this->receiving_lib->add_item($item['item_id'], $item['quantity'], $this->receiving_lib->get_stock_destination());
|
||||
$this->receiving_lib->add_item($item['item_id'], -$item['quantity'], $this->receiving_lib->get_stock_source());
|
||||
}
|
||||
|
||||
$this->complete();
|
||||
}
|
||||
else
|
||||
{
|
||||
$data['error'] = $this->lang->line('receivings_error_requisition');
|
||||
|
||||
$this->_reload($data);
|
||||
}
|
||||
}
|
||||
|
||||
public function receipt($receiving_id)
|
||||
{
|
||||
$receiving_info = $this->Receiving->get_info($receiving_id)->row_array();
|
||||
$this->receiving_lib->copy_entire_receiving($receiving_id);
|
||||
$data['cart'] = $this->receiving_lib->get_cart();
|
||||
$data['total'] = $this->receiving_lib->get_total();
|
||||
$data['mode'] = $this->receiving_lib->get_mode();
|
||||
$data['transaction_time'] = date($this->config->item('dateformat') . ' ' . $this->config->item('timeformat'), strtotime($receiving_info['receiving_time']));
|
||||
$data['show_stock_locations'] = $this->Stock_location->show_locations('receivings');
|
||||
$data['payment_type'] = $receiving_info['payment_type'];
|
||||
$data['reference'] = $this->receiving_lib->get_reference();
|
||||
$data['receiving_id'] = 'RECV ' . $receiving_id;
|
||||
$data['barcode'] = $this->barcode_lib->generate_receipt_barcode($data['receiving_id']);
|
||||
$employee_info = $this->Employee->get_info($receiving_info['employee_id']);
|
||||
$data['employee'] = $employee_info->first_name . ' ' . $employee_info->last_name;
|
||||
|
||||
$supplier_id = $this->receiving_lib->get_supplier();
|
||||
if($supplier_id != -1)
|
||||
{
|
||||
$supplier_info = $this->Supplier->get_info($supplier_id);
|
||||
$data['supplier'] = $supplier_info->company_name;
|
||||
$data['first_name'] = $supplier_info->first_name;
|
||||
$data['last_name'] = $supplier_info->last_name;
|
||||
$data['supplier_email'] = $supplier_info->email;
|
||||
$data['supplier_address'] = $supplier_info->address_1;
|
||||
if(!empty($supplier_info->zip) or !empty($supplier_info->city))
|
||||
{
|
||||
$data['supplier_location'] = $supplier_info->zip . ' ' . $supplier_info->city;
|
||||
}
|
||||
else
|
||||
{
|
||||
$data['supplier_location'] = '';
|
||||
}
|
||||
}
|
||||
|
||||
$data['print_after_sale'] = FALSE;
|
||||
|
||||
$data = $this->xss_clean($data);
|
||||
|
||||
$this->load->view("receivings/receipt", $data);
|
||||
|
||||
$this->receiving_lib->clear_all();
|
||||
}
|
||||
|
||||
private function _reload($data = array())
|
||||
{
|
||||
$data['cart'] = $this->receiving_lib->get_cart();
|
||||
$data['modes'] = array('receive' => $this->lang->line('receivings_receiving'), 'return' => $this->lang->line('receivings_return'));
|
||||
$data['mode'] = $this->receiving_lib->get_mode();
|
||||
$data['stock_locations'] = $this->Stock_location->get_allowed_locations('receivings');
|
||||
$data['show_stock_locations'] = count($data['stock_locations']) > 1;
|
||||
if($data['show_stock_locations'])
|
||||
{
|
||||
$data['modes']['requisition'] = $this->lang->line('receivings_requisition');
|
||||
$data['stock_source'] = $this->receiving_lib->get_stock_source();
|
||||
$data['stock_destination'] = $this->receiving_lib->get_stock_destination();
|
||||
}
|
||||
|
||||
$data['total'] = $this->receiving_lib->get_total();
|
||||
$data['items_module_allowed'] = $this->Employee->has_grant('items', $this->Employee->get_logged_in_employee_info()->person_id);
|
||||
$data['comment'] = $this->receiving_lib->get_comment();
|
||||
$data['reference'] = $this->receiving_lib->get_reference();
|
||||
$data['payment_options'] = $this->Receiving->get_payment_options();
|
||||
|
||||
$supplier_id = $this->receiving_lib->get_supplier();
|
||||
$supplier_info = '';
|
||||
if($supplier_id != -1)
|
||||
{
|
||||
$supplier_info = $this->Supplier->get_info($supplier_id);
|
||||
$data['supplier'] = $supplier_info->company_name;
|
||||
$data['first_name'] = $supplier_info->first_name;
|
||||
$data['last_name'] = $supplier_info->last_name;
|
||||
$data['supplier_email'] = $supplier_info->email;
|
||||
$data['supplier_address'] = $supplier_info->address_1;
|
||||
if(!empty($supplier_info->zip) or !empty($supplier_info->city))
|
||||
{
|
||||
$data['supplier_location'] = $supplier_info->zip . ' ' . $supplier_info->city;
|
||||
}
|
||||
else
|
||||
{
|
||||
$data['supplier_location'] = '';
|
||||
}
|
||||
}
|
||||
|
||||
$data['print_after_sale'] = $this->receiving_lib->is_print_after_sale();
|
||||
|
||||
$data = $this->xss_clean($data);
|
||||
|
||||
$this->load->view("receivings/receiving", $data);
|
||||
}
|
||||
|
||||
public function save($receiving_id = -1)
|
||||
{
|
||||
$newdate = $this->input->post('date');
|
||||
|
||||
$date_formatter = date_create_from_format($this->config->item('dateformat') . ' ' . $this->config->item('timeformat'), $newdate);
|
||||
|
||||
$receiving_data = array(
|
||||
'receiving_time' => $date_formatter->format('Y-m-d H:i:s'),
|
||||
'supplier_id' => $this->input->post('supplier_id') ? $this->input->post('supplier_id') : NULL,
|
||||
'employee_id' => $this->input->post('employee_id'),
|
||||
'comment' => $this->input->post('comment'),
|
||||
'reference' => $this->input->post('reference') != '' ? $this->input->post('reference') : NULL
|
||||
);
|
||||
|
||||
if($this->Receiving->update($receiving_data, $receiving_id))
|
||||
{
|
||||
echo json_encode(array('success' => TRUE, 'message' => $this->lang->line('receivings_successfully_updated'), 'id' => $receiving_id));
|
||||
}
|
||||
else
|
||||
{
|
||||
echo json_encode(array('success' => FALSE, 'message' => $this->lang->line('receivings_unsuccessfully_updated'), 'id' => $receiving_id));
|
||||
}
|
||||
}
|
||||
|
||||
public function cancel_receiving()
|
||||
{
|
||||
$this->receiving_lib->clear_all();
|
||||
|
||||
$this->_reload();
|
||||
}
|
||||
}
|
||||
?>
|
||||
1459
application/controllers/Reports.php
Normal file
1459
application/controllers/Reports.php
Normal file
File diff suppressed because it is too large
Load Diff
1392
application/controllers/Sales.php
Normal file
1392
application/controllers/Sales.php
Normal file
File diff suppressed because it is too large
Load Diff
103
application/controllers/Secure_Controller.php
Normal file
103
application/controllers/Secure_Controller.php
Normal file
@@ -0,0 +1,103 @@
|
||||
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
|
||||
|
||||
class Secure_Controller extends CI_Controller
|
||||
{
|
||||
/*
|
||||
* Controllers that are considered secure extend Secure_Controller, optionally a $module_id can
|
||||
* be set to also check if a user can access a particular module in the system.
|
||||
*/
|
||||
public function __construct($module_id = NULL, $submodule_id = NULL, $menu_group = NULL)
|
||||
{
|
||||
parent::__construct();
|
||||
|
||||
$this->load->model('Employee');
|
||||
$model = $this->Employee;
|
||||
|
||||
if(!$model->is_logged_in())
|
||||
{
|
||||
redirect('login');
|
||||
}
|
||||
|
||||
$logged_in_employee_info = $model->get_logged_in_employee_info();
|
||||
if(!$model->has_module_grant($module_id, $logged_in_employee_info->person_id) ||
|
||||
(isset($submodule_id) && !$model->has_module_grant($submodule_id, $logged_in_employee_info->person_id)))
|
||||
{
|
||||
redirect('no_access/' . $module_id . '/' . $submodule_id);
|
||||
}
|
||||
|
||||
// load up global data visible to all the loaded views
|
||||
|
||||
$this->load->library('session');
|
||||
if($menu_group == NULL)
|
||||
{
|
||||
$menu_group = $this->session->userdata('menu_group');
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->session->set_userdata('menu_group', $menu_group);
|
||||
}
|
||||
|
||||
if($menu_group == 'home')
|
||||
{
|
||||
$allowed_modules = $this->Module->get_allowed_home_modules($logged_in_employee_info->person_id);
|
||||
}
|
||||
else
|
||||
{
|
||||
$allowed_modules = $this->Module->get_allowed_office_modules($logged_in_employee_info->person_id);
|
||||
}
|
||||
|
||||
foreach($allowed_modules->result() as $module)
|
||||
{
|
||||
$data['allowed_modules'][] = $module;
|
||||
}
|
||||
|
||||
$data['user_info'] = $logged_in_employee_info;
|
||||
$data['controller_name'] = $module_id;
|
||||
|
||||
$this->load->vars($data);
|
||||
}
|
||||
|
||||
/*
|
||||
* Internal method to do XSS clean in the derived classes
|
||||
*/
|
||||
protected function xss_clean($str, $is_image = FALSE)
|
||||
{
|
||||
// This setting is configurable in application/config/config.php.
|
||||
// Users can disable the XSS clean for performance reasons
|
||||
// (cases like intranet installation with no Internet access)
|
||||
if($this->config->item('ospos_xss_clean') == FALSE)
|
||||
{
|
||||
return $str;
|
||||
}
|
||||
else
|
||||
{
|
||||
return $this->security->xss_clean($str, $is_image);
|
||||
}
|
||||
}
|
||||
|
||||
public function numeric($str)
|
||||
{
|
||||
return parse_decimals($str);
|
||||
}
|
||||
|
||||
public function check_numeric()
|
||||
{
|
||||
$result = TRUE;
|
||||
|
||||
foreach($this->input->get() as $str)
|
||||
{
|
||||
$result &= parse_decimals($str);
|
||||
}
|
||||
|
||||
echo $result !== FALSE ? 'true' : 'false';
|
||||
}
|
||||
|
||||
// this is the basic set of methods most OSPOS Controllers will implement
|
||||
public function index() { return FALSE; }
|
||||
public function search() { return FALSE; }
|
||||
public function suggest_search() { return FALSE; }
|
||||
public function view($data_item_id = -1) { return FALSE; }
|
||||
public function save($data_item_id = -1) { return FALSE; }
|
||||
public function delete() { return FALSE; }
|
||||
}
|
||||
?>
|
||||
165
application/controllers/Suppliers.php
Normal file
165
application/controllers/Suppliers.php
Normal file
@@ -0,0 +1,165 @@
|
||||
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
|
||||
|
||||
require_once("Persons.php");
|
||||
|
||||
class Suppliers extends Persons
|
||||
{
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct('suppliers');
|
||||
}
|
||||
|
||||
public function index()
|
||||
{
|
||||
$data['table_headers'] = $this->xss_clean(get_suppliers_manage_table_headers());
|
||||
|
||||
$this->load->view('people/manage', $data);
|
||||
}
|
||||
|
||||
/*
|
||||
Gets one row for a supplier manage table. This is called using AJAX to update one row.
|
||||
*/
|
||||
public function get_row($row_id)
|
||||
{
|
||||
$data_row = $this->xss_clean(get_supplier_data_row($this->Supplier->get_info($row_id)));
|
||||
|
||||
echo json_encode($data_row);
|
||||
}
|
||||
|
||||
/*
|
||||
Returns Supplier table data rows. This will be called with AJAX.
|
||||
*/
|
||||
public function search()
|
||||
{
|
||||
$search = $this->input->get('search');
|
||||
$limit = $this->input->get('limit');
|
||||
$offset = $this->input->get('offset');
|
||||
$sort = $this->input->get('sort');
|
||||
$order = $this->input->get('order');
|
||||
|
||||
$suppliers = $this->Supplier->search($search, $limit, $offset, $sort, $order);
|
||||
$total_rows = $this->Supplier->get_found_rows($search);
|
||||
|
||||
$data_rows = array();
|
||||
foreach($suppliers->result() as $supplier)
|
||||
{
|
||||
$data_rows[] = $this->xss_clean(get_supplier_data_row($supplier));
|
||||
}
|
||||
|
||||
echo json_encode(array('total' => $total_rows, 'rows' => $data_rows));
|
||||
}
|
||||
|
||||
/*
|
||||
Gives search suggestions based on what is being searched for
|
||||
*/
|
||||
public function suggest()
|
||||
{
|
||||
$suggestions = $this->xss_clean($this->Supplier->get_search_suggestions($this->input->get('term'), TRUE));
|
||||
|
||||
echo json_encode($suggestions);
|
||||
}
|
||||
|
||||
public function suggest_search()
|
||||
{
|
||||
$suggestions = $this->xss_clean($this->Supplier->get_search_suggestions($this->input->post('term'), FALSE));
|
||||
|
||||
echo json_encode($suggestions);
|
||||
}
|
||||
|
||||
/*
|
||||
Loads the supplier edit form
|
||||
*/
|
||||
public function view($supplier_id = -1)
|
||||
{
|
||||
$info = $this->Supplier->get_info($supplier_id);
|
||||
foreach(get_object_vars($info) as $property => $value)
|
||||
{
|
||||
$info->$property = $this->xss_clean($value);
|
||||
}
|
||||
$data['person_info'] = $info;
|
||||
|
||||
$this->load->view("suppliers/form", $data);
|
||||
}
|
||||
|
||||
/*
|
||||
Inserts/updates a supplier
|
||||
*/
|
||||
public function save($supplier_id = -1)
|
||||
{
|
||||
$first_name = $this->xss_clean($this->input->post('first_name'));
|
||||
$last_name = $this->xss_clean($this->input->post('last_name'));
|
||||
$email = $this->xss_clean(strtolower($this->input->post('email')));
|
||||
|
||||
// format first and last name properly
|
||||
$first_name = $this->nameize($first_name);
|
||||
$last_name = $this->nameize($last_name);
|
||||
|
||||
$person_data = array(
|
||||
'first_name' => $first_name,
|
||||
'last_name' => $last_name,
|
||||
'gender' => $this->input->post('gender'),
|
||||
'email' => $email,
|
||||
'phone_number' => $this->input->post('phone_number'),
|
||||
'address_1' => $this->input->post('address_1'),
|
||||
'address_2' => $this->input->post('address_2'),
|
||||
'city' => $this->input->post('city'),
|
||||
'state' => $this->input->post('state'),
|
||||
'zip' => $this->input->post('zip'),
|
||||
'country' => $this->input->post('country'),
|
||||
'comments' => $this->input->post('comments')
|
||||
);
|
||||
|
||||
$supplier_data = array(
|
||||
'company_name' => $this->input->post('company_name'),
|
||||
'agency_name' => $this->input->post('agency_name'),
|
||||
'account_number' => $this->input->post('account_number') == '' ? NULL : $this->input->post('account_number')
|
||||
);
|
||||
|
||||
if($this->Supplier->save_supplier($person_data, $supplier_data, $supplier_id))
|
||||
{
|
||||
$supplier_data = $this->xss_clean($supplier_data);
|
||||
|
||||
//New supplier
|
||||
if($supplier_id == -1)
|
||||
{
|
||||
echo json_encode(array('success' => TRUE,
|
||||
'message' => $this->lang->line('suppliers_successful_adding') . ' ' . $supplier_data['company_name'],
|
||||
'id' => $supplier_data['person_id']));
|
||||
}
|
||||
else //Existing supplier
|
||||
{
|
||||
echo json_encode(array('success' => TRUE,
|
||||
'message' => $this->lang->line('suppliers_successful_updating') . ' ' . $supplier_data['company_name'],
|
||||
'id' => $supplier_id));
|
||||
}
|
||||
}
|
||||
else//failure
|
||||
{
|
||||
$supplier_data = $this->xss_clean($supplier_data);
|
||||
|
||||
echo json_encode(array('success' => FALSE,
|
||||
'message' => $this->lang->line('suppliers_error_adding_updating') . ' ' . $supplier_data['company_name'],
|
||||
'id' => -1));
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
This deletes suppliers from the suppliers table
|
||||
*/
|
||||
public function delete()
|
||||
{
|
||||
$suppliers_to_delete = $this->xss_clean($this->input->post('ids'));
|
||||
|
||||
if($this->Supplier->delete_list($suppliers_to_delete))
|
||||
{
|
||||
echo json_encode(array('success' => TRUE,'message' => $this->lang->line('suppliers_successful_deleted').' '.
|
||||
count($suppliers_to_delete).' '.$this->lang->line('suppliers_one_or_multiple')));
|
||||
}
|
||||
else
|
||||
{
|
||||
echo json_encode(array('success' => FALSE,'message' => $this->lang->line('suppliers_cannot_be_deleted')));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
?>
|
||||
220
application/controllers/Taxes.php
Normal file
220
application/controllers/Taxes.php
Normal file
@@ -0,0 +1,220 @@
|
||||
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
|
||||
|
||||
require_once("Secure_Controller.php");
|
||||
|
||||
class Taxes extends Secure_Controller
|
||||
{
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct('taxes');
|
||||
|
||||
$this->load->model('enums/Rounding_mode');
|
||||
|
||||
}
|
||||
|
||||
public function index()
|
||||
{
|
||||
$data['table_headers'] = $this->xss_clean(get_taxes_manage_table_headers());
|
||||
|
||||
$this->load->view('taxes/manage', $data);
|
||||
}
|
||||
|
||||
/*
|
||||
Returns tax_codes table data rows. This will be called with AJAX.
|
||||
*/
|
||||
public function search()
|
||||
{
|
||||
$search = $this->input->get('search');
|
||||
$limit = $this->input->get('limit');
|
||||
$offset = $this->input->get('offset');
|
||||
$sort = $this->input->get('sort');
|
||||
$order = $this->input->get('order');
|
||||
|
||||
$tax_codes = $this->Tax->search($search, $limit, $offset, $sort, $order);
|
||||
|
||||
$total_rows = $this->Tax->get_found_rows($search);
|
||||
|
||||
$data_rows = array();
|
||||
foreach($tax_codes->result() as $tax_code_row)
|
||||
{
|
||||
$data_rows[] = $this->xss_clean(get_tax_data_row($tax_code_row));
|
||||
}
|
||||
|
||||
echo json_encode(array('total' => $total_rows, 'rows' => $data_rows));
|
||||
}
|
||||
|
||||
/*
|
||||
Gives search suggestions based on what is being searched for
|
||||
*/
|
||||
public function suggest_search()
|
||||
{
|
||||
$suggestions = $this->xss_clean($this->Tax->get_search_suggestions($this->input->post('term')));
|
||||
|
||||
echo json_encode($suggestions);
|
||||
}
|
||||
|
||||
/*
|
||||
Provides list of tax categories to select from
|
||||
*/
|
||||
public function suggest_tax_categories()
|
||||
{
|
||||
$suggestions = $this->xss_clean($this->Tax->get_tax_category_suggestions($this->input->post('term')));
|
||||
|
||||
echo json_encode($suggestions);
|
||||
}
|
||||
|
||||
|
||||
public function get_row($row_id)
|
||||
{
|
||||
$data_row = $this->xss_clean(get_tax_codes_data_row($this->Tax->get_info($row_id), $this));
|
||||
|
||||
echo json_encode($data_row);
|
||||
}
|
||||
|
||||
public function view($tax_code = -1)
|
||||
{
|
||||
$tax_code_info = $this->Tax->get_info($tax_code);
|
||||
|
||||
$default_tax_category_id = 1; // Tax category id is always the default tax category
|
||||
$default_tax_category = $this->Tax->get_tax_category($default_tax_category_id);
|
||||
|
||||
$tax_rate_info = $this->Tax->get_rate_info($tax_code, $default_tax_category_id);
|
||||
|
||||
$data['rounding_options'] = Rounding_mode::get_rounding_options();
|
||||
$data['html_rounding_options'] = $this->get_html_rounding_options();
|
||||
|
||||
if($tax_code == -1)
|
||||
{
|
||||
$data['tax_code'] = '';
|
||||
$data['tax_code_name'] = '';
|
||||
$data['tax_code_type'] = '0';
|
||||
$data['city'] = '';
|
||||
$data['state'] = '';
|
||||
$data['tax_rate'] = '0.0000';
|
||||
$data['rate_tax_code'] = '';
|
||||
$data['rate_tax_category_id'] = 1;
|
||||
$data['tax_category'] = '';
|
||||
$data['add_tax_category'] = '';
|
||||
$data['rounding_code'] = '0';
|
||||
}
|
||||
else
|
||||
{
|
||||
$data['tax_code'] = $tax_code;
|
||||
$data['tax_code_name'] = $tax_code_info->tax_code_name;
|
||||
$data['tax_code_type'] = $tax_code_info->tax_code_type;
|
||||
$data['city'] = $tax_code_info->city;
|
||||
$data['state'] = $tax_code_info->state;
|
||||
$data['rate_tax_code'] = $tax_code_info->rate_tax_code;
|
||||
$data['rate_tax_category_id'] = $tax_code_info->rate_tax_category_id;
|
||||
$data['tax_category'] = $tax_code_info->tax_category;
|
||||
$data['add_tax_category'] = '';
|
||||
$data['tax_rate'] = $tax_rate_info->tax_rate;
|
||||
$data['rounding_code'] = $tax_rate_info->rounding_code;
|
||||
}
|
||||
|
||||
$data = $this->xss_clean($data);
|
||||
|
||||
$tax_code_rates = array();
|
||||
foreach($this->Tax->get_tax_code_rate_exceptions($tax_code) as $tax_code_rate)
|
||||
{
|
||||
$tax_code_row = array();
|
||||
$tax_code_row['rate_tax_category_id'] = $this->xss_clean($tax_code_rate['rate_tax_category_id']);
|
||||
$tax_code_row['tax_category'] = $this->xss_clean($tax_code_rate['tax_category']);
|
||||
$tax_code_row['tax_rate'] = $this->xss_clean($tax_code_rate['tax_rate']);
|
||||
$tax_code_row['rounding_code'] = $this->xss_clean($tax_code_rate['rounding_code']);
|
||||
|
||||
$tax_code_rates[] = $tax_code_row;
|
||||
}
|
||||
|
||||
$data['tax_code_rates'] = $tax_code_rates;
|
||||
|
||||
$this->load->view("taxes/form", $data);
|
||||
}
|
||||
|
||||
public static function get_html_rounding_options()
|
||||
{
|
||||
return Rounding_mode::get_html_rounding_options();
|
||||
}
|
||||
|
||||
public function save($tax_code = -1)
|
||||
{
|
||||
$entered_tax_code = $this->xss_clean($this->input->post('tax_code'));
|
||||
$tax_code_data = array(
|
||||
'tax_code' => strtoupper($this->input->post('tax_code')),
|
||||
'tax_code_name' => $this->input->post('tax_code_name'),
|
||||
'tax_code_type' => $this->input->post('tax_code_type'),
|
||||
'city' => $this->input->post('city'),
|
||||
'state' => $this->input->post('state'));
|
||||
|
||||
$tax_rate_data = array(
|
||||
'rate_tax_code' => $this->input->post('tax_code'),
|
||||
'rate_tax_category_id' => 1,
|
||||
'tax_rate' => parse_decimals($this->input->post('tax_rate')),
|
||||
'rounding_code' => $this->input->post('rounding_code')
|
||||
);
|
||||
|
||||
if($this->Tax->save($tax_code_data, $tax_rate_data, $tax_code))
|
||||
{
|
||||
$tax_code_rate_exceptions = array();
|
||||
if(!empty($this->input->post('exception_tax_rate')))
|
||||
{
|
||||
foreach($this->input->post('exception_tax_rate') as $tax_category_id => $exception_tax_rate)
|
||||
{
|
||||
$exception_rounding_code = $this->input->post('exception_rounding_code[' . $tax_category_id . ']');
|
||||
$tax_code_rate_exceptions[] = array(
|
||||
'rate_tax_code' => $entered_tax_code,
|
||||
'rate_tax_category_id' => $tax_category_id,
|
||||
'tax_rate' => $exception_tax_rate,
|
||||
'rounding_code' => $exception_rounding_code
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
if(!empty($tax_code_rate_exceptions))
|
||||
{
|
||||
$success = $this->Tax->save_tax_rate_exceptions($tax_code_rate_exceptions, $entered_tax_code);
|
||||
}
|
||||
|
||||
$tax_code_data = $this->xss_clean($tax_code_data);
|
||||
|
||||
//New tax_code record
|
||||
if($tax_code == -1)
|
||||
{
|
||||
echo json_encode(array('success' => TRUE, 'message' => $this->lang->line('taxes_tax_code_successfully_added') . ' ' . $entered_tax_code));
|
||||
}
|
||||
else //Existing tax_code
|
||||
{
|
||||
echo json_encode(array('success' => TRUE, 'message' => $this->lang->line('taxes_tax_code_successful_updated') . ' ' . $entered_tax_code));
|
||||
}
|
||||
}
|
||||
else //failure
|
||||
{
|
||||
$tax_code_data = $this->xss_clean($tax_code_data);
|
||||
|
||||
echo json_encode(array('success' => FALSE, 'message' => $this->lang->line('taxes_tax_code_error_adding_updating') . ' ' .
|
||||
$entered_tax_code));
|
||||
}
|
||||
}
|
||||
|
||||
public function delete()
|
||||
{
|
||||
$tax_codes_to_delete = $this->xss_clean($this->input->post('ids'));
|
||||
|
||||
if($this->Tax->delete_list($tax_codes_to_delete))
|
||||
{
|
||||
echo json_encode(array('success' => TRUE, 'message' => $this->lang->line('taxes_tax_code_successful_deleted')));
|
||||
} else
|
||||
{
|
||||
echo json_encode(array('success' => FALSE, 'message' => $this->lang->line('taxes_tax_code_cannot_be_deleted')));
|
||||
}
|
||||
}
|
||||
|
||||
public function suggest_sales_tax_codes()
|
||||
{
|
||||
$suggestions = $this->xss_clean($this->Tax->get_sales_tax_codes_search_suggestions($this->input->post_get('term')));
|
||||
|
||||
echo json_encode($suggestions);
|
||||
}
|
||||
|
||||
}
|
||||
?>
|
||||
@@ -1,16 +0,0 @@
|
||||
<?php
|
||||
require_once ("secure_area.php");
|
||||
class Barcode extends Secure_area
|
||||
{
|
||||
function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
}
|
||||
|
||||
function index()
|
||||
{
|
||||
$this->load->view('barcode');
|
||||
}
|
||||
|
||||
}
|
||||
?>
|
||||
@@ -1,220 +0,0 @@
|
||||
<?php
|
||||
require_once ("secure_area.php");
|
||||
class Config extends Secure_area
|
||||
{
|
||||
function __construct()
|
||||
{
|
||||
parent::__construct('config');
|
||||
$this->load->library('barcode_lib');
|
||||
}
|
||||
|
||||
function index()
|
||||
{
|
||||
$location_names = array();
|
||||
$data['stock_locations'] = $this->Stock_location->get_all()->result_array();
|
||||
$data['support_barcode'] = $this->barcode_lib->get_list_barcodes();
|
||||
$this->load->view("configs/manage", $data);
|
||||
$this->_remove_duplicate_cookies();
|
||||
}
|
||||
|
||||
function save()
|
||||
{
|
||||
$upload_success = $this->_handle_logo_upload();
|
||||
$upload_data = $this->upload->data();
|
||||
|
||||
$batch_save_data=array(
|
||||
'company'=>$this->input->post('company'),
|
||||
'address'=>$this->input->post('address'),
|
||||
'phone'=>$this->input->post('phone'),
|
||||
'email'=>$this->input->post('email'),
|
||||
'fax'=>$this->input->post('fax'),
|
||||
'website'=>$this->input->post('website'),
|
||||
'default_tax_1_rate'=>$this->input->post('default_tax_1_rate'),
|
||||
'default_tax_1_name'=>$this->input->post('default_tax_1_name'),
|
||||
'default_tax_2_rate'=>$this->input->post('default_tax_2_rate'),
|
||||
'default_tax_2_name'=>$this->input->post('default_tax_2_name'),
|
||||
'return_policy'=>$this->input->post('return_policy'),
|
||||
'tax_included'=>$this->input->post('tax_included'),
|
||||
'recv_invoice_format'=>$this->input->post('recv_invoice_format'),
|
||||
'sales_invoice_format'=>$this->input->post('sales_invoice_format'),
|
||||
'receiving_calculate_average_price'=>$this->input->post('receiving_calculate_average_price'),
|
||||
'lines_per_page'=>$this->input->post('lines_per_page'),
|
||||
'default_sales_discount'=>$this->input->post('default_sales_discount'),
|
||||
'custom1_name'=>$this->input->post('custom1_name'),
|
||||
'custom2_name'=>$this->input->post('custom2_name'),
|
||||
'custom3_name'=>$this->input->post('custom3_name'),
|
||||
'custom4_name'=>$this->input->post('custom4_name'),
|
||||
'custom5_name'=>$this->input->post('custom5_name'),
|
||||
'custom6_name'=>$this->input->post('custom6_name'),
|
||||
'custom7_name'=>$this->input->post('custom7_name'),
|
||||
'custom8_name'=>$this->input->post('custom8_name'),
|
||||
'custom9_name'=>$this->input->post('custom9_name'),
|
||||
'custom10_name'=>$this->input->post('custom10_name')
|
||||
);
|
||||
|
||||
if (!empty($upload_data['orig_name']))
|
||||
{
|
||||
$batch_save_data['company_logo'] = $upload_data['raw_name'] . $upload_data['file_ext'];
|
||||
}
|
||||
|
||||
$result = $this->Appconfig->batch_save( $batch_save_data );
|
||||
$success = $upload_success && $result ? true : false;
|
||||
$message = $this->lang->line('config_saved_' . ($success ? '' : 'un') . 'successfully');
|
||||
$message = $upload_success ? $message : $this->upload->display_errors();
|
||||
echo json_encode(array('success'=>$success,'message'=>$message));
|
||||
$this->_remove_duplicate_cookies();
|
||||
}
|
||||
|
||||
function save_locale()
|
||||
{
|
||||
$batch_save_data=array(
|
||||
'currency_symbol'=>$this->input->post('currency_symbol'),
|
||||
'currency_side'=>$this->input->post('currency_side'),
|
||||
'language'=>$this->input->post('language'),
|
||||
'timezone'=>$this->input->post('timezone'),
|
||||
'dateformat'=>$this->input->post('dateformat'),
|
||||
'timeformat'=>$this->input->post('timeformat'),
|
||||
'thousands_separator'=>$this->input->post('thousands_separator'),
|
||||
'decimal_point'=>$this->input->post('decimal_point')
|
||||
);
|
||||
|
||||
$result = $this->Appconfig->batch_save( $batch_save_data );
|
||||
$success = $result ? true : false;
|
||||
echo json_encode(array('success'=>$success, 'message'=>$this->lang->line('config_saved_' . ($success ? '' : 'un') . 'successfully')));
|
||||
$this->_remove_duplicate_cookies();
|
||||
}
|
||||
|
||||
function stock_locations()
|
||||
{
|
||||
$stock_locations = $this->Stock_location->get_all()->result_array();
|
||||
$this->load->view('partial/stock_locations', array('stock_locations' => $stock_locations));
|
||||
}
|
||||
|
||||
function _clear_session_state()
|
||||
{
|
||||
$this->load->library('sale_lib');
|
||||
$this->sale_lib->clear_sale_location();
|
||||
$this->sale_lib->clear_all();
|
||||
$this->load->library('receiving_lib');
|
||||
$this->receiving_lib->clear_stock_source();
|
||||
$this->receiving_lib->clear_stock_destination();
|
||||
$this->receiving_lib->clear_all();
|
||||
}
|
||||
|
||||
function save_locations()
|
||||
{
|
||||
$this->db->trans_start();
|
||||
|
||||
$deleted_locations = $this->Stock_location->get_allowed_locations();
|
||||
foreach($this->input->post() as $key => $value)
|
||||
{
|
||||
if (strstr($key, 'stock_location'))
|
||||
{
|
||||
$location_id = preg_replace("/.*?_(\d+)$/", "$1", $key);
|
||||
unset($deleted_locations[$location_id]);
|
||||
// save or update
|
||||
$location_data = array('location_name' => $value);
|
||||
if ($this->Stock_location->save($location_data, $location_id))
|
||||
{
|
||||
$this->_clear_session_state();
|
||||
}
|
||||
}
|
||||
}
|
||||
// all locations not available in post will be deleted now
|
||||
foreach ($deleted_locations as $location_id => $location_name)
|
||||
{
|
||||
$this->Stock_location->delete($location_id);
|
||||
}
|
||||
$success = $this->db->trans_complete();
|
||||
echo json_encode(array('success'=>$success,'message'=>$this->lang->line('config_saved_' . ($success ? '' : 'un') . 'successfully')));
|
||||
$this->_remove_duplicate_cookies();
|
||||
}
|
||||
|
||||
function save_barcode()
|
||||
{
|
||||
$batch_save_data=array(
|
||||
'barcode_type'=>$this->input->post('barcode_type'),
|
||||
'barcode_quality'=>$this->input->post('barcode_quality'),
|
||||
'barcode_width'=>$this->input->post('barcode_width'),
|
||||
'barcode_height'=>$this->input->post('barcode_height'),
|
||||
'barcode_font'=>$this->input->post('barcode_font'),
|
||||
'barcode_font_size'=>$this->input->post('barcode_font_size'),
|
||||
'barcode_first_row'=>$this->input->post('barcode_first_row'),
|
||||
'barcode_second_row'=>$this->input->post('barcode_second_row'),
|
||||
'barcode_third_row'=>$this->input->post('barcode_third_row'),
|
||||
'barcode_num_in_row'=>$this->input->post('barcode_num_in_row'),
|
||||
'barcode_page_width'=>$this->input->post('barcode_page_width'),
|
||||
'barcode_page_cellspacing'=>$this->input->post('barcode_page_cellspacing'),
|
||||
'barcode_generate_if_empty'=>$this->input->post('barcode_generate_if_empty'),
|
||||
'barcode_content'=>$this->input->post('barcode_content')
|
||||
);
|
||||
|
||||
$result = $this->Appconfig->batch_save( $batch_save_data );
|
||||
$success = $result ? true : false;
|
||||
echo json_encode(array('success'=>$success, 'message'=>$this->lang->line('config_saved_' . ($success ? '' : 'un') . 'successfully')));
|
||||
}
|
||||
|
||||
function save_receipt()
|
||||
{
|
||||
$batch_save_data = array (
|
||||
'use_invoice_template' => $this->input->post ( 'use_invoice_template' ),
|
||||
'invoice_default_comments' => $this->input->post ( 'invoice_default_comments' ),
|
||||
'invoice_email_message' => $this->input->post ( 'invoice_email_message' ),
|
||||
'receipt_show_taxes' => $this->input->post ( 'receipt_show_taxes' ),
|
||||
'print_silently' => $this->input->post ( 'print_silently' ),
|
||||
'print_header' => $this->input->post ( 'print_header' ),
|
||||
'print_footer' => $this->input->post ( 'print_footer' ),
|
||||
'print_top_margin' => $this->input->post ( 'print_top_margin' ),
|
||||
'print_left_margin' => $this->input->post ( 'print_left_margin' ),
|
||||
'print_bottom_margin' => $this->input->post ( 'print_bottom_margin' ),
|
||||
'print_right_margin' => $this->input->post ( 'print_right_margin' ),
|
||||
'show_total_discount' => $this->input->post( 'show_total_discount' )
|
||||
);
|
||||
$result = $this->Appconfig->batch_save( $batch_save_data );
|
||||
$success = $result ? true : false;
|
||||
echo json_encode(array('success'=>$success, 'message'=>$this->lang->line('config_saved_' . ($success ? '' : 'un') . 'successfully')));
|
||||
}
|
||||
|
||||
function _handle_logo_upload()
|
||||
{
|
||||
$this->load->helper('directory');
|
||||
// load upload library
|
||||
$config = array('upload_path' => './uploads/',
|
||||
'allowed_types' => 'gif|jpg|png',
|
||||
'max_size' => '1024',
|
||||
'max_width' => '800',
|
||||
'max_height' => '680',
|
||||
'file_name' => 'company_logo');
|
||||
$this->load->library('upload', $config);
|
||||
$this->upload->do_upload('company_logo');
|
||||
return strlen($this->upload->display_errors()) == 0 || !strcmp($this->upload->display_errors(), '<p>'.$this->lang->line('upload_no_file_selected').'</p>');
|
||||
}
|
||||
|
||||
function backup_db()
|
||||
{
|
||||
$employee_id=$this->Employee->get_logged_in_employee_info()->person_id;
|
||||
if($this->Employee->has_module_grant('config',$employee_id))
|
||||
{
|
||||
$this->load->dbutil();
|
||||
$prefs = array(
|
||||
'format' => 'zip',
|
||||
'filename' => 'ospos.sql'
|
||||
);
|
||||
|
||||
$backup =& $this->dbutil->backup($prefs);
|
||||
|
||||
$file_name = 'ospos-' . date("Y-m-d-H-i-s") .'.zip';
|
||||
$save = 'uploads/'.$file_name;
|
||||
$this->load->helper('download');
|
||||
while (ob_get_level()) {
|
||||
ob_end_clean();
|
||||
}
|
||||
force_download($file_name, $backup);
|
||||
}
|
||||
else
|
||||
{
|
||||
redirect('no_access/config');
|
||||
}
|
||||
}
|
||||
}
|
||||
?>
|
||||
@@ -1,219 +0,0 @@
|
||||
<?php
|
||||
require_once ("person_controller.php");
|
||||
class Customers extends Person_controller
|
||||
{
|
||||
function __construct()
|
||||
{
|
||||
parent::__construct('customers');
|
||||
}
|
||||
|
||||
function index($limit_from=0)
|
||||
{
|
||||
$data['controller_name']=$this->get_controller_name();
|
||||
$data['form_width']=$this->get_form_width();
|
||||
$lines_per_page = $this->Appconfig->get('lines_per_page');
|
||||
$customers = $this->Customer->get_all($lines_per_page,$limit_from);
|
||||
$data['links'] = $this->_initialize_pagination($this->Customer,$lines_per_page,$limit_from);
|
||||
$data['manage_table']=get_people_manage_table($customers,$this);
|
||||
$this->load->view('people/manage',$data);
|
||||
}
|
||||
|
||||
/*
|
||||
Returns customer table data rows. This will be called with AJAX.
|
||||
*/
|
||||
function search()
|
||||
{
|
||||
$search = $this->input->post('search');
|
||||
$limit_from = $this->input->post('limit_from');
|
||||
$lines_per_page = $this->Appconfig->get('lines_per_page');
|
||||
$customers = $this->Customer->search($search, $lines_per_page, $limit_from);
|
||||
$total_rows = $this->Customer->get_found_rows($search);
|
||||
$links = $this->_initialize_pagination($this->Customer,$lines_per_page, $limit_from, $total_rows);
|
||||
$data_rows=get_people_manage_table_data_rows($customers,$this);
|
||||
echo json_encode(array('total_rows' => $total_rows, 'rows' => $data_rows, 'pagination' => $links));
|
||||
}
|
||||
|
||||
/*
|
||||
Gives search suggestions based on what is being searched for
|
||||
*/
|
||||
function suggest()
|
||||
{
|
||||
$suggestions = $this->Customer->get_search_suggestions($this->input->post('q'),$this->input->post('limit'));
|
||||
echo implode("\n",$suggestions);
|
||||
}
|
||||
|
||||
/*
|
||||
Loads the customer edit form
|
||||
*/
|
||||
function view($customer_id=-1)
|
||||
{
|
||||
$data['person_info']=$this->Customer->get_info($customer_id);
|
||||
$this->load->view("customers/form",$data);
|
||||
}
|
||||
|
||||
/*
|
||||
Inserts/updates a customer
|
||||
*/
|
||||
function save($customer_id=-1)
|
||||
{
|
||||
$person_data = array(
|
||||
'first_name'=>$this->input->post('first_name'),
|
||||
'last_name'=>$this->input->post('last_name'),
|
||||
'gender'=>$this->input->post('gender'),
|
||||
'email'=>$this->input->post('email'),
|
||||
'phone_number'=>$this->input->post('phone_number'),
|
||||
'address_1'=>$this->input->post('address_1'),
|
||||
'address_2'=>$this->input->post('address_2'),
|
||||
'city'=>$this->input->post('city'),
|
||||
'state'=>$this->input->post('state'),
|
||||
'zip'=>$this->input->post('zip'),
|
||||
'country'=>$this->input->post('country'),
|
||||
'comments'=>$this->input->post('comments')
|
||||
);
|
||||
$customer_data=array(
|
||||
'account_number'=>$this->input->post('account_number')=='' ? null:$this->input->post('account_number'),
|
||||
'company_name'=>$this->input->post('company_name')=='' ? null:$this->input->post('company_name'),
|
||||
'taxable'=>$this->input->post('taxable')=='' ? 0:1,
|
||||
);
|
||||
if($this->Customer->save($person_data,$customer_data,$customer_id))
|
||||
{
|
||||
//New customer
|
||||
if($customer_id==-1)
|
||||
{
|
||||
echo json_encode(array('success'=>true,'message'=>$this->lang->line('customers_successful_adding').' '.
|
||||
$person_data['first_name'].' '.$person_data['last_name'],'person_id'=>$customer_data['person_id']));
|
||||
}
|
||||
else //previous customer
|
||||
{
|
||||
echo json_encode(array('success'=>true,'message'=>$this->lang->line('customers_successful_updating').' '.
|
||||
$person_data['first_name'].' '.$person_data['last_name'],'person_id'=>$customer_id));
|
||||
}
|
||||
}
|
||||
else//failure
|
||||
{
|
||||
echo json_encode(array('success'=>false,'message'=>$this->lang->line('customers_error_adding_updating').' '.
|
||||
$person_data['first_name'].' '.$person_data['last_name'],'person_id'=>-1));
|
||||
}
|
||||
}
|
||||
|
||||
function check_account_number()
|
||||
{
|
||||
$exists = $this->Customer->account_number_exists($this->input->post('account_number'),$this->input->post('person_id'));
|
||||
echo json_encode(array('success'=>!$exists,'message'=>$this->lang->line('customers_account_number_duplicate')));
|
||||
}
|
||||
|
||||
/*
|
||||
This deletes customers from the customers table
|
||||
*/
|
||||
function delete()
|
||||
{
|
||||
$customers_to_delete=$this->input->post('ids');
|
||||
|
||||
if($this->Customer->delete_list($customers_to_delete))
|
||||
{
|
||||
echo json_encode(array('success'=>true,'message'=>$this->lang->line('customers_successful_deleted').' '.
|
||||
count($customers_to_delete).' '.$this->lang->line('customers_one_or_multiple')));
|
||||
}
|
||||
else
|
||||
{
|
||||
echo json_encode(array('success'=>false,'message'=>$this->lang->line('customers_cannot_be_deleted')));
|
||||
}
|
||||
}
|
||||
|
||||
function excel()
|
||||
{
|
||||
$data = file_get_contents("import_customers.csv");
|
||||
$name = 'import_customers.csv';
|
||||
force_download($name, $data);
|
||||
}
|
||||
|
||||
function excel_import()
|
||||
{
|
||||
$this->load->view("customers/excel_import", null);
|
||||
}
|
||||
|
||||
function do_excel_import()
|
||||
{
|
||||
$msg = 'do_excel_import';
|
||||
$failCodes = array();
|
||||
if ($_FILES['file_path']['error']!=UPLOAD_ERR_OK)
|
||||
{
|
||||
$msg = $this->lang->line('items_excel_import_failed');
|
||||
echo json_encode( array('success'=>false,'message'=>$msg) );
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (($handle = fopen($_FILES['file_path']['tmp_name'], "r")) !== FALSE)
|
||||
{
|
||||
//Skip first row
|
||||
fgetcsv($handle);
|
||||
|
||||
$i=1;
|
||||
while (($data = fgetcsv($handle)) !== FALSE)
|
||||
{
|
||||
$person_data = array(
|
||||
'first_name'=>$data[0],
|
||||
'last_name'=>$data[1],
|
||||
'gender'=>$data[2],
|
||||
'email'=>$data[3],
|
||||
'phone_number'=>$data[4],
|
||||
'address_1'=>$data[5],
|
||||
'address_2'=>$data[6],
|
||||
'city'=>$data[7],
|
||||
'state'=>$data[8],
|
||||
'zip'=>$data[9],
|
||||
'country'=>$data[10],
|
||||
'comments'=>$data[11]
|
||||
);
|
||||
|
||||
$customer_data=array(
|
||||
'taxable'=>$data[13]=='' ? 0:1
|
||||
);
|
||||
|
||||
$account_number = $data[12];
|
||||
$invalidated = false;
|
||||
if ($account_number != "")
|
||||
{
|
||||
$customer_data['account_number'] = $account_number;
|
||||
$invalidated = $this->Customer->account_number_exists($account_number);
|
||||
}
|
||||
|
||||
if($invalidated || !$this->Customer->save($person_data,$customer_data))
|
||||
{
|
||||
$failCodes[] = $i;
|
||||
}
|
||||
|
||||
$i++;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
echo json_encode( array('success'=>false,'message'=>'Your upload file has no data or not in supported format.') );
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
$success = true;
|
||||
if(count($failCodes) > 0)
|
||||
{
|
||||
$msg = "Most customers imported. But some were not, here is list of their CODE (" .count($failCodes) ."): ".implode(", ", $failCodes);
|
||||
$success = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
$msg = "Import Customers successful";
|
||||
}
|
||||
|
||||
echo json_encode( array('success'=>$success,'message'=>$msg) );
|
||||
}
|
||||
|
||||
/*
|
||||
get the width for the add/edit form
|
||||
*/
|
||||
function get_form_width()
|
||||
{
|
||||
return 400;
|
||||
}
|
||||
}
|
||||
?>
|
||||
@@ -1,136 +0,0 @@
|
||||
<?php
|
||||
require_once ("person_controller.php");
|
||||
class Employees extends Person_controller
|
||||
{
|
||||
function __construct()
|
||||
{
|
||||
parent::__construct('employees');
|
||||
}
|
||||
|
||||
function index($limit_from=0)
|
||||
{
|
||||
$data['controller_name']=$this->get_controller_name();
|
||||
$data['form_width']=$this->get_form_width();
|
||||
$lines_per_page = $this->Appconfig->get('lines_per_page');
|
||||
$suppliers = $this->Employee->get_all($lines_per_page,$limit_from);
|
||||
$data['links'] = $this->_initialize_pagination($this->Employee,$lines_per_page,$limit_from);
|
||||
$data['manage_table']=get_people_manage_table($suppliers,$this);
|
||||
$this->load->view('suppliers/manage',$data);
|
||||
}
|
||||
|
||||
/*
|
||||
Returns employee table data rows. This will be called with AJAX.
|
||||
*/
|
||||
function search()
|
||||
{
|
||||
$search = $this->input->post('search');
|
||||
$limit_from = $this->input->post('limit_from');
|
||||
$lines_per_page = $this->Appconfig->get('lines_per_page');
|
||||
$employees = $this->Employee->search($search, $limit_from, $lines_per_page);
|
||||
$total_rows = $this->Employee->get_found_rows($search);
|
||||
$links = $this->_initialize_pagination($this->Employee, $lines_per_page, $limit_from, $total_rows);
|
||||
$data_rows=get_people_manage_table_data_rows($employees,$this);
|
||||
echo json_encode(array('rows' => $data_rows, 'pagination' => $links));
|
||||
}
|
||||
|
||||
/*
|
||||
Gives search suggestions based on what is being searched for
|
||||
*/
|
||||
function suggest()
|
||||
{
|
||||
$suggestions = $this->Employee->get_search_suggestions($this->input->post('q'),$this->input->post('limit'));
|
||||
echo implode("\n",$suggestions);
|
||||
}
|
||||
|
||||
/*
|
||||
Loads the employee edit form
|
||||
*/
|
||||
function view($employee_id=-1)
|
||||
{
|
||||
$data['person_info']=$this->Employee->get_info($employee_id);
|
||||
$data['all_modules']=$this->Module->get_all_modules();
|
||||
$data['all_subpermissions']=$this->Module->get_all_subpermissions();
|
||||
$this->load->view("employees/form",$data);
|
||||
}
|
||||
|
||||
/*
|
||||
Inserts/updates an employee
|
||||
*/
|
||||
function save($employee_id=-1)
|
||||
{
|
||||
$person_data = array(
|
||||
'first_name'=>$this->input->post('first_name'),
|
||||
'last_name'=>$this->input->post('last_name'),
|
||||
'gender'=>$this->input->post('gender'),
|
||||
'email'=>$this->input->post('email'),
|
||||
'phone_number'=>$this->input->post('phone_number'),
|
||||
'address_1'=>$this->input->post('address_1'),
|
||||
'address_2'=>$this->input->post('address_2'),
|
||||
'city'=>$this->input->post('city'),
|
||||
'state'=>$this->input->post('state'),
|
||||
'zip'=>$this->input->post('zip'),
|
||||
'country'=>$this->input->post('country'),
|
||||
'comments'=>$this->input->post('comments')
|
||||
);
|
||||
$grants_data = $this->input->post("grants")!=FALSE ? $this->input->post("grants"):array();
|
||||
|
||||
//Password has been changed OR first time password set
|
||||
if($this->input->post('password')!='')
|
||||
{
|
||||
$employee_data=array(
|
||||
'username'=>$this->input->post('username'),
|
||||
'password'=>md5($this->input->post('password'))
|
||||
);
|
||||
}
|
||||
else //Password not changed
|
||||
{
|
||||
$employee_data=array('username'=>$this->input->post('username'));
|
||||
}
|
||||
|
||||
if($this->Employee->save($person_data,$employee_data,$grants_data,$employee_id))
|
||||
{
|
||||
//New employee
|
||||
if($employee_id==-1)
|
||||
{
|
||||
echo json_encode(array('success'=>true,'message'=>$this->lang->line('employees_successful_adding').' '.
|
||||
$person_data['first_name'].' '.$person_data['last_name'],'person_id'=>$employee_data['person_id']));
|
||||
}
|
||||
else //previous employee
|
||||
{
|
||||
echo json_encode(array('success'=>true,'message'=>$this->lang->line('employees_successful_updating').' '.
|
||||
$person_data['first_name'].' '.$person_data['last_name'],'person_id'=>$employee_id));
|
||||
}
|
||||
}
|
||||
else//failure
|
||||
{
|
||||
echo json_encode(array('success'=>false,'message'=>$this->lang->line('employees_error_adding_updating').' '.
|
||||
$person_data['first_name'].' '.$person_data['last_name'],'person_id'=>-1));
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
This deletes employees from the employees table
|
||||
*/
|
||||
function delete()
|
||||
{
|
||||
$employees_to_delete=$this->input->post('ids');
|
||||
|
||||
if($this->Employee->delete_list($employees_to_delete))
|
||||
{
|
||||
echo json_encode(array('success'=>true,'message'=>$this->lang->line('employees_successful_deleted').' '.
|
||||
count($employees_to_delete).' '.$this->lang->line('employees_one_or_multiple')));
|
||||
}
|
||||
else
|
||||
{
|
||||
echo json_encode(array('success'=>false,'message'=>$this->lang->line('employees_cannot_be_deleted')));
|
||||
}
|
||||
}
|
||||
/*
|
||||
get the width for the add/edit form
|
||||
*/
|
||||
function get_form_width()
|
||||
{
|
||||
return 750;
|
||||
}
|
||||
}
|
||||
?>
|
||||
@@ -1,124 +0,0 @@
|
||||
<?php
|
||||
require_once ("secure_area.php");
|
||||
require_once ("interfaces/idata_controller.php");
|
||||
|
||||
class Giftcards extends Secure_area implements iData_controller
|
||||
{
|
||||
function __construct()
|
||||
{
|
||||
parent::__construct('giftcards');
|
||||
}
|
||||
|
||||
function index($limit_from=0)
|
||||
{
|
||||
$data['controller_name'] = $this->get_controller_name();
|
||||
$data['form_width'] = $this->get_form_width();
|
||||
$lines_per_page = $this->Appconfig->get('lines_per_page');
|
||||
$giftcards = $this->Giftcard->get_all($lines_per_page, $limit_from);
|
||||
$data['links'] = $this->_initialize_pagination($this->Giftcard, $lines_per_page, $limit_from);
|
||||
$data['manage_table'] = get_giftcards_manage_table($giftcards, $this);
|
||||
$this->load->view('giftcards/manage', $data);
|
||||
}
|
||||
|
||||
function search()
|
||||
{
|
||||
$search = $this->input->post('search');
|
||||
$limit_from = $this->input->post('limit_from');
|
||||
$lines_per_page = $this->Appconfig->get('lines_per_page');
|
||||
$giftcards = $this->Giftcard->search($search, $lines_per_page, $limit_from);
|
||||
$total_rows = $this->Giftcard->get_found_rows($search);
|
||||
$links = $this->_initialize_pagination($this->Giftcard, $lines_per_page, $limit_from, $total_rows);
|
||||
$data_rows = get_giftcards_manage_table_data_rows($giftcards, $this);
|
||||
echo json_encode(array('total_rows' => $total_rows, 'rows' => $data_rows, 'pagination' => $links));
|
||||
}
|
||||
|
||||
/*
|
||||
Gives search suggestions based on what is being searched for
|
||||
*/
|
||||
function suggest()
|
||||
{
|
||||
$suggestions = $this->Giftcard->get_search_suggestions($this->input->post('q'), $this->input->post('limit'));
|
||||
echo implode("\n",$suggestions);
|
||||
}
|
||||
|
||||
/*
|
||||
Gives search suggestions for person_id based on what is being searched for
|
||||
*/
|
||||
function person_search()
|
||||
{
|
||||
$suggestions = $this->Customer->get_customer_search_suggestions($this->input->post('q'), $this->input->post('limit'));
|
||||
echo implode("\n",$suggestions);
|
||||
}
|
||||
|
||||
function get_row()
|
||||
{
|
||||
$giftcard_id = $this->input->post('row_id');
|
||||
$data_row = get_giftcard_data_row($this->Giftcard->get_info($giftcard_id), $this);
|
||||
echo $data_row;
|
||||
}
|
||||
|
||||
function view($giftcard_id=-1)
|
||||
{
|
||||
$giftcard_info = $this->Giftcard->get_info($giftcard_id);
|
||||
$person_name=$giftcard_id > 0? $giftcard_info->first_name . ' ' . $giftcard_info->last_name : '';
|
||||
$data['selected_person'] = $giftcard_id > 0 && isset($giftcard_info->person_id) ? $giftcard_info->person_id . "|" . $person_name : "";
|
||||
$data['giftcard_number'] = $giftcard_id > 0 ? $giftcard_info->giftcard_number : $this->Giftcard->get_max_number()->giftcard_number + 1;
|
||||
$data['giftcard_info'] = $giftcard_info;
|
||||
$this->load->view("giftcards/form",$data);
|
||||
}
|
||||
|
||||
function save($giftcard_id=-1)
|
||||
{
|
||||
$giftcard_data = array(
|
||||
'record_time' => date('Y-m-d H:i:s'),
|
||||
'giftcard_number'=>$this->input->post('giftcard_number', TRUE),
|
||||
'value'=>$this->input->post('value', TRUE),
|
||||
'person_id'=>$this->input->post('person_id', TRUE) ? $this->input->post('person_id') : NULL
|
||||
);
|
||||
|
||||
if( $this->Giftcard->save( $giftcard_data, $giftcard_id ) )
|
||||
{
|
||||
//New giftcard
|
||||
if($giftcard_id==-1)
|
||||
{
|
||||
echo json_encode(array('success'=>true, 'message'=>$this->lang->line('giftcards_successful_adding').' '.
|
||||
$giftcard_data['giftcard_number'], 'giftcard_id'=>$giftcard_data['giftcard_id']));
|
||||
$giftcard_id = $giftcard_data['giftcard_id'];
|
||||
}
|
||||
else //previous giftcard
|
||||
{
|
||||
echo json_encode(array('success'=>true, 'message'=>$this->lang->line('giftcards_successful_updating').' '.
|
||||
$giftcard_data['giftcard_number'], 'giftcard_id'=>$giftcard_id));
|
||||
}
|
||||
}
|
||||
else//failure
|
||||
{
|
||||
echo json_encode(array('success'=>false,'message'=>$this->lang->line('giftcards_error_adding_updating').' '.
|
||||
$giftcard_data['giftcard_number'], 'giftcard_id'=>-1));
|
||||
}
|
||||
}
|
||||
|
||||
function delete()
|
||||
{
|
||||
$giftcards_to_delete=$this->input->post('ids');
|
||||
|
||||
if($this->Giftcard->delete_list($giftcards_to_delete))
|
||||
{
|
||||
echo json_encode(array('success'=>true, 'message'=>$this->lang->line('giftcards_successful_deleted').' '.
|
||||
count($giftcards_to_delete).' '.$this->lang->line('giftcards_one_or_multiple')));
|
||||
}
|
||||
else
|
||||
{
|
||||
echo json_encode(array('success'=>false, 'message'=>$this->lang->line('giftcards_cannot_be_deleted')));
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
get the width for the add/edit form
|
||||
*/
|
||||
function get_form_width()
|
||||
{
|
||||
return 360;
|
||||
}
|
||||
}
|
||||
?>
|
||||
@@ -1,21 +0,0 @@
|
||||
<?php
|
||||
require_once ("secure_area.php");
|
||||
|
||||
class Home extends Secure_area
|
||||
{
|
||||
function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
}
|
||||
|
||||
function index()
|
||||
{
|
||||
$this->load->view("home");
|
||||
}
|
||||
|
||||
function logout()
|
||||
{
|
||||
$this->Employee->logout();
|
||||
}
|
||||
}
|
||||
?>
|
||||
@@ -1,3 +1,4 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>403 Forbidden</title>
|
||||
@@ -7,4 +8,4 @@
|
||||
<p>Directory access is forbidden.</p>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
</html>
|
||||
|
||||
@@ -1,17 +0,0 @@
|
||||
<?php
|
||||
/*
|
||||
This interface is implemented by any controller that keeps track of data items, such
|
||||
as the customers, employees, and items controllers.
|
||||
*/
|
||||
interface iData_controller
|
||||
{
|
||||
public function index();
|
||||
public function search();
|
||||
public function suggest();
|
||||
public function get_row();
|
||||
public function view($data_item_id=-1);
|
||||
public function save($data_item_id=-1);
|
||||
public function delete();
|
||||
public function get_form_width();
|
||||
}
|
||||
?>
|
||||
@@ -1,11 +0,0 @@
|
||||
<?php
|
||||
/*
|
||||
This interface is implemented by any controller that keeps track of people, such
|
||||
as customers and employees.
|
||||
*/
|
||||
require_once("idata_controller.php");
|
||||
interface iPerson_controller extends iData_controller
|
||||
{
|
||||
public function mailto();
|
||||
}
|
||||
?>
|
||||
@@ -1,193 +0,0 @@
|
||||
<?php
|
||||
require_once ("secure_area.php");
|
||||
require_once ("interfaces/idata_controller.php");
|
||||
class Item_kits extends Secure_area implements iData_controller
|
||||
{
|
||||
function __construct()
|
||||
{
|
||||
parent::__construct('item_kits');
|
||||
}
|
||||
|
||||
// add the total cost and retail price to a passed items kit retrieving the data from each singolar item part of the kit
|
||||
private function add_totals_to_item_kit($item_kit)
|
||||
{
|
||||
$item_kit->total_cost_price = 0;
|
||||
$item_kit->total_unit_price = 0;
|
||||
|
||||
foreach ($this->Item_kit_items->get_info($item_kit->item_kit_id) as $item_kit_item)
|
||||
{
|
||||
$item_info = $this->Item->get_info($item_kit_item['item_id']);
|
||||
|
||||
$item_kit->total_cost_price += $item_info->cost_price * $item_kit_item['quantity'];
|
||||
$item_kit->total_unit_price += $item_info->unit_price * $item_kit_item['quantity'];
|
||||
}
|
||||
|
||||
return $item_kit;
|
||||
}
|
||||
|
||||
function index($limit_from=0)
|
||||
{
|
||||
$data['controller_name'] = $this->get_controller_name();
|
||||
$data['form_width'] = $this->get_form_width();
|
||||
$lines_per_page = $this->Appconfig->get('lines_per_page');
|
||||
$item_kits = $this->Item_kit->get_all($lines_per_page, $limit_from);
|
||||
|
||||
foreach($item_kits->result() as $item_kit)
|
||||
{
|
||||
// calculate the total cost and retail price of the Kit so it can be printed out in the manage table
|
||||
$item_kit = $this->add_totals_to_item_kit($item_kit);
|
||||
}
|
||||
|
||||
$data['links'] = $this->_initialize_pagination($this->Item_kit, $lines_per_page, $limit_from);
|
||||
$data['manage_table'] = get_item_kits_manage_table($item_kits, $this);
|
||||
|
||||
$this->load->view('item_kits/manage', $data);
|
||||
$this->_remove_duplicate_cookies();
|
||||
}
|
||||
|
||||
function search()
|
||||
{
|
||||
$search = $this->input->post('search');
|
||||
$limit_from = $this->input->post('limit_from');
|
||||
$lines_per_page = $this->Appconfig->get('lines_per_page');
|
||||
$item_kits = $this->Item_kit->search($search, $lines_per_page, $limit_from);
|
||||
$total_rows = $this->Item_kit->get_found_rows($search);
|
||||
$links = $this->_initialize_pagination($this->Item_kit, $lines_per_page, $limit_from, $total_rows, 'search');
|
||||
|
||||
foreach($item_kits->result() as $item_kit)
|
||||
{
|
||||
// calculate the total cost and retail price of the Kit so it can be printed out in the manage table
|
||||
$item_kit = $this->add_totals_to_item_kit($item_kit);
|
||||
}
|
||||
|
||||
$data_rows = get_item_kits_manage_table_data_rows($item_kits, $this);
|
||||
$this->_remove_duplicate_cookies();
|
||||
|
||||
echo json_encode(array('total_rows' => $total_rows, 'rows' => $data_rows, 'pagination' => $links));
|
||||
}
|
||||
|
||||
/*
|
||||
Gives search suggestions based on what is being searched for
|
||||
*/
|
||||
function suggest()
|
||||
{
|
||||
$suggestions = $this->Item_kit->get_search_suggestions($this->input->post('q'), $this->input->post('limit'));
|
||||
|
||||
echo implode("\n", $suggestions);
|
||||
}
|
||||
|
||||
function get_row()
|
||||
{
|
||||
$item_kit_id = $this->input->post('row_id');
|
||||
|
||||
// calculate the total cost and retail price of the Kit so it can be added to the table refresh
|
||||
$item_kit = $this->add_totals_to_item_kit($this->Item_kit->get_info($item_kit_id));
|
||||
|
||||
echo (get_item_kit_data_row($item_kit, $this));
|
||||
$this->_remove_duplicate_cookies();
|
||||
}
|
||||
|
||||
function view($item_kit_id=-1)
|
||||
{
|
||||
$data['item_kit_info'] = $this->Item_kit->get_info($item_kit_id);
|
||||
$this->load->view("item_kits/form", $data);
|
||||
}
|
||||
|
||||
function save($item_kit_id=-1)
|
||||
{
|
||||
$item_kit_data = array(
|
||||
'name' => $this->input->post('name'),
|
||||
'description' => $this->input->post('description')
|
||||
);
|
||||
|
||||
if ($this->Item_kit->save($item_kit_data, $item_kit_id))
|
||||
{
|
||||
//New item kit
|
||||
if ($item_kit_id==-1)
|
||||
{
|
||||
$item_kit_id = $item_kit_data['item_kit_id'];
|
||||
|
||||
echo json_encode(array('success'=>true,
|
||||
'message'=>$this->lang->line('item_kits_successful_adding').' '.$item_kit_data['name'],
|
||||
'item_kit_id'=>$item_kit_id));
|
||||
}
|
||||
else //previous item
|
||||
{
|
||||
echo json_encode(array('success'=>true,
|
||||
'message'=>$this->lang->line('item_kits_successful_updating').' '.$item_kit_data['name'],
|
||||
'item_kit_id'=>$item_kit_id));
|
||||
}
|
||||
|
||||
if ($this->input->post('item_kit_item'))
|
||||
{
|
||||
$item_kit_items = array();
|
||||
foreach($this->input->post('item_kit_item') as $item_id => $quantity)
|
||||
{
|
||||
$item_kit_items[] = array(
|
||||
'item_id' => $item_id,
|
||||
'quantity' => $quantity
|
||||
);
|
||||
}
|
||||
|
||||
$this->Item_kit_items->save($item_kit_items, $item_kit_id);
|
||||
}
|
||||
}
|
||||
else//failure
|
||||
{
|
||||
echo json_encode(array('success'=>false,
|
||||
'message'=>$this->lang->line('item_kits_error_adding_updating').' '.$item_kit_data['name'],
|
||||
'item_kit_id'=>-1));
|
||||
}
|
||||
}
|
||||
|
||||
function delete()
|
||||
{
|
||||
$item_kits_to_delete = $this->input->post('ids');
|
||||
|
||||
if ($this->Item_kit->delete_list($item_kits_to_delete))
|
||||
{
|
||||
echo json_encode(array('success'=>true,
|
||||
'message'=>$this->lang->line('item_kits_successful_deleted').' '.count($item_kits_to_delete).' '.$this->lang->line('item_kits_one_or_multiple')));
|
||||
}
|
||||
else
|
||||
{
|
||||
echo json_encode(array('success'=>false,
|
||||
'message'=>$this->lang->line('item_kits_cannot_be_deleted')));
|
||||
}
|
||||
}
|
||||
|
||||
function generate_barcodes($item_kit_ids)
|
||||
{
|
||||
$this->load->library('barcode_lib');
|
||||
$result = array();
|
||||
|
||||
$item_kit_ids = explode(':', $item_kit_ids);
|
||||
foreach ($item_kit_ids as $item_kid_id)
|
||||
{
|
||||
// calculate the total cost and retail price of the Kit so it can be added to the barcode text at the bottom
|
||||
$item_kit = $this->add_totals_to_item_kit($this->Item_kit->get_info($item_kid_id));
|
||||
|
||||
$result[] = array('name'=>$item_kit->name, 'item_id'=>'KIT '.$item_kid_id, 'item_number'=>'KIT '.$item_kid_id, 'cost_price'=>$item_kit->total_cost_price, 'unit_price'=>$item_kit->total_unit_price);
|
||||
}
|
||||
|
||||
$data['items'] = $result;
|
||||
$barcode_config = $this->barcode_lib->get_barcode_config();
|
||||
// in case the selected barcode type is not Code39 or Code128 we set by default Code128
|
||||
// the rationale for this is that EAN codes cannot have strings as seed, so 'KIT ' is not allowed
|
||||
if($barcode_config['barcode_type'] != 'Code39' && $barcode_config['barcode_type'] != 'Code128')
|
||||
{
|
||||
$barcode_config['barcode_type'] = 'Code128';
|
||||
}
|
||||
$data['barcode_config'] = $barcode_config;
|
||||
$this->load->view("barcode_sheet", $data);
|
||||
}
|
||||
|
||||
/*
|
||||
get the width for the add/edit form
|
||||
*/
|
||||
function get_form_width()
|
||||
{
|
||||
return 400;
|
||||
}
|
||||
}
|
||||
?>
|
||||
@@ -1,798 +0,0 @@
|
||||
<?php
|
||||
require_once ("secure_area.php");
|
||||
require_once ("interfaces/idata_controller.php");
|
||||
|
||||
class Items extends Secure_area implements iData_controller
|
||||
{
|
||||
function __construct()
|
||||
{
|
||||
parent::__construct('items');
|
||||
$this->load->library('item_lib');
|
||||
}
|
||||
|
||||
function index($limit_from=0)
|
||||
{
|
||||
$stock_location = $this->item_lib->get_item_location();
|
||||
$stock_locations = $this->Stock_location->get_allowed_locations();
|
||||
|
||||
$data['controller_name'] = $this->get_controller_name();
|
||||
$data['form_width'] = $this->get_form_width();
|
||||
$lines_per_page = $this->Appconfig->get('lines_per_page');
|
||||
$items = $this->Item->get_all($stock_location, $lines_per_page, $limit_from);
|
||||
$data['links'] = $this->_initialize_pagination($this->Item, $lines_per_page, $limit_from);
|
||||
|
||||
// assume year 2010 as starting date for OSPOS
|
||||
$start_of_time = date($this->config->item('dateformat'), mktime(0,0,0,1,1,2010));
|
||||
$today = date($this->config->item('dateformat'));
|
||||
|
||||
$start_date = $this->input->post('start_date') != NULL ? $this->input->post('start_date', TRUE) : $start_of_time;
|
||||
$start_date_formatter = date_create_from_format($this->config->item('dateformat'), $start_date);
|
||||
$end_date = $this->input->post('end_date') != NULL ? $this->input->post('end_date', TRUE) : $today;
|
||||
$end_date_formatter = date_create_from_format($this->config->item('dateformat'), $end_date);
|
||||
|
||||
$data['start_date'] = $start_date_formatter->format($this->config->item('dateformat'));
|
||||
$data['end_date'] = $end_date_formatter->format($this->config->item('dateformat'));
|
||||
|
||||
$data['stock_location'] = $stock_location;
|
||||
$data['stock_locations'] = $stock_locations;
|
||||
$data['manage_table'] = get_items_manage_table( $this->Item->get_all($stock_location, $lines_per_page, $limit_from), $this );
|
||||
|
||||
$this->load->view('items/manage', $data);
|
||||
|
||||
$this->_remove_duplicate_cookies();
|
||||
}
|
||||
|
||||
function find_item_info()
|
||||
{
|
||||
$item_number=$this->input->post('scan_item_number');
|
||||
echo json_encode($this->Item->find_item_info($item_number));
|
||||
}
|
||||
|
||||
function search()
|
||||
{
|
||||
$search = $this->input->post('search');
|
||||
$this->item_lib->set_item_location($this->input->post('stock_location'));
|
||||
$data['search_section_state'] = $this->input->post('search_section_state');
|
||||
$limit_from = $this->input->post('limit_from');
|
||||
$lines_per_page = $this->Appconfig->get('lines_per_page');
|
||||
|
||||
// assume year 2010 as starting date for OSPOS
|
||||
$start_of_time = date($this->config->item('dateformat'), mktime(0,0,0,1,1,2010));
|
||||
$today = date($this->config->item('dateformat'));
|
||||
|
||||
$start_date = $this->input->post('start_date') != NULL ? $this->input->post('start_date', TRUE) : $start_of_time;
|
||||
$start_date_formatter = date_create_from_format($this->config->item('dateformat'), $start_date);
|
||||
$end_date = $this->input->post('end_date') != NULL ? $this->input->post('end_date', TRUE) : $today;
|
||||
$end_date_formatter = date_create_from_format($this->config->item('dateformat'), $end_date);
|
||||
|
||||
$filters = array('start_date' => $start_date_formatter->format('Y-m-d'),
|
||||
'end_date' => $end_date_formatter->format('Y-m-d'),
|
||||
'stock_location_id' => $this->item_lib->get_item_location(),
|
||||
'empty_upc' => $this->input->post('empty_upc'),
|
||||
'low_inventory' => $this->input->post('low_inventory'),
|
||||
'is_serialized' => $this->input->post('is_serialized'),
|
||||
'no_description' => $this->input->post('no_description'),
|
||||
'search_custom' => $this->input->post('search_custom'),
|
||||
'is_deleted' => $this->input->post('is_deleted'));
|
||||
|
||||
$items = $this->Item->search($search, $filters, $lines_per_page, $limit_from);
|
||||
$data_rows = get_items_manage_table_data_rows($items, $this);
|
||||
$total_rows = $this->Item->get_found_rows($search, $filters);
|
||||
$links = $this->_initialize_pagination($this->Item, $lines_per_page, $limit_from, $total_rows, 'search');
|
||||
$data_rows = get_items_manage_table_data_rows($items, $this);
|
||||
// do not move this line to be after the json_encode otherwise the searhc function won't work!!
|
||||
$this->_remove_duplicate_cookies();
|
||||
|
||||
echo json_encode(array('total_rows' => $total_rows, 'rows' => $data_rows, 'pagination' => $links));
|
||||
}
|
||||
|
||||
function pic_thumb($pic_id)
|
||||
{
|
||||
$this->load->helper('file');
|
||||
$this->load->library('image_lib');
|
||||
$base_path = "uploads/item_pics/" . $pic_id ;
|
||||
$images = glob ($base_path. "*");
|
||||
if (sizeof($images) > 0)
|
||||
{
|
||||
$image_path = $images[0];
|
||||
$ext = pathinfo($image_path, PATHINFO_EXTENSION);
|
||||
$thumb_path = $base_path . $this->image_lib->thumb_marker.'.'.$ext;
|
||||
if (sizeof($images) < 2)
|
||||
{
|
||||
$config['image_library'] = 'gd2';
|
||||
$config['source_image'] = $image_path;
|
||||
$config['maintain_ratio'] = TRUE;
|
||||
$config['create_thumb'] = TRUE;
|
||||
$config['width'] = 52;
|
||||
$config['height'] = 32;
|
||||
$this->image_lib->initialize($config);
|
||||
$image = $this->image_lib->resize();
|
||||
$thumb_path = $this->image_lib->full_dst_path;
|
||||
}
|
||||
$this->output->set_content_type(get_mime_by_extension($thumb_path));
|
||||
$this->output->set_output(file_get_contents($thumb_path));
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
Gives search suggestions based on what is being searched for
|
||||
*/
|
||||
function suggest()
|
||||
{
|
||||
$suggestions = $this->Item->get_search_suggestions($this->input->post('q'), $this->input->post('limit'),
|
||||
$this->input->post('search_custom'), $this->input->post('is_deleted'));
|
||||
|
||||
echo implode("\n",$suggestions);
|
||||
}
|
||||
|
||||
function item_search()
|
||||
{
|
||||
$suggestions = $this->Item->get_item_search_suggestions($this->input->post('q'), $this->input->post('limit'));
|
||||
|
||||
echo implode("\n",$suggestions);
|
||||
}
|
||||
|
||||
/*
|
||||
Gives search suggestions based on what is being searched for
|
||||
*/
|
||||
function suggest_category()
|
||||
{
|
||||
$suggestions = $this->Item->get_category_suggestions($this->input->post('q'));
|
||||
|
||||
echo implode("\n",$suggestions);
|
||||
}
|
||||
|
||||
/*
|
||||
Gives search suggestions based on what is being searched for
|
||||
*/
|
||||
function suggest_location()
|
||||
{
|
||||
$suggestions = $this->Item->get_location_suggestions($this->input->post('q'));
|
||||
|
||||
echo implode("\n",$suggestions);
|
||||
}
|
||||
|
||||
/*
|
||||
Gives search suggestions based on what is being searched for
|
||||
*/
|
||||
function suggest_custom1()
|
||||
{
|
||||
$suggestions = $this->Item->get_custom1_suggestions($this->input->post('q'));
|
||||
|
||||
echo implode("\n",$suggestions);
|
||||
}
|
||||
|
||||
/*
|
||||
Gives search suggestions based on what is being searched for
|
||||
*/
|
||||
function suggest_custom2()
|
||||
{
|
||||
$suggestions = $this->Item->get_custom2_suggestions($this->input->post('q'));
|
||||
|
||||
echo implode("\n",$suggestions);
|
||||
}
|
||||
|
||||
/*
|
||||
Gives search suggestions based on what is being searched for
|
||||
*/
|
||||
function suggest_custom3()
|
||||
{
|
||||
$suggestions = $this->Item->get_custom3_suggestions($this->input->post('q'));
|
||||
|
||||
echo implode("\n",$suggestions);
|
||||
}
|
||||
|
||||
/*
|
||||
Gives search suggestions based on what is being searched for
|
||||
*/
|
||||
function suggest_custom4()
|
||||
{
|
||||
$suggestions = $this->Item->get_custom4_suggestions($this->input->post('q'));
|
||||
|
||||
echo implode("\n",$suggestions);
|
||||
}
|
||||
|
||||
/*
|
||||
Gives search suggestions based on what is being searched for
|
||||
*/
|
||||
function suggest_custom5()
|
||||
{
|
||||
$suggestions = $this->Item->get_custom5_suggestions($this->input->post('q'));
|
||||
|
||||
echo implode("\n",$suggestions);
|
||||
}
|
||||
|
||||
/*
|
||||
Gives search suggestions based on what is being searched for
|
||||
*/
|
||||
function suggest_custom6()
|
||||
{
|
||||
$suggestions = $this->Item->get_custom6_suggestions($this->input->post('q'));
|
||||
|
||||
echo implode("\n",$suggestions);
|
||||
}
|
||||
|
||||
/*
|
||||
Gives search suggestions based on what is being searched for
|
||||
*/
|
||||
function suggest_custom7()
|
||||
{
|
||||
$suggestions = $this->Item->get_custom7_suggestions($this->input->post('q'));
|
||||
|
||||
echo implode("\n",$suggestions);
|
||||
}
|
||||
|
||||
/*
|
||||
Gives search suggestions based on what is being searched for
|
||||
*/
|
||||
function suggest_custom8()
|
||||
{
|
||||
$suggestions = $this->Item->get_custom8_suggestions($this->input->post('q'));
|
||||
|
||||
echo implode("\n",$suggestions);
|
||||
}
|
||||
|
||||
/*
|
||||
Gives search suggestions based on what is being searched for
|
||||
*/
|
||||
function suggest_custom9()
|
||||
{
|
||||
$suggestions = $this->Item->get_custom9_suggestions($this->input->post('q'));
|
||||
|
||||
echo implode("\n",$suggestions);
|
||||
}
|
||||
|
||||
/*
|
||||
Gives search suggestions based on what is being searched for
|
||||
*/
|
||||
function suggest_custom10()
|
||||
{
|
||||
$suggestions = $this->Item->get_custom10_suggestions($this->input->post('q'));
|
||||
|
||||
echo implode("\n",$suggestions);
|
||||
}
|
||||
|
||||
function get_row()
|
||||
{
|
||||
$item_id = $this->input->post('row_id');
|
||||
$item_info = $this->Item->get_info($item_id);
|
||||
$stock_location = $this->item_lib->get_item_location();
|
||||
$item_quantity = $this->Item_quantity->get_item_quantity($item_id,$stock_location);
|
||||
$item_info->quantity = $item_quantity->quantity;
|
||||
$data_row = get_item_data_row($item_info,$this);
|
||||
|
||||
echo $data_row;
|
||||
|
||||
$this->_remove_duplicate_cookies();
|
||||
}
|
||||
|
||||
function view($item_id=-1)
|
||||
{
|
||||
$data['item_info']=$this->Item->get_info($item_id);
|
||||
$data['item_tax_info']=$this->Item_taxes->get_info($item_id);
|
||||
$suppliers = array('' => $this->lang->line('items_none'));
|
||||
foreach($this->Supplier->get_all()->result_array() as $row)
|
||||
{
|
||||
$suppliers[$row['person_id']] = $row['company_name'];
|
||||
}
|
||||
|
||||
$data['suppliers']=$suppliers;
|
||||
$data['selected_supplier'] = $this->Item->get_info($item_id)->supplier_id;
|
||||
$data['default_tax_1_rate']=($item_id==-1) ? $this->Appconfig->get('default_tax_1_rate') : '';
|
||||
$data['default_tax_2_rate']=($item_id==-1) ? $this->Appconfig->get('default_tax_2_rate') : '';
|
||||
|
||||
$locations_data = $this->Stock_location->get_undeleted_all()->result_array();
|
||||
foreach($locations_data as $location)
|
||||
{
|
||||
$quantity = $this->Item_quantity->get_item_quantity($item_id,$location['location_id'])->quantity;
|
||||
$quantity = ($item_id == -1) ? null: $quantity;
|
||||
$location_array[$location['location_id']] = array('location_name'=>$location['location_name'], 'quantity'=>$quantity);
|
||||
$data['stock_locations'] = $location_array;
|
||||
}
|
||||
|
||||
$this->load->view("items/form", $data);
|
||||
}
|
||||
|
||||
function inventory($item_id=-1)
|
||||
{
|
||||
$data['item_info']=$this->Item->get_info($item_id);
|
||||
|
||||
$data['stock_locations'] = array();
|
||||
$stock_locations = $this->Stock_location->get_undeleted_all()->result_array();
|
||||
foreach($stock_locations as $location_data)
|
||||
{
|
||||
$data['stock_locations'][$location_data['location_id']] = $location_data['location_name'];
|
||||
$data['item_quantities'][$location_data['location_id']] = $this->Item_quantity->get_item_quantity($item_id,$location_data['location_id'])->quantity;
|
||||
}
|
||||
|
||||
$this->load->view("items/inventory", $data);
|
||||
}
|
||||
|
||||
function count_details($item_id=-1)
|
||||
{
|
||||
$data['item_info']=$this->Item->get_info($item_id);
|
||||
|
||||
$data['stock_locations'] = array();
|
||||
$stock_locations = $this->Stock_location->get_undeleted_all()->result_array();
|
||||
foreach($stock_locations as $location_data)
|
||||
{
|
||||
$data['stock_locations'][$location_data['location_id']] = $location_data['location_name'];
|
||||
$data['item_quantities'][$location_data['location_id']] = $this->Item_quantity->get_item_quantity($item_id,$location_data['location_id'])->quantity;
|
||||
}
|
||||
|
||||
$this->load->view("items/count_details", $data);
|
||||
}
|
||||
|
||||
function generate_barcodes($item_ids)
|
||||
{
|
||||
$this->load->library('barcode_lib');
|
||||
$result = array();
|
||||
|
||||
$item_ids = explode(':', $item_ids);
|
||||
$result = $this->Item->get_multiple_info($item_ids)->result_array();
|
||||
$config = $this->barcode_lib->get_barcode_config();
|
||||
|
||||
$data['barcode_config'] = $config;
|
||||
|
||||
// check the list of items to see if any item_number field is empty
|
||||
foreach($result as &$item)
|
||||
{
|
||||
// update the UPC/EAN/ISBN field if empty / null with the newly generated barcode
|
||||
if (empty($item['item_number']) && $this->Appconfig->get('barcode_generate_if_empty'))
|
||||
{
|
||||
// get the newly generated barcode
|
||||
$barcode_instance = Barcode_lib::barcode_instance($item, $config);
|
||||
$item['item_number'] = $barcode_instance->getData();
|
||||
// remove from item any suppliers table info to avoid save failure because of unknown fields
|
||||
// WARNING: if suppliers table is changed this list needs to be upgraded, which makes the matter a bit tricky to maintain
|
||||
unset($item['person_id']);
|
||||
unset($item['company_name']);
|
||||
unset($item['account_number']);
|
||||
unset($item['agency_name']);
|
||||
|
||||
// update the item in the database in order to save the UPC/EAN/ISBN field
|
||||
$this->Item->save($item, $item['item_id']);
|
||||
}
|
||||
}
|
||||
$data['items'] = $result;
|
||||
// display barcodes
|
||||
$this->load->view("barcode_sheet", $data);
|
||||
|
||||
}
|
||||
|
||||
function bulk_edit()
|
||||
{
|
||||
$data = array();
|
||||
$suppliers = array('' => $this->lang->line('items_none'));
|
||||
foreach($this->Supplier->get_all()->result_array() as $row)
|
||||
{
|
||||
$suppliers[$row['person_id']] = $row['company_name'];
|
||||
}
|
||||
$data['suppliers'] = $suppliers;
|
||||
$data['allow_alt_description_choices'] = array(
|
||||
''=>$this->lang->line('items_do_nothing'),
|
||||
1 =>$this->lang->line('items_change_all_to_allow_alt_desc'),
|
||||
0 =>$this->lang->line('items_change_all_to_not_allow_allow_desc'));
|
||||
|
||||
$data['serialization_choices'] = array(
|
||||
''=>$this->lang->line('items_do_nothing'),
|
||||
1 =>$this->lang->line('items_change_all_to_serialized'),
|
||||
0 =>$this->lang->line('items_change_all_to_unserialized'));
|
||||
|
||||
$this->load->view("items/form_bulk", $data);
|
||||
}
|
||||
|
||||
function save($item_id=-1)
|
||||
{
|
||||
$upload_success = $this->_handle_image_upload();
|
||||
$upload_data = $this->upload->data();
|
||||
//Save item data
|
||||
$item_data = array(
|
||||
'name'=>$this->input->post('name'),
|
||||
'description'=>$this->input->post('description'),
|
||||
'category'=>$this->input->post('category'),
|
||||
'supplier_id'=>$this->input->post('supplier_id')=='' ? null:$this->input->post('supplier_id'),
|
||||
'item_number'=>$this->input->post('item_number')=='' ? null:$this->input->post('item_number'),
|
||||
'cost_price'=>$this->input->post('cost_price'),
|
||||
'unit_price'=>$this->input->post('unit_price'),
|
||||
'reorder_level'=>$this->input->post('reorder_level'),
|
||||
'receiving_quantity'=>$this->input->post('receiving_quantity'),
|
||||
'allow_alt_description'=>$this->input->post('allow_alt_description'),
|
||||
'is_serialized'=>$this->input->post('is_serialized'),
|
||||
'deleted'=>$this->input->post('is_deleted'),
|
||||
'custom1'=>$this->input->post('custom1'),
|
||||
'custom2'=>$this->input->post('custom2'),
|
||||
'custom3'=>$this->input->post('custom3'),
|
||||
'custom4'=>$this->input->post('custom4'),
|
||||
'custom5'=>$this->input->post('custom5'),
|
||||
'custom6'=>$this->input->post('custom6'),
|
||||
'custom7'=>$this->input->post('custom7'),
|
||||
'custom8'=>$this->input->post('custom8'),
|
||||
'custom9'=>$this->input->post('custom9'),
|
||||
'custom10'=>$this->input->post('custom10')
|
||||
);
|
||||
|
||||
if (!empty($upload_data['orig_name']))
|
||||
{
|
||||
$item_data['pic_id'] = $upload_data['raw_name'];
|
||||
}
|
||||
|
||||
$employee_id = $this->Employee->get_logged_in_employee_info()->person_id;
|
||||
$cur_item_info = $this->Item->get_info($item_id);
|
||||
|
||||
if($this->Item->save($item_data,$item_id))
|
||||
{
|
||||
$success = TRUE;
|
||||
$new_item = FALSE;
|
||||
//New item
|
||||
if ($item_id==-1)
|
||||
{
|
||||
$item_id = $item_data['item_id'];
|
||||
$new_item = TRUE;
|
||||
}
|
||||
|
||||
$items_taxes_data = array();
|
||||
$tax_names = $this->input->post('tax_names');
|
||||
$tax_percents = $this->input->post('tax_percents');
|
||||
for($k=0;$k<count($tax_percents);$k++)
|
||||
{
|
||||
if (is_numeric($tax_percents[$k]))
|
||||
{
|
||||
$items_taxes_data[] = array('name'=>$tax_names[$k], 'percent'=>$tax_percents[$k] );
|
||||
}
|
||||
}
|
||||
$success &= $this->Item_taxes->save($items_taxes_data, $item_id);
|
||||
|
||||
//Save item quantity
|
||||
$stock_locations = $this->Stock_location->get_undeleted_all()->result_array();
|
||||
foreach($stock_locations as $location_data)
|
||||
{
|
||||
$updated_quantity = $this->input->post($location_data['location_id'].'_quantity');
|
||||
$location_detail = array('item_id'=>$item_id,
|
||||
'location_id'=>$location_data['location_id'],
|
||||
'quantity'=>$updated_quantity);
|
||||
$item_quantity = $this->Item_quantity->get_item_quantity($item_id, $location_data['location_id']);
|
||||
if ($item_quantity->quantity != $updated_quantity || $new_item)
|
||||
{
|
||||
$success &= $this->Item_quantity->save($location_detail, $item_id, $location_data['location_id']);
|
||||
|
||||
$inv_data = array(
|
||||
'trans_date'=>date('Y-m-d H:i:s'),
|
||||
'trans_items'=>$item_id,
|
||||
'trans_user'=>$employee_id,
|
||||
'trans_location'=>$location_data['location_id'],
|
||||
'trans_comment'=>$this->lang->line('items_manually_editing_of_quantity'),
|
||||
'trans_inventory'=>$updated_quantity - $item_quantity->quantity
|
||||
);
|
||||
|
||||
$success &= $this->Inventory->insert($inv_data);
|
||||
}
|
||||
}
|
||||
|
||||
if ($success && $upload_success)
|
||||
{
|
||||
$success_message = $this->lang->line('items_successful_' . ($new_item ? 'adding' : 'updating')) .' '. $item_data['name'];
|
||||
|
||||
echo json_encode(array('success'=>true,'message'=>$success_message,'item_id'=>$item_id));
|
||||
}
|
||||
else
|
||||
{
|
||||
$error_message = $upload_success ?
|
||||
$this->lang->line('items_error_adding_updating') .' '. $item_data['name'] :
|
||||
$this->upload->display_errors();
|
||||
|
||||
echo json_encode(array('success'=>false,
|
||||
'message'=>$error_message,'item_id'=>$item_id));
|
||||
}
|
||||
|
||||
}
|
||||
else//failure
|
||||
{
|
||||
echo json_encode(array('success'=>false,
|
||||
'message'=>$this->lang->line('items_error_adding_updating').' '
|
||||
.$item_data['name'],'item_id'=>-1));
|
||||
}
|
||||
}
|
||||
|
||||
function check_item_number()
|
||||
{
|
||||
$exists = $this->Item->item_number_exists($this->input->post('item_number'),$this->input->post('item_id'));
|
||||
echo json_encode(array('success'=>!$exists,'message'=>$this->lang->line('items_item_number_duplicate')));
|
||||
}
|
||||
|
||||
function _handle_image_upload()
|
||||
{
|
||||
$this->load->helper('directory');
|
||||
$map = directory_map('./uploads/item_pics/', 1);
|
||||
// load upload library
|
||||
$config = array('upload_path' => './uploads/item_pics/',
|
||||
'allowed_types' => 'gif|jpg|png',
|
||||
'max_size' => '100',
|
||||
'max_width' => '640',
|
||||
'max_height' => '480',
|
||||
'file_name' => sizeof($map));
|
||||
$this->load->library('upload', $config);
|
||||
$this->upload->do_upload('item_image');
|
||||
|
||||
return strlen($this->upload->display_errors()) == 0 ||
|
||||
!strcmp($this->upload->display_errors(),
|
||||
'<p>'.$this->lang->line('upload_no_file_selected').'</p>');
|
||||
}
|
||||
|
||||
function save_inventory($item_id=-1)
|
||||
{
|
||||
$employee_id=$this->Employee->get_logged_in_employee_info()->person_id;
|
||||
$cur_item_info = $this->Item->get_info($item_id);
|
||||
$location_id = $this->input->post('stock_location');
|
||||
$inv_data = array(
|
||||
'trans_date'=>date('Y-m-d H:i:s'),
|
||||
'trans_items'=>$item_id,
|
||||
'trans_user'=>$employee_id,
|
||||
'trans_location'=>$location_id,
|
||||
'trans_comment'=>$this->input->post('trans_comment'),
|
||||
'trans_inventory'=>$this->input->post('newquantity')
|
||||
);
|
||||
|
||||
$this->Inventory->insert($inv_data);
|
||||
|
||||
//Update stock quantity
|
||||
$item_quantity= $this->Item_quantity->get_item_quantity($item_id,$location_id);
|
||||
$item_quantity_data = array(
|
||||
'item_id'=>$item_id,
|
||||
'location_id'=>$location_id,
|
||||
'quantity'=>$item_quantity->quantity + $this->input->post('newquantity')
|
||||
);
|
||||
|
||||
if($this->Item_quantity->save($item_quantity_data,$item_id,$location_id))
|
||||
{
|
||||
echo json_encode(array('success'=>true,'message'=>$this->lang->line('items_successful_updating').' '.
|
||||
$cur_item_info->name,'item_id'=>$item_id));
|
||||
}
|
||||
else//failure
|
||||
{
|
||||
echo json_encode(array('success'=>false,'message'=>$this->lang->line('items_error_adding_updating').' '.
|
||||
$cur_item_info->name,'item_id'=>-1));
|
||||
}
|
||||
}
|
||||
|
||||
function bulk_update()
|
||||
{
|
||||
$items_to_update=$this->input->post('item_ids');
|
||||
$item_data = array();
|
||||
|
||||
foreach($_POST as $key=>$value)
|
||||
{
|
||||
//This field is nullable, so treat it differently
|
||||
if ($key == 'supplier_id')
|
||||
{
|
||||
$item_data["$key"]=$value == '' ? null : $value;
|
||||
}
|
||||
elseif($value!='' and !(in_array($key, array('submit', 'item_ids', 'tax_names', 'tax_percents', 'category'))))
|
||||
{
|
||||
$item_data["$key"]=$value;
|
||||
}
|
||||
}
|
||||
|
||||
//Item data could be empty if tax information is being updated
|
||||
if(empty($item_data) || $this->Item->update_multiple($item_data,$items_to_update))
|
||||
{
|
||||
$items_taxes_data = array();
|
||||
$tax_names = $this->input->post('tax_names');
|
||||
$tax_percents = $this->input->post('tax_percents');
|
||||
for($k=0;$k<count($tax_percents);$k++)
|
||||
{
|
||||
if (is_numeric($tax_percents[$k]))
|
||||
{
|
||||
$items_taxes_data[] = array('name'=>$tax_names[$k], 'percent'=>$tax_percents[$k] );
|
||||
}
|
||||
}
|
||||
$this->Item_taxes->save_multiple($items_taxes_data, $items_to_update);
|
||||
|
||||
echo json_encode(array('success'=>true,'message'=>$this->lang->line('items_successful_bulk_edit')));
|
||||
}
|
||||
else
|
||||
{
|
||||
echo json_encode(array('success'=>false,'message'=>$this->lang->line('items_error_updating_multiple')));
|
||||
}
|
||||
}
|
||||
|
||||
function delete()
|
||||
{
|
||||
$items_to_delete=$this->input->post('ids');
|
||||
|
||||
if($this->Item->delete_list($items_to_delete))
|
||||
{
|
||||
echo json_encode(array('success'=>true,'message'=>$this->lang->line('items_successful_deleted').' '.
|
||||
count($items_to_delete).' '.$this->lang->line('items_one_or_multiple')));
|
||||
}
|
||||
else
|
||||
{
|
||||
echo json_encode(array('success'=>false,'message'=>$this->lang->line('items_cannot_be_deleted')));
|
||||
}
|
||||
}
|
||||
|
||||
function excel()
|
||||
{
|
||||
$data = file_get_contents("import_items.csv");
|
||||
$name = 'import_items.csv';
|
||||
force_download($name, $data);
|
||||
}
|
||||
|
||||
function excel_import()
|
||||
{
|
||||
$this->load->view("items/excel_import", null);
|
||||
}
|
||||
|
||||
function do_excel_import()
|
||||
{
|
||||
$msg = 'do_excel_import';
|
||||
$failCodes = array();
|
||||
if ($_FILES['file_path']['error']!=UPLOAD_ERR_OK)
|
||||
{
|
||||
$msg = $this->lang->line('items_excel_import_failed');
|
||||
echo json_encode( array('success'=>false,'message'=>$msg) );
|
||||
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (($handle = fopen($_FILES['file_path']['tmp_name'], "r")) !== FALSE)
|
||||
{
|
||||
//Skip first row
|
||||
fgetcsv($handle);
|
||||
|
||||
$i=1;
|
||||
while (($data = fgetcsv($handle)) !== FALSE)
|
||||
{
|
||||
if (sizeof($data) >= 23) {
|
||||
$item_data = array(
|
||||
'name' => $data[1],
|
||||
'description' => $data[11],
|
||||
'category' => $data[2],
|
||||
'cost_price' => $data[4],
|
||||
'unit_price' => $data[5],
|
||||
'reorder_level' => $data[10],
|
||||
'supplier_id' => $this->Supplier->exists($data[3]) ? $data[3] : null,
|
||||
'allow_alt_description' => $data[12] != '' ? '1' : '0',
|
||||
'is_serialized' => $data[13] != '' ? '1' : '0',
|
||||
'custom1' => $data[14],
|
||||
'custom2' => $data[15],
|
||||
'custom3' => $data[16],
|
||||
'custom4' => $data[17],
|
||||
'custom5' => $data[18],
|
||||
'custom6' => $data[19],
|
||||
'custom7' => $data[20],
|
||||
'custom8' => $data[21],
|
||||
'custom9' => $data[22],
|
||||
'custom10' => $data[23]
|
||||
);
|
||||
$item_number = $data[0];
|
||||
$invalidated = false;
|
||||
if ($item_number != "")
|
||||
{
|
||||
$item_data['item_number'] = $item_number;
|
||||
$invalidated = $this->Item->item_number_exists($item_number);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$invalidated = true;
|
||||
}
|
||||
if(!$invalidated && $this->Item->save($item_data))
|
||||
{
|
||||
$items_taxes_data = null;
|
||||
//tax 1
|
||||
if( is_numeric($data[7]) && $data[6]!='' )
|
||||
{
|
||||
$items_taxes_data[] = array('name'=>$data[6], 'percent'=>$data[7] );
|
||||
}
|
||||
|
||||
//tax 2
|
||||
if( is_numeric($data[9]) && $data[8]!='' )
|
||||
{
|
||||
$items_taxes_data[] = array('name'=>$data[8], 'percent'=>$data[9] );
|
||||
}
|
||||
|
||||
// save tax values
|
||||
if(count($items_taxes_data) > 0)
|
||||
{
|
||||
$this->Item_taxes->save($items_taxes_data, $item_data['item_id']);
|
||||
}
|
||||
|
||||
// quantities & inventory Info
|
||||
$employee_id=$this->Employee->get_logged_in_employee_info()->person_id;
|
||||
$emp_info=$this->Employee->get_info($employee_id);
|
||||
$comment ='Qty CSV Imported';
|
||||
|
||||
$cols = count($data);
|
||||
|
||||
// array to store information if location got a quantity
|
||||
$allowed_locations = $this->Stock_location->get_allowed_locations();
|
||||
for ($col = 24; $col < $cols; $col = $col + 2)
|
||||
{
|
||||
$location_id = $data[$col];
|
||||
if (array_key_exists($location_id, $allowed_locations))
|
||||
{
|
||||
$item_quantity_data = array (
|
||||
'item_id' => $item_data['item_id'],
|
||||
'location_id' => $location_id,
|
||||
'quantity' => $data[$col + 1],
|
||||
);
|
||||
$this->Item_quantity->save($item_quantity_data, $item_data['item_id'], $location_id);
|
||||
|
||||
$excel_data = array(
|
||||
'trans_items'=>$item_data['item_id'],
|
||||
'trans_user'=>$employee_id,
|
||||
'trans_comment'=>$comment,
|
||||
'trans_location'=>$data[$col],
|
||||
'trans_inventory'=>$data[$col + 1]
|
||||
);
|
||||
|
||||
$this->Inventory->insert($excel_data);
|
||||
unset($allowed_locations[$location_id]);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* now iterate through the array and check for which location_id no entry into item_quantities was made yet
|
||||
* those get an entry with quantity as 0.
|
||||
* unfortunately a bit duplicate code from above...
|
||||
*/
|
||||
foreach($allowed_locations as $location_id => $location_name)
|
||||
{
|
||||
$item_quantity_data = array(
|
||||
'item_id' => $item_data['item_id'],
|
||||
'location_id' => $location_id,
|
||||
'quantity' => 0,
|
||||
);
|
||||
$this->Item_quantity->save($item_quantity_data, $item_data['item_id'], $data[$col]);
|
||||
|
||||
$excel_data = array
|
||||
(
|
||||
'trans_items'=>$item_data['item_id'],
|
||||
'trans_user'=>$employee_id,
|
||||
'trans_comment'=>$comment,
|
||||
'trans_location'=>$location_id,
|
||||
'trans_inventory'=>0
|
||||
);
|
||||
$this->db->insert('inventory',$excel_data);
|
||||
}
|
||||
}
|
||||
else//insert or update item failure
|
||||
{
|
||||
$failCodes[] = $i;
|
||||
}
|
||||
}
|
||||
$i++;
|
||||
}
|
||||
else
|
||||
{
|
||||
echo json_encode( array('success'=>false, 'message'=>'Your upload file has no data or not in supported format.') );
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
$success = true;
|
||||
if(count($failCodes) > 0)
|
||||
{
|
||||
$msg = "Most items imported. But some were not, here is list of their CODE (" .count($failCodes) ."): ".implode(", ", $failCodes);
|
||||
$success = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
$msg = "Import items successful";
|
||||
}
|
||||
|
||||
echo json_encode( array('success'=>$success, 'message'=>$msg) );
|
||||
}
|
||||
|
||||
/*
|
||||
get the width for the add/edit form
|
||||
*/
|
||||
function get_form_width()
|
||||
{
|
||||
return 450;
|
||||
}
|
||||
}
|
||||
?>
|
||||
@@ -1,192 +0,0 @@
|
||||
<?php if (!defined('BASEPATH')) exit('No direct script access allowed');
|
||||
// ---------------------------------------------------------------------
|
||||
class Languagecheck extends CI_Controller {
|
||||
|
||||
/*
|
||||
* use this language as comparison reference.
|
||||
* this should be the one that is complete.
|
||||
*/
|
||||
private $reference = 'english';
|
||||
|
||||
private $lang_path = 'language';
|
||||
|
||||
// -----------------------------------------------------------------
|
||||
|
||||
/*
|
||||
* controller constructor
|
||||
*/
|
||||
function Languagecheck()
|
||||
{
|
||||
parent::Controller();
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------
|
||||
|
||||
/*
|
||||
* use remap to capture all calls to this controller
|
||||
*/
|
||||
function _remap()
|
||||
{
|
||||
// load the required helpers
|
||||
$this->load->helper('directory');
|
||||
|
||||
// for simplicity, we don't use views
|
||||
$this->output('h1', 'Open Source Point of Sale - Language file checking and validation');
|
||||
|
||||
// determine the language file path
|
||||
if ( ! is_dir($this->lang_path) )
|
||||
{
|
||||
$this->lang_path = APPPATH . $this->lang_path;
|
||||
|
||||
if ( ! is_dir($this->lang_path) )
|
||||
{
|
||||
$this->output('h2', 'Defined language path "'.$this->lang_path.'" not found!', TRUE);
|
||||
exit;
|
||||
}
|
||||
}
|
||||
|
||||
// fetch the languages directory map
|
||||
$languages = directory_map( $this->lang_path, TRUE );
|
||||
|
||||
// is our reference language present?
|
||||
if ( ! in_array($this->reference, $languages ) )
|
||||
{
|
||||
$this->output('h2', 'Reference language "'.$this->reference.'" not found!', TRUE);
|
||||
exit;
|
||||
}
|
||||
|
||||
// load the list of language files for the reference language
|
||||
$references = directory_map( $this->lang_path . '/' . $this->reference, TRUE );
|
||||
|
||||
// now process the list
|
||||
foreach( $references as $reference )
|
||||
{
|
||||
// skip non-language files in the language directory
|
||||
if ( strpos($reference, '_lang'.EXT) === FALSE )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// process it
|
||||
$this->output('h2', 'Processing '.$this->reference . ' » ' .$reference);
|
||||
|
||||
// load the language file
|
||||
include $this->lang_path . '/' . $this->reference . '/' . $reference;
|
||||
|
||||
// did the file contain any language strings?
|
||||
if ( empty($lang) )
|
||||
{
|
||||
// language file was empty or not properly defined
|
||||
$this->output('h3', 'Language file doesn\'t contain any language strings. Skipping file!', TRUE);
|
||||
continue;
|
||||
}
|
||||
|
||||
// store the loaded language strings
|
||||
$lang_ref = $lang;
|
||||
unset($lang);
|
||||
|
||||
// now loop through the available languages
|
||||
foreach ( $languages as $language )
|
||||
{
|
||||
// skip the reference language
|
||||
if ( $language == $this->reference )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// language file to check
|
||||
$file = $this->lang_path . '/' . $language . '/' . $reference;
|
||||
|
||||
// check if the language file exists for this language
|
||||
if ( ! file_exists( $file ) )
|
||||
{
|
||||
// file not found
|
||||
$this->output('h3', 'Language file doesn\'t exist for the language '.$language.'!', TRUE);
|
||||
}
|
||||
else
|
||||
{
|
||||
// load the file to compare
|
||||
include $file;
|
||||
|
||||
// did the file contain any language strings?
|
||||
if ( empty($lang) )
|
||||
{
|
||||
// language file was empty or not properly defined
|
||||
$this->output('h3', 'Language file for the language '.$language.' doesn\'t contain any language strings!', TRUE);
|
||||
}
|
||||
else
|
||||
{
|
||||
// start comparing
|
||||
$this->output('h3', 'Comparing with the '.$language.' version:');
|
||||
|
||||
// assume all goes well
|
||||
$failures = 0;
|
||||
|
||||
// start comparing language keys
|
||||
foreach( $lang_ref as $key => $value )
|
||||
{
|
||||
if ( ! isset($lang[$key]) )
|
||||
{
|
||||
// report the missing key
|
||||
$this->output('', 'Missing language string "'.$key.'"', TRUE);
|
||||
|
||||
// increment the failure counter
|
||||
$failures++;
|
||||
}
|
||||
}
|
||||
|
||||
if ( ! $failures )
|
||||
{
|
||||
$this->output('', 'The two language files have matching strings.');
|
||||
}
|
||||
}
|
||||
|
||||
// make sure the lang array is deleted before the next check
|
||||
if ( isset($lang) )
|
||||
{
|
||||
unset($lang);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
$this->output('h2', 'Language file checking and validation completed');
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------
|
||||
|
||||
private function output($type = '', $line = '', $highlight = FALSE)
|
||||
{
|
||||
switch ($type)
|
||||
{
|
||||
case 'h1':
|
||||
$html = "<h1>{line}</h1>\n<hr />\n";
|
||||
break;
|
||||
|
||||
case 'h2':
|
||||
$html = "<h2>{line}</h2>\n";
|
||||
break;
|
||||
|
||||
case 'h3':
|
||||
$html = "<h3> {line}</h3>\n";
|
||||
break;
|
||||
|
||||
default:
|
||||
$html = " » {line}<br />";
|
||||
break;
|
||||
}
|
||||
|
||||
if ( $highlight )
|
||||
{
|
||||
$line = '<span style="color:red;font-weight:bold;">' . $line . '</span>';
|
||||
}
|
||||
|
||||
echo str_replace('{line}', $line, $html);
|
||||
}
|
||||
// -----------------------------------------------------------------
|
||||
|
||||
}
|
||||
|
||||
/* End of file languagecheck.php */
|
||||
/* Location: ./application/controllers/languagecheck.php */
|
||||
@@ -1,43 +0,0 @@
|
||||
<?php
|
||||
class Login extends CI_Controller
|
||||
{
|
||||
function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
}
|
||||
|
||||
function index()
|
||||
{
|
||||
if($this->Employee->is_logged_in())
|
||||
{
|
||||
redirect('home');
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->form_validation->set_rules('username', 'lang:login_undername', 'callback_login_check');
|
||||
$this->form_validation->set_error_delimiters('<div class="error">', '</div>');
|
||||
|
||||
if($this->form_validation->run() == FALSE)
|
||||
{
|
||||
$this->load->view('login');
|
||||
}
|
||||
else
|
||||
{
|
||||
redirect('home');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function login_check($username)
|
||||
{
|
||||
$password = $this->input->post("password");
|
||||
|
||||
if(!$this->Employee->login($username,$password))
|
||||
{
|
||||
$this->form_validation->set_message('login_check', $this->lang->line('login_invalid_username_and_password'));
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
?>
|
||||
@@ -1,16 +0,0 @@
|
||||
<?php
|
||||
class No_Access extends CI_Controller
|
||||
{
|
||||
function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
}
|
||||
|
||||
function index($module_id='',$permission_id='')
|
||||
{
|
||||
$data['module_name']=$this->Module->get_module_name($module_id);
|
||||
$data['permission_id']=$permission_id;
|
||||
$this->load->view('no_access',$data);
|
||||
}
|
||||
}
|
||||
?>
|
||||
@@ -1,53 +0,0 @@
|
||||
<?php
|
||||
require_once ("interfaces/iperson_controller.php");
|
||||
require_once ("secure_area.php");
|
||||
abstract class Person_controller extends Secure_area implements iPerson_controller
|
||||
{
|
||||
function __construct($module_id=null)
|
||||
{
|
||||
parent::__construct($module_id);
|
||||
}
|
||||
|
||||
/*
|
||||
This returns a mailto link for persons with a certain id. This is called with AJAX.
|
||||
*/
|
||||
function mailto()
|
||||
{
|
||||
$people_to_email=$this->input->post('ids');
|
||||
|
||||
if($people_to_email!=false)
|
||||
{
|
||||
$mailto_url='mailto:';
|
||||
foreach($this->Person->get_multiple_info($people_to_email)->result() as $person)
|
||||
{
|
||||
$mailto_url.=$person->email.',';
|
||||
}
|
||||
//remove last comma
|
||||
$mailto_url=substr($mailto_url,0,strlen($mailto_url)-1);
|
||||
|
||||
echo $mailto_url;
|
||||
exit;
|
||||
}
|
||||
echo '#';
|
||||
}
|
||||
|
||||
/*
|
||||
Gives search suggestions based on what is being searched for
|
||||
*/
|
||||
function suggest()
|
||||
{
|
||||
$suggestions = $this->Person->get_search_suggestions($this->input->post('q'),$this->input->post('limit'));
|
||||
echo implode("\n",$suggestions);
|
||||
}
|
||||
|
||||
/*
|
||||
Gets one row for a person manage table. This is called using AJAX to update one row.
|
||||
*/
|
||||
function get_row()
|
||||
{
|
||||
$person_id = $this->input->post('row_id');
|
||||
$data_row=get_person_data_row($this->Person->get_info($person_id),$this);
|
||||
echo $data_row;
|
||||
}
|
||||
}
|
||||
?>
|
||||
@@ -1,411 +0,0 @@
|
||||
<?php
|
||||
require_once ("secure_area.php");
|
||||
class Receivings extends Secure_area
|
||||
{
|
||||
function __construct()
|
||||
{
|
||||
parent::__construct('receivings');
|
||||
$this->load->library('receiving_lib');
|
||||
$this->load->library('barcode_lib');
|
||||
}
|
||||
|
||||
function index()
|
||||
{
|
||||
$this->_reload();
|
||||
}
|
||||
|
||||
function item_search()
|
||||
{
|
||||
$suggestions = $this->Item->get_item_search_suggestions($this->input->post('q'),$this->input->post('limit'));
|
||||
$suggestions = array_merge($suggestions, $this->Item_kit->get_item_kit_search_suggestions($this->input->post('q'),$this->input->post('limit')));
|
||||
echo implode("\n",$suggestions);
|
||||
}
|
||||
|
||||
function supplier_search()
|
||||
{
|
||||
$suggestions = $this->Supplier->get_suppliers_search_suggestions($this->input->post('q'),$this->input->post('limit'));
|
||||
echo implode("\n",$suggestions);
|
||||
}
|
||||
|
||||
function select_supplier()
|
||||
{
|
||||
$supplier_id = $this->input->post("supplier");
|
||||
$this->receiving_lib->set_supplier($supplier_id);
|
||||
$this->_reload();
|
||||
}
|
||||
|
||||
function change_mode()
|
||||
{
|
||||
$stock_destination = $this->input->post('stock_destination');
|
||||
$stock_source = $this->input->post("stock_source");
|
||||
if ((!$stock_source || $stock_source == $this->receiving_lib->get_stock_source()) &&
|
||||
(!$stock_destination || $stock_destination == $this->receiving_lib->get_stock_destination()))
|
||||
{
|
||||
$this->receiving_lib->clear_invoice_number();
|
||||
$mode = $this->input->post("mode");
|
||||
$this->receiving_lib->set_mode($mode);
|
||||
}
|
||||
else if ($this->Stock_location->is_allowed_location($stock_source, 'receivings'))
|
||||
{
|
||||
$this->receiving_lib->set_stock_source($stock_source);
|
||||
$this->receiving_lib->set_stock_destination($stock_destination);
|
||||
}
|
||||
$this->_reload();
|
||||
}
|
||||
|
||||
function set_comment()
|
||||
{
|
||||
$this->receiving_lib->set_comment($this->input->post('comment'));
|
||||
}
|
||||
|
||||
function set_invoice_number_enabled()
|
||||
{
|
||||
$this->receiving_lib->set_invoice_number_enabled($this->input->post('recv_invoice_number_enabled'));
|
||||
}
|
||||
|
||||
function set_print_after_sale()
|
||||
{
|
||||
$this->receiving_lib->set_print_after_sale($this->input->post('recv_print_after_sale'));
|
||||
}
|
||||
|
||||
function set_invoice_number()
|
||||
{
|
||||
$this->receiving_lib->set_invoice_number($this->input->post('recv_invoice_number'));
|
||||
}
|
||||
|
||||
function add()
|
||||
{
|
||||
$data=array();
|
||||
$mode = $this->receiving_lib->get_mode();
|
||||
$item_id_or_number_or_item_kit_or_receipt = $this->input->post("item");
|
||||
$quantity = ($mode=="receive" or $mode=="requisition") ? 1:-1;
|
||||
$item_location = $this->receiving_lib->get_stock_source();
|
||||
if($mode=='return' && $this->receiving_lib->is_valid_receipt($item_id_or_number_or_item_kit_or_receipt))
|
||||
{
|
||||
$this->receiving_lib->return_entire_receiving($item_id_or_number_or_item_kit_or_receipt);
|
||||
}
|
||||
elseif($this->receiving_lib->is_valid_item_kit($item_id_or_number_or_item_kit_or_receipt))
|
||||
{
|
||||
$this->receiving_lib->add_item_kit($item_id_or_number_or_item_kit_or_receipt,$item_location);
|
||||
}
|
||||
else
|
||||
{
|
||||
if(!$this->receiving_lib->add_item($item_id_or_number_or_item_kit_or_receipt,$quantity,$item_location))
|
||||
$data['error']=$this->lang->line('recvs_unable_to_add_item');
|
||||
}
|
||||
$this->_reload($data);
|
||||
}
|
||||
|
||||
function edit_item($item_id)
|
||||
{
|
||||
$data= array();
|
||||
|
||||
$this->form_validation->set_rules('price', 'lang:items_price', 'required|numeric');
|
||||
$this->form_validation->set_rules('quantity', 'lang:items_quantity', 'required|numeric');
|
||||
$this->form_validation->set_rules('discount', 'lang:items_discount', 'required|numeric');
|
||||
|
||||
$description = $this->input->post("description");
|
||||
$serialnumber = $this->input->post("serialnumber");
|
||||
$price = $this->input->post("price");
|
||||
$quantity = $this->input->post("quantity");
|
||||
$discount = $this->input->post("discount");
|
||||
$item_location = $this->input->post("location");
|
||||
|
||||
if ($this->form_validation->run() != FALSE)
|
||||
{
|
||||
$this->receiving_lib->edit_item($item_id,$description,$serialnumber,$quantity,$discount,$price);
|
||||
}
|
||||
else
|
||||
{
|
||||
$data['error']=$this->lang->line('recvs_error_editing_item');
|
||||
}
|
||||
|
||||
$this->_reload($data);
|
||||
}
|
||||
|
||||
function edit($receiving_id)
|
||||
{
|
||||
$data = array();
|
||||
|
||||
$data['suppliers'] = array('' => 'No Supplier');
|
||||
foreach ($this->Supplier->get_all()->result() as $supplier)
|
||||
{
|
||||
$data['suppliers'][$supplier->person_id] = $supplier->first_name . ' ' . $supplier->last_name;
|
||||
}
|
||||
|
||||
$data['employees'] = array();
|
||||
foreach ($this->Employee->get_all()->result() as $employee)
|
||||
{
|
||||
$data['employees'][$employee->person_id] = $employee->first_name . ' '. $employee->last_name;
|
||||
}
|
||||
|
||||
$receiving_info = $this->Receiving->get_info($receiving_id)->row_array();
|
||||
$person_name = $receiving_info['first_name'] . " " . $receiving_info['last_name'];
|
||||
$data['selected_supplier'] = !empty($receiving_info['supplier_id']) ? $receiving_info['supplier_id'] . "|" . $person_name : "";
|
||||
$data['receiving_info'] = $receiving_info;
|
||||
|
||||
$this->load->view('receivings/form', $data);
|
||||
}
|
||||
|
||||
function delete_item($item_number)
|
||||
{
|
||||
$this->receiving_lib->delete_item($item_number);
|
||||
$this->_reload();
|
||||
}
|
||||
|
||||
function delete($receiving_id = -1, $update_inventory=TRUE)
|
||||
{
|
||||
$employee_id=$this->Employee->get_logged_in_employee_info()->person_id;
|
||||
$receiving_ids=$receiving_id == -1 ? $this->input->post('ids') : array($receiving_id);
|
||||
|
||||
if($this->Receiving->delete_list($receiving_ids, $employee_id, $update_inventory))
|
||||
{
|
||||
echo json_encode(array('success'=>true,'message'=>$this->lang->line('recvs_successfully_deleted').' '.
|
||||
count($receiving_ids).' '.$this->lang->line('recvs_one_or_multiple'),'ids'=>$receiving_ids));
|
||||
}
|
||||
else
|
||||
{
|
||||
echo json_encode(array('success'=>false,'message'=>$this->lang->line('recvs_cannot_be_deleted')));
|
||||
}
|
||||
}
|
||||
|
||||
function delete_supplier()
|
||||
{
|
||||
$this->receiving_lib->clear_invoice_number();
|
||||
$this->receiving_lib->delete_supplier();
|
||||
$this->_reload();
|
||||
}
|
||||
|
||||
function complete()
|
||||
{
|
||||
$data['cart']=$this->receiving_lib->get_cart();
|
||||
$data['total']=$this->receiving_lib->get_total();
|
||||
$data['receipt_title']=$this->lang->line('recvs_receipt');
|
||||
$data['transaction_time']= date($this->config->item('dateformat').' '.$this->config->item('timeformat'));
|
||||
$data['mode']=$this->receiving_lib->get_mode();
|
||||
$data['show_stock_locations']=$this->Stock_location->show_locations('receivings');
|
||||
$supplier_id=$this->receiving_lib->get_supplier();
|
||||
$employee_id=$this->Employee->get_logged_in_employee_info()->person_id;
|
||||
$comment = $this->input->post('comment');
|
||||
$emp_info=$this->Employee->get_info($employee_id);
|
||||
$payment_type=$this->input->post('payment_type');
|
||||
$data['stock_location']=$this->receiving_lib->get_stock_source();
|
||||
if ($this->input->post('amount_tendered'))
|
||||
{
|
||||
$data['amount_tendered'] = $this->input->post('amount_tendered');
|
||||
$data['amount_change'] = to_currency($data['amount_tendered'] - round($data['total'], 2));
|
||||
}
|
||||
$data['employee']=$emp_info->first_name.' '.$emp_info->last_name;
|
||||
$suppl_info ='';
|
||||
if($supplier_id!=-1)
|
||||
{
|
||||
$suppl_info=$this->Supplier->get_info($supplier_id);
|
||||
$data['supplier']=$suppl_info->company_name; // first_name.' '.$suppl_info->last_name;
|
||||
}
|
||||
$invoice_number=$this->_substitute_invoice_number($suppl_info);
|
||||
if ($this->receiving_lib->is_invoice_number_enabled() && $this->Receiving->invoice_number_exists($invoice_number))
|
||||
{
|
||||
$data['error']=$this->lang->line('recvs_invoice_number_duplicate');
|
||||
$this->_reload($data);
|
||||
}
|
||||
else
|
||||
{
|
||||
$invoice_number = $this->receiving_lib->is_invoice_number_enabled() ? $invoice_number : NULL;
|
||||
$data['invoice_number']=$invoice_number;
|
||||
$data['payment_type']=$this->input->post('payment_type');
|
||||
//SAVE receiving to database
|
||||
$data['receiving_id']='RECV '.$this->Receiving->save($data['cart'], $supplier_id,$employee_id,$comment,$invoice_number,$payment_type,$data['stock_location']);
|
||||
|
||||
if ($data['receiving_id'] == 'RECV -1')
|
||||
{
|
||||
$data['error_message'] = $this->lang->line('receivings_transaction_failed');
|
||||
}
|
||||
$data['barcode']=$this->barcode_lib->generate_receipt_barcode($data['receiving_id']);
|
||||
$data['print_after_sale'] = $this->receiving_lib->is_print_after_sale();
|
||||
$this->load->view("receivings/receipt",$data);
|
||||
$this->receiving_lib->clear_all();
|
||||
}
|
||||
$this->_remove_duplicate_cookies();
|
||||
}
|
||||
|
||||
private function _substitute_variable($text, $variable, $object, $function)
|
||||
{
|
||||
// don't query if this variable isn't used
|
||||
if (strstr($text, $variable))
|
||||
{
|
||||
$value = call_user_func(array($object, $function));
|
||||
$text = str_replace($variable, $value, $text);
|
||||
}
|
||||
return $text;
|
||||
}
|
||||
|
||||
private function _substitute_variables($text,$supplier_info)
|
||||
{
|
||||
$text=$this->_substitute_variable($text, '$YCO', $this->Receiving, 'get_invoice_number_for_year');
|
||||
$text=$this->_substitute_variable($text, '$CO', $this->Receiving , 'get_invoice_count');
|
||||
$text=strftime($text);
|
||||
$text=$this->_substitute_supplier($text, $supplier_info);
|
||||
return $text;
|
||||
}
|
||||
|
||||
|
||||
private function _substitute_supplier($text,$supplier_info)
|
||||
{
|
||||
$supplier_id=$this->receiving_lib->get_supplier();
|
||||
if($supplier_id!=-1)
|
||||
{
|
||||
$text=str_replace('$SU',$supplier_info->company_name,$text);
|
||||
$words = preg_split("/\s+/", trim($supplier_info->company_name));
|
||||
$acronym = "";
|
||||
foreach ($words as $w) {
|
||||
$acronym .= $w[0];
|
||||
}
|
||||
$text=str_replace('$SI',$acronym,$text);
|
||||
}
|
||||
return $text;
|
||||
}
|
||||
|
||||
private function _substitute_invoice_number($supplier_info='')
|
||||
{
|
||||
$invoice_number=$this->receiving_lib->get_invoice_number();
|
||||
$invoice_number=$this->config->config['recv_invoice_format'];
|
||||
$invoice_number = $this->_substitute_variables($invoice_number,$supplier_info);
|
||||
$this->receiving_lib->set_invoice_number($invoice_number);
|
||||
return $this->receiving_lib->get_invoice_number();
|
||||
}
|
||||
|
||||
function requisition_complete()
|
||||
{
|
||||
if ($this->receiving_lib->get_stock_source() != $this->receiving_lib->get_stock_destination())
|
||||
{
|
||||
foreach($this->receiving_lib->get_cart() as $item)
|
||||
{
|
||||
$this->receiving_lib->delete_item($item['line']);
|
||||
$this->receiving_lib->add_item($item['item_id'],$item['quantity'],$this->receiving_lib->get_stock_destination());
|
||||
$this->receiving_lib->add_item($item['item_id'],-$item['quantity'],$this->receiving_lib->get_stock_source());
|
||||
}
|
||||
|
||||
$this->complete();
|
||||
}
|
||||
else
|
||||
{
|
||||
$data['error']=$this->lang->line('recvs_error_requisition');
|
||||
$this->_reload($data);
|
||||
}
|
||||
}
|
||||
|
||||
function receipt($receiving_id)
|
||||
{
|
||||
$receiving_info = $this->Receiving->get_info($receiving_id)->row_array();
|
||||
$this->receiving_lib->copy_entire_receiving($receiving_id);
|
||||
$data['cart']=$this->receiving_lib->get_cart();
|
||||
$data['total']=$this->receiving_lib->get_total();
|
||||
$data['mode']=$this->receiving_lib->get_mode();
|
||||
$data['receipt_title']=$this->lang->line('recvs_receipt');
|
||||
$data['transaction_time']= date($this->config->item('dateformat').' '.$this->config->item('timeformat'), strtotime($receiving_info['receiving_time']));
|
||||
$data['show_stock_locations']=$this->Stock_location->show_locations('receivings');
|
||||
$supplier_id=$this->receiving_lib->get_supplier();
|
||||
$emp_info=$this->Employee->get_info($receiving_info['employee_id']);
|
||||
$data['payment_type']=$receiving_info['payment_type'];
|
||||
$data['invoice_number']=$this->receiving_lib->get_invoice_number();
|
||||
$data['receiving_id']='RECV '.$receiving_id;
|
||||
$data['barcode']=$this->barcode_lib->generate_receipt_barcode($data['receiving_id']);
|
||||
$data['employee']=$emp_info->first_name.' '.$emp_info->last_name;
|
||||
|
||||
if($supplier_id!=-1)
|
||||
{
|
||||
$supplier_info=$this->Supplier->get_info($supplier_id);
|
||||
$data['supplier']=$supplier_info->first_name.' '.$supplier_info->last_name;
|
||||
}
|
||||
$data['print_after_sale'] = FALSE;
|
||||
$this->load->view("receivings/receipt",$data);
|
||||
$this->receiving_lib->clear_all();
|
||||
$this->_remove_duplicate_cookies();
|
||||
}
|
||||
|
||||
private function _reload($data=array())
|
||||
{
|
||||
$person_info = $this->Employee->get_logged_in_employee_info();
|
||||
$data['cart']=$this->receiving_lib->get_cart();
|
||||
$data['modes']=array('receive'=>$this->lang->line('recvs_receiving'),'return'=>$this->lang->line('recvs_return'));
|
||||
$data['mode']=$this->receiving_lib->get_mode();
|
||||
|
||||
$data['stock_locations']=$this->Stock_location->get_allowed_locations('receivings');
|
||||
$show_stock_locations = count($data['stock_locations']) > 1;
|
||||
if ($show_stock_locations)
|
||||
{
|
||||
$data['modes']['requisition']=$this->lang->line('recvs_requisition');
|
||||
$data['stock_source']=$this->receiving_lib->get_stock_source();
|
||||
$data['stock_destination']=$this->receiving_lib->get_stock_destination();
|
||||
}
|
||||
$data['show_stock_locations']=$show_stock_locations;
|
||||
|
||||
$data['total']=$this->receiving_lib->get_total();
|
||||
$data['items_module_allowed']=$this->Employee->has_grant('items',$person_info->person_id);
|
||||
$data['comment']=$this->receiving_lib->get_comment();
|
||||
$data['payment_options']=array(
|
||||
$this->lang->line('sales_cash') => $this->lang->line('sales_cash'),
|
||||
$this->lang->line('sales_check') => $this->lang->line('sales_check'),
|
||||
$this->lang->line('sales_debit') => $this->lang->line('sales_debit'),
|
||||
$this->lang->line('sales_credit') => $this->lang->line('sales_credit')
|
||||
);
|
||||
|
||||
$supplier_id=$this->receiving_lib->get_supplier();
|
||||
$suppl_info='';
|
||||
if($supplier_id!=-1)
|
||||
{
|
||||
$suppl_info=$this->Supplier->get_info($supplier_id);
|
||||
$data['supplier']=$suppl_info->company_name; // first_name.' '.$info->last_name;
|
||||
}
|
||||
$data['invoice_number']=$this->_substitute_invoice_number($suppl_info);
|
||||
$data['invoice_number_enabled']=$this->receiving_lib->is_invoice_number_enabled();
|
||||
$data['print_after_sale']=$this->receiving_lib->is_print_after_sale();
|
||||
$this->load->view("receivings/receiving",$data);
|
||||
$this->_remove_duplicate_cookies();
|
||||
}
|
||||
|
||||
function save($receiving_id)
|
||||
{
|
||||
$date_formatter = date_create_from_format($this->config->item('dateformat') . ' ' . $this->config->item('timeformat'), $this->input->post('date', TRUE));
|
||||
|
||||
$receiving_data = array(
|
||||
'receiving_time' => $date_formatter->format('Y-m-d H:i:s'),
|
||||
'supplier_id' => $this->input->post('supplier_id') ? $this->input->post('supplier_id') : null,
|
||||
'employee_id' => $this->input->post('employee_id'),
|
||||
'comment' => $this->input->post('comment'),
|
||||
'invoice_number' => $this->input->post('invoice_number') != '' ? $this->input->post('invoice_number') : null
|
||||
);
|
||||
|
||||
if ($this->Receiving->update($receiving_data, $receiving_id))
|
||||
{
|
||||
echo json_encode(array(
|
||||
'success'=>true,
|
||||
'message'=>$this->lang->line('recvs_successfully_updated'),
|
||||
'id'=>$receiving_id)
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
echo json_encode(array(
|
||||
'success'=>false,
|
||||
'message'=>$this->lang->line('recvs_unsuccessfully_updated'),
|
||||
'id'=>$receiving_id)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
function cancel_receiving()
|
||||
{
|
||||
$this->receiving_lib->clear_all();
|
||||
$this->_reload();
|
||||
}
|
||||
|
||||
function check_invoice_number()
|
||||
{
|
||||
$receiving_id=$this->input->post('receiving_id');
|
||||
$invoice_number=$this->input->post('invoice_number');
|
||||
$exists=!empty($invoice_number) && $this->Receiving->invoice_number_exists($invoice_number,$receiving_id);
|
||||
echo json_encode(array('success'=>!$exists,'message'=>$this->lang->line('recvs_invoice_number_duplicate')));
|
||||
}
|
||||
}
|
||||
?>
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,848 +0,0 @@
|
||||
<?php
|
||||
require_once ("secure_area.php");
|
||||
class Sales extends Secure_area
|
||||
{
|
||||
function __construct()
|
||||
{
|
||||
parent::__construct('sales');
|
||||
$this->load->library('sale_lib');
|
||||
$this->load->library('barcode_lib');
|
||||
}
|
||||
|
||||
function index()
|
||||
{
|
||||
$this->_reload();
|
||||
}
|
||||
|
||||
function manage($only_invoices = FALSE, $only_cash = FALSE, $limit_from = 0)
|
||||
{
|
||||
$person_id = $this->session->userdata('person_id');
|
||||
|
||||
if (!$this->Employee->has_grant('reports_sales', $person_id))
|
||||
{
|
||||
redirect('no_access/sales/reports_sales');
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->Sale->create_sales_items_temp_table();
|
||||
|
||||
$data['controller_name'] = strtolower($this->uri->segment(1));
|
||||
$data['only_invoices'] = array($this->lang->line('sales_no_filter'), $this->lang->line('sales_invoice'));
|
||||
$data['search_section_state'] = $this->input->post('search_section_state');
|
||||
$lines_per_page = $this->Appconfig->get('lines_per_page');
|
||||
|
||||
$today = date($this->config->item('dateformat'));
|
||||
$start_date = $this->input->post('start_date') != NULL ? $this->input->post('start_date', TRUE) : $today;
|
||||
$start_date_formatter = date_create_from_format($this->config->item('dateformat'), $start_date);
|
||||
$end_date = $this->input->post('end_date') != NULL ? $this->input->post('end_date', TRUE) : $today;
|
||||
$end_date_formatter = date_create_from_format($this->config->item('dateformat'), $end_date);
|
||||
|
||||
$sale_type = 'all';
|
||||
$location_id = 'all';
|
||||
$is_valid_receipt = FALSE;
|
||||
$search = null;
|
||||
|
||||
$filters = array('sale_type' => $sale_type,
|
||||
'location_id' => $location_id,
|
||||
'start_date' => $start_date_formatter->format('Y-m-d'),
|
||||
'end_date' => $end_date_formatter->format('Y-m-d'),
|
||||
'only_invoices' => $only_invoices,
|
||||
'only_cash' => $only_cash,
|
||||
'is_valid_receipt' => $is_valid_receipt);
|
||||
|
||||
$sales = $this->Sale->search($search, $filters, $lines_per_page, $limit_from)->result_array();
|
||||
$payments = $this->Sale->get_payments_summary($search, $filters);
|
||||
$total_rows = $this->Sale->get_found_rows($search, $filters);
|
||||
$data['only_invoices'] = $only_invoices;
|
||||
$data['start_date'] = $start_date_formatter->format($this->config->item('dateformat'));
|
||||
$data['end_date'] = $end_date_formatter->format($this->config->item('dateformat'));
|
||||
$data['links'] = $this->_initialize_pagination($this->Sale, $lines_per_page, $limit_from, $total_rows, 'manage', $only_invoices);
|
||||
$data['manage_table'] = get_sales_manage_table($sales, $this);
|
||||
$data['payments_summary'] = get_sales_manage_payments_summary($payments, $sales, $this);
|
||||
|
||||
$this->load->view($data['controller_name'] . '/manage', $data);
|
||||
}
|
||||
|
||||
$this->_remove_duplicate_cookies();
|
||||
}
|
||||
|
||||
function get_row()
|
||||
{
|
||||
$this->Sale->create_sales_items_temp_table();
|
||||
|
||||
$sale_id = $this->input->post('row_id');
|
||||
$sale_info = $this->Sale->get_info($sale_id)->result_array();
|
||||
$data_row = get_sales_manage_sale_data_row($sale_info[0], $this);
|
||||
|
||||
echo $data_row;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* Get the width for the add/edit form.
|
||||
* @return number The form width
|
||||
*/
|
||||
function get_form_width()
|
||||
{
|
||||
return 400;
|
||||
}
|
||||
|
||||
function search()
|
||||
{
|
||||
$this->Sale->create_sales_items_temp_table();
|
||||
|
||||
$only_invoices = $this->input->post('only_invoices', TRUE);
|
||||
$only_cash = $this->input->post('only_cash', TRUE);
|
||||
$lines_per_page = $this->Appconfig->get('lines_per_page');
|
||||
$limit_from = $this->input->post('limit_from', TRUE);
|
||||
$search = $this->input->post('search', TRUE);
|
||||
|
||||
$today = date($this->config->item('dateformat'));
|
||||
$start_date = $this->input->post('start_date') != NULL ? $this->input->post('start_date', TRUE) : $today;
|
||||
$start_date_formatter = date_create_from_format($this->config->item('dateformat'), $start_date);
|
||||
$end_date = $this->input->post('end_date') != NULL ? $this->input->post('end_date', TRUE) : $today;
|
||||
$end_date_formatter = date_create_from_format($this->config->item('dateformat'), $end_date);
|
||||
|
||||
$is_valid_receipt = isset($search) ? $this->sale_lib->is_valid_receipt($search) : FALSE;
|
||||
|
||||
$sale_type = 'all';
|
||||
$location_id = 'all';
|
||||
|
||||
$filters = array('sale_type' => $sale_type,
|
||||
'location_id' => $location_id,
|
||||
'start_date' => $start_date_formatter->format('Y-m-d'),
|
||||
'end_date' => $end_date_formatter->format('Y-m-d'),
|
||||
'only_invoices' => $only_invoices,
|
||||
'only_cash' => $only_cash,
|
||||
'is_valid_receipt' => $is_valid_receipt);
|
||||
|
||||
$sales = $this->Sale->search($search, $filters, $lines_per_page, $limit_from)->result_array();
|
||||
$payments = $this->Sale->get_payments_summary($search, $filters);
|
||||
$total_rows = $this->Sale->get_found_rows($search, $filters);
|
||||
$links = $this->_initialize_pagination($this->Sale, $lines_per_page, $limit_from, $total_rows, 'search', $only_invoices);
|
||||
$sale_rows = get_sales_manage_table_data_rows($sales, $this);
|
||||
$payment_summary = get_sales_manage_payments_summary($payments, $sales, $this);
|
||||
$this->_remove_duplicate_cookies();
|
||||
|
||||
echo json_encode(array('total_rows' => $total_rows, 'rows' => $sale_rows, 'pagination' => $links, 'payment_summary' => $payment_summary));
|
||||
}
|
||||
|
||||
function item_search()
|
||||
{
|
||||
$suggestions = array();
|
||||
|
||||
if ($this->sale_lib->get_mode() == 'return')
|
||||
{
|
||||
$this->sale_lib->is_valid_receipt($this->input->post('q')) && $suggestions[] = $this->input->post('q');
|
||||
}
|
||||
$suggestions = array_merge($suggestions, $this->Item->get_item_search_suggestions($this->input->post('q'),$this->input->post('limit')));
|
||||
$suggestions = array_merge($suggestions, $this->Item_kit->get_item_kit_search_suggestions($this->input->post('q'),$this->input->post('limit')));
|
||||
|
||||
echo implode("\n", $suggestions);
|
||||
}
|
||||
|
||||
function customer_search()
|
||||
{
|
||||
$suggestions = $this->Customer->get_customer_search_suggestions($this->input->post('q'),$this->input->post('limit'));
|
||||
|
||||
echo implode("\n",$suggestions);
|
||||
}
|
||||
|
||||
function suggest()
|
||||
{
|
||||
$search = $this->input->post('q', TRUE);
|
||||
$limit = $this->input->post('limit', TRUE);
|
||||
$suggestions = $this->Sale->get_search_suggestions($search, $limit);
|
||||
|
||||
echo implode("\n",$suggestions);
|
||||
}
|
||||
|
||||
function select_customer()
|
||||
{
|
||||
$customer_id = $this->input->post("customer");
|
||||
$this->sale_lib->set_customer($customer_id);
|
||||
$this->_reload();
|
||||
}
|
||||
|
||||
function change_mode()
|
||||
{
|
||||
$stock_location = $this->input->post("stock_location");
|
||||
if (!$stock_location || $stock_location == $this->sale_lib->get_sale_location())
|
||||
{
|
||||
$mode = $this->input->post("mode");
|
||||
$this->sale_lib->set_mode($mode);
|
||||
}
|
||||
else if ($this->Stock_location->is_allowed_location($stock_location, 'sales'))
|
||||
{
|
||||
$this->sale_lib->set_sale_location($stock_location);
|
||||
}
|
||||
$this->_reload();
|
||||
}
|
||||
|
||||
function set_comment()
|
||||
{
|
||||
$this->sale_lib->set_comment($this->input->post('comment'));
|
||||
}
|
||||
|
||||
function set_invoice_number()
|
||||
{
|
||||
$this->sale_lib->set_invoice_number($this->input->post('sales_invoice_number'));
|
||||
}
|
||||
|
||||
function set_invoice_number_enabled()
|
||||
{
|
||||
$this->sale_lib->set_invoice_number_enabled($this->input->post('sales_invoice_number_enabled'));
|
||||
}
|
||||
|
||||
function set_print_after_sale()
|
||||
{
|
||||
$this->sale_lib->set_print_after_sale($this->input->post('sales_print_after_sale'));
|
||||
}
|
||||
|
||||
function set_email_receipt()
|
||||
{
|
||||
$this->sale_lib->set_email_receipt($this->input->post('email_receipt'));
|
||||
}
|
||||
|
||||
// Multiple Payments
|
||||
function add_payment()
|
||||
{
|
||||
$data = array();
|
||||
$this->form_validation->set_rules( 'amount_tendered', 'lang:sales_amount_tendered', 'trim|required|numeric' );
|
||||
|
||||
if ( $this->form_validation->run() == FALSE )
|
||||
{
|
||||
if ( $this->input->post( 'payment_type' ) == $this->lang->line( 'sales_gift_card' ) )
|
||||
{
|
||||
$data['error']=$this->lang->line('sales_must_enter_numeric_giftcard');
|
||||
}
|
||||
else
|
||||
{
|
||||
$data['error']=$this->lang->line('sales_must_enter_numeric');
|
||||
}
|
||||
|
||||
$this->_reload( $data );
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
$payment_type = $this->input->post( 'payment_type' );
|
||||
if ( $payment_type == $this->lang->line( 'sales_giftcard' ) )
|
||||
{
|
||||
$payments = $this->sale_lib->get_payments();
|
||||
$payment_type = $this->input->post( 'payment_type' ) . ':' . $payment_amount = $this->input->post( 'amount_tendered' );
|
||||
$current_payments_with_giftcard = isset( $payments[$payment_type] ) ? $payments[$payment_type]['payment_amount'] : 0;
|
||||
$cur_giftcard_value = $this->Giftcard->get_giftcard_value( $this->input->post( 'amount_tendered' ) ) - $current_payments_with_giftcard;
|
||||
|
||||
if ( $cur_giftcard_value <= 0 )
|
||||
{
|
||||
$data['error'] = $this->lang->line('giftcards_remaining_balance', $this->input->post( 'amount_tendered' ), to_currency( $this->Giftcard->get_giftcard_value( $this->input->post( 'amount_tendered' ))));
|
||||
$this->_reload( $data );
|
||||
return;
|
||||
}
|
||||
$new_giftcard_value = $this->Giftcard->get_giftcard_value( $this->input->post( 'amount_tendered' ) ) - $this->sale_lib->get_amount_due( );
|
||||
$new_giftcard_value = ( $new_giftcard_value >= 0 ) ? $new_giftcard_value : 0;
|
||||
$this->sale_lib->set_giftcard_remainder($new_giftcard_value);
|
||||
$data['warning'] = $this->lang->line('giftcards_remaining_balance', $this->input->post( 'amount_tendered' ), to_currency( $new_giftcard_value, TRUE ));
|
||||
$payment_amount = min( $this->sale_lib->get_amount_due( ), $this->Giftcard->get_giftcard_value( $this->input->post( 'amount_tendered' ) ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
$payment_amount = $this->input->post( 'amount_tendered' );
|
||||
}
|
||||
|
||||
if( !$this->sale_lib->add_payment( $payment_type, $payment_amount ) )
|
||||
{
|
||||
$data['error']='Unable to Add Payment! Please try again!';
|
||||
}
|
||||
|
||||
$this->_reload($data);
|
||||
}
|
||||
|
||||
// Multiple Payments
|
||||
function delete_payment( $payment_id )
|
||||
{
|
||||
$this->sale_lib->delete_payment( $payment_id );
|
||||
$this->_reload();
|
||||
}
|
||||
|
||||
function add()
|
||||
{
|
||||
$data=array();
|
||||
$mode = $this->sale_lib->get_mode();
|
||||
$item_id_or_number_or_item_kit_or_receipt = $this->input->post("item");
|
||||
$quantity = ($mode=="return")? -1:1;
|
||||
$item_location = $this->sale_lib->get_sale_location();
|
||||
|
||||
if($mode == 'return' && $this->sale_lib->is_valid_receipt($item_id_or_number_or_item_kit_or_receipt))
|
||||
{
|
||||
$this->sale_lib->return_entire_sale($item_id_or_number_or_item_kit_or_receipt);
|
||||
}
|
||||
else if($this->sale_lib->is_valid_item_kit($item_id_or_number_or_item_kit_or_receipt))
|
||||
{
|
||||
$this->sale_lib->add_item_kit($item_id_or_number_or_item_kit_or_receipt,$item_location);
|
||||
}
|
||||
else if(!$this->sale_lib->add_item($item_id_or_number_or_item_kit_or_receipt,$quantity,$item_location,$this->config->item('default_sales_discount')))
|
||||
{
|
||||
$data['error']=$this->lang->line('sales_unable_to_add_item');
|
||||
}
|
||||
|
||||
if($this->sale_lib->out_of_stock($item_id_or_number_or_item_kit_or_receipt,$item_location))
|
||||
{
|
||||
$data['warning'] = $this->lang->line('sales_quantity_less_than_zero');
|
||||
}
|
||||
$this->_reload($data);
|
||||
}
|
||||
|
||||
function edit_item($line)
|
||||
{
|
||||
$data = array();
|
||||
|
||||
$this->form_validation->set_rules('price', 'lang:items_price', 'required|numeric');
|
||||
$this->form_validation->set_rules('quantity', 'lang:items_quantity', 'required|numeric');
|
||||
$this->form_validation->set_rules('discount', 'lang:items_discount', 'required|numeric');
|
||||
|
||||
$description = $this->input->post("description");
|
||||
$serialnumber = $this->input->post("serialnumber");
|
||||
$price = $this->input->post("price");
|
||||
$quantity = $this->input->post("quantity");
|
||||
$discount = $this->input->post("discount");
|
||||
$item_location = $this->input->post("location");
|
||||
|
||||
if ($this->form_validation->run() != FALSE)
|
||||
{
|
||||
$this->sale_lib->edit_item($line, $description, $serialnumber, $quantity, $discount, $price);
|
||||
}
|
||||
else
|
||||
{
|
||||
$data['error'] = $this->lang->line('sales_error_editing_item');
|
||||
}
|
||||
|
||||
if($this->sale_lib->out_of_stock($this->sale_lib->get_item_id($line),$item_location))
|
||||
{
|
||||
$data['warning'] = $this->lang->line('sales_quantity_less_than_zero');
|
||||
}
|
||||
|
||||
$this->_reload($data);
|
||||
}
|
||||
|
||||
function delete_item($item_number)
|
||||
{
|
||||
$this->sale_lib->delete_item($item_number);
|
||||
$this->_reload();
|
||||
}
|
||||
|
||||
function remove_customer()
|
||||
{
|
||||
$this->sale_lib->clear_giftcard_remainder();
|
||||
$this->sale_lib->clear_invoice_number();
|
||||
$this->sale_lib->remove_customer();
|
||||
$this->_reload();
|
||||
}
|
||||
|
||||
function complete()
|
||||
{
|
||||
$data['cart'] = $this->sale_lib->get_cart();
|
||||
$data['subtotal'] = $this->sale_lib->get_subtotal();
|
||||
$data['discounted_subtotal'] = $this->sale_lib->get_subtotal(TRUE);
|
||||
$data['tax_exclusive_subtotal'] = $this->sale_lib->get_subtotal(TRUE, TRUE);
|
||||
$data['taxes'] = $this->sale_lib->get_taxes();
|
||||
$data['total'] = $this->sale_lib->get_total();
|
||||
$data['discount'] = $this->sale_lib->get_discount();
|
||||
$data['receipt_title'] = $this->lang->line('sales_receipt');
|
||||
$data['transaction_time'] = date($this->config->item('dateformat').' '.$this->config->item('timeformat'));
|
||||
$data['transaction_date'] = date($this->config->item('dateformat'));
|
||||
$data['show_stock_locations'] = $this->Stock_location->show_locations('sales');
|
||||
$customer_id = $this->sale_lib->get_customer();
|
||||
$employee_id = $this->Employee->get_logged_in_employee_info()->person_id;
|
||||
$data['comments'] = $this->sale_lib->get_comment();
|
||||
$emp_info=$this->Employee->get_info($employee_id);
|
||||
$data['payments'] = $this->sale_lib->get_payments();
|
||||
$data['amount_change'] = $this->sale_lib->get_amount_due() * -1;
|
||||
$data['amount_due'] = $this->sale_lib->get_amount_due();
|
||||
$data['employee'] = $emp_info->first_name.' '.$emp_info->last_name;
|
||||
$data['company_info'] = implode("\n", array(
|
||||
$this->config->item('address'),
|
||||
$this->config->item('phone'),
|
||||
$this->config->item('account_number')
|
||||
));
|
||||
$cust_info = '';
|
||||
if($customer_id!=-1)
|
||||
{
|
||||
$cust_info = $this->Customer->get_info($customer_id);
|
||||
if (isset($cust_info->company_name))
|
||||
{
|
||||
$data['customer'] = $cust_info->company_name;
|
||||
}
|
||||
else
|
||||
{
|
||||
$data['customer'] = $cust_info->first_name.' '.$cust_info->last_name;
|
||||
}
|
||||
$data['customer_address'] = $cust_info->address_1;
|
||||
$data['customer_location'] = $cust_info->zip . ' ' . $cust_info->city;
|
||||
$data['account_number'] = $cust_info->account_number;
|
||||
$data['customer_info'] = implode("\n", array(
|
||||
$data['customer'],
|
||||
$data['customer_address'],
|
||||
$data['customer_location'],
|
||||
$data['account_number']
|
||||
));
|
||||
}
|
||||
$invoice_number = $this->_substitute_invoice_number($cust_info);
|
||||
if ($this->sale_lib->is_invoice_number_enabled() && $this->Sale->invoice_number_exists($invoice_number))
|
||||
{
|
||||
$data['error'] = $this->lang->line('sales_invoice_number_duplicate');
|
||||
$this->_reload($data);
|
||||
}
|
||||
else
|
||||
{
|
||||
$invoice_number = $this->sale_lib->is_invoice_number_enabled() ? $invoice_number : NULL;
|
||||
$data['invoice_number'] = $invoice_number;
|
||||
$data['sale_id'] = 'POS '.$this->Sale->save($data['cart'], $customer_id, $employee_id, $data['comments'], $invoice_number, $data['payments']);
|
||||
if ($data['sale_id'] == 'POS -1')
|
||||
{
|
||||
$data['error_message'] = $this->lang->line('sales_transaction_failed');
|
||||
}
|
||||
else
|
||||
{
|
||||
$data['barcode'] = $this->barcode_lib->generate_receipt_barcode($data['sale_id']);
|
||||
// if we want to email. .. just attach the pdf in there?
|
||||
if ($this->sale_lib->get_email_receipt() && !empty($cust_info->email))
|
||||
{
|
||||
$this->load->library('email');
|
||||
$config['mailtype'] = 'html';
|
||||
$this->email->initialize($config);
|
||||
$this->email->from($this->config->item('email'), $this->config->item('company'));
|
||||
$this->email->to($cust_info->email);
|
||||
|
||||
$this->email->subject($this->lang->line('sales_receipt'));
|
||||
if ($this->config->item('use_invoice_template') && $this->sale_lib->is_invoice_number_enabled())
|
||||
{
|
||||
$data['image_prefix']="";
|
||||
$filename = $this->_invoice_email_pdf($data);
|
||||
$this->email->attach($filename);
|
||||
$text = $this->config->item('invoice_email_message');
|
||||
$text = str_replace('$INV', $invoice_number, $text);
|
||||
$text = str_replace('$CO', $data['sale_id'], $text);
|
||||
$text = $this->_substitute_customer($text, $cust_info);
|
||||
$this->email->message($text);
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->email->message($this->load->view("sales/receipt_email",$data, true));
|
||||
}
|
||||
$this->email->send();
|
||||
}
|
||||
}
|
||||
$data['cur_giftcard_value'] = $this->sale_lib->get_giftcard_remainder();
|
||||
$data['print_after_sale'] = $this->sale_lib->is_print_after_sale();
|
||||
if ($this->sale_lib->is_invoice_number_enabled() && $this->config->item('use_invoice_template'))
|
||||
{
|
||||
$this->load->view("sales/invoice",$data);
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->load->view("sales/receipt",$data);
|
||||
}
|
||||
$this->sale_lib->clear_all();
|
||||
}
|
||||
|
||||
$this->_remove_duplicate_cookies();
|
||||
}
|
||||
|
||||
private function _invoice_email_pdf($data)
|
||||
{
|
||||
$data['image_prefix'] = "";
|
||||
$html = $this->load->view('sales/invoice_email', $data, true);
|
||||
// load pdf helper
|
||||
$this->load->helper(array('dompdf', 'file'));
|
||||
$file_content = pdf_create($html, '', false);
|
||||
$filename = sys_get_temp_dir() . '/'. $this->lang->line('sales_invoice') .'-' . str_replace('/', '-' , $data["invoice_number"]) . '.pdf';
|
||||
write_file($filename, $file_content);
|
||||
|
||||
return $filename;
|
||||
}
|
||||
|
||||
function invoice_email($sale_id)
|
||||
{
|
||||
$sale_data = $this->_load_sale_data($sale_id);
|
||||
$sale_data['image_prefix'] = base_url();
|
||||
$this->load->view('sales/invoice_email', $sale_data);
|
||||
$this->sale_lib->clear_all();
|
||||
$this->_remove_duplicate_cookies();
|
||||
}
|
||||
|
||||
function send_invoice($sale_id)
|
||||
{
|
||||
$sale_data = $this->_load_sale_data($sale_id);
|
||||
$text = $this->config->item('invoice_email_message');
|
||||
$text = str_replace('$INV', $sale_data['invoice_number'], $text);
|
||||
$text = str_replace('$CO', 'POS ' . $sale_data['sale_id'], $text);
|
||||
$text = $this->_substitute_customer($text,(object) $sale_data);
|
||||
$result = FALSE;
|
||||
$message = $this->lang->line('sales_invoice_no_email');
|
||||
if (isset($sale_data["customer_email"]) && !empty( $sale_data["customer_email"])) {
|
||||
$this->load->library('email');
|
||||
$this->email->from($this->config->item('email'), $this->config->item('company'));
|
||||
$this->email->to($sale_data['customer_email']);
|
||||
$this->email->subject($this->lang->line('sales_invoice') . ' ' . $sale_data['invoice_number']);
|
||||
$this->email->message($text);
|
||||
$filename = $this->_invoice_email_pdf($sale_data);
|
||||
$this->email->attach($filename);
|
||||
$result = $this->email->send();
|
||||
$message = $this->lang->line($result ? 'sales_invoice_sent' : 'sales_invoice_unsent') . ' ' . $sale_data["customer_email"];
|
||||
}
|
||||
echo json_encode(array(
|
||||
'success'=>$result,
|
||||
'message'=>$message,
|
||||
'id'=>$sale_id)
|
||||
);
|
||||
$this->sale_lib->clear_all();
|
||||
$this->_remove_duplicate_cookies();
|
||||
}
|
||||
|
||||
private function _substitute_variable($text, $variable, $object, $function)
|
||||
{
|
||||
// don't query if this variable isn't used
|
||||
if (strstr($text, $variable))
|
||||
{
|
||||
$value = call_user_func(array($object, $function));
|
||||
$text = str_replace($variable, $value, $text);
|
||||
}
|
||||
|
||||
return $text;
|
||||
}
|
||||
|
||||
private function _substitute_customer($text, $cust_info)
|
||||
{
|
||||
// substitute customer info
|
||||
$customer_id=$this->sale_lib->get_customer();
|
||||
if($customer_id!=-1 && $cust_info!='')
|
||||
{
|
||||
$text=str_replace('$CU',$cust_info->first_name . ' ' . $cust_info->last_name,$text);
|
||||
$words = preg_split("/\s+/", trim($cust_info->first_name . ' ' . $cust_info->last_name));
|
||||
$acronym = "";
|
||||
foreach ($words as $w) {
|
||||
$acronym .= $w[0];
|
||||
}
|
||||
$text=str_replace('$CI',$acronym,$text);
|
||||
}
|
||||
|
||||
return $text;
|
||||
}
|
||||
|
||||
private function _substitute_variables($text, $cust_info)
|
||||
{
|
||||
$text=$this->_substitute_variable($text, '$YCO', $this->Sale, 'get_invoice_number_for_year');
|
||||
$text=$this->_substitute_variable($text, '$CO', $this->Sale , 'get_invoice_count');
|
||||
$text=$this->_substitute_variable($text, '$SCO', $this->Sale_suspended, 'get_invoice_count');
|
||||
$text=strftime($text);
|
||||
$text=$this->_substitute_customer($text, $cust_info);
|
||||
|
||||
return $text;
|
||||
}
|
||||
|
||||
private function _substitute_invoice_number($cust_info)
|
||||
{
|
||||
$invoice_number = $this->config->config['sales_invoice_format'];
|
||||
$invoice_number = $this->_substitute_variables($invoice_number, $cust_info);
|
||||
$this->sale_lib->set_invoice_number($invoice_number, TRUE);
|
||||
return $this->sale_lib->get_invoice_number();
|
||||
}
|
||||
|
||||
private function _load_sale_data($sale_id)
|
||||
{
|
||||
$this->Sale->create_sales_items_temp_table();
|
||||
|
||||
$this->sale_lib->clear_all();
|
||||
$sale_info = $this->Sale->get_info($sale_id)->row_array();
|
||||
$this->sale_lib->copy_entire_sale($sale_id);
|
||||
$data['cart'] = $this->sale_lib->get_cart();
|
||||
$data['payments'] = $this->sale_lib->get_payments();
|
||||
$data['subtotal'] = $this->sale_lib->get_subtotal();
|
||||
$data['discounted_subtotal'] = $this->sale_lib->get_subtotal(TRUE);
|
||||
$data['tax_exclusive_subtotal'] = $this->sale_lib->get_subtotal(TRUE, TRUE);
|
||||
$data['taxes'] = $this->sale_lib->get_taxes();
|
||||
$data['total'] = $this->sale_lib->get_total();
|
||||
$data['discount'] = $this->sale_lib->get_discount();
|
||||
$data['receipt_title'] = $this->lang->line('sales_receipt');
|
||||
$data['transaction_time'] = date($this->config->item('dateformat').' '.$this->config->item('timeformat'), strtotime($sale_info['sale_time']));
|
||||
$data['transaction_date'] = date($this->config->item('dateformat'), strtotime($sale_info['sale_time']));
|
||||
$data['show_stock_locations'] = $this->Stock_location->show_locations('sales');
|
||||
$customer_id = $this->sale_lib->get_customer();
|
||||
$employee_id = $this->Employee->get_logged_in_employee_info()->person_id;
|
||||
$emp_info = $this->Employee->get_info($employee_id);
|
||||
$data['amount_change'] = $this->sale_lib->get_amount_due() * -1;
|
||||
$data['amount_due'] = $this->sale_lib->get_amount_due();
|
||||
$data['employee'] = $emp_info->first_name.' '.$emp_info->last_name;
|
||||
|
||||
if($customer_id!=-1)
|
||||
{
|
||||
$cust_info = $this->Customer->get_info($customer_id);
|
||||
if (isset($cust_info->company_name))
|
||||
{
|
||||
$data['customer'] = $cust_info->company_name;
|
||||
}
|
||||
else
|
||||
{
|
||||
$data['customer'] = $cust_info->first_name.' '.$cust_info->last_name;
|
||||
}
|
||||
$data['first_name'] = $cust_info->first_name;
|
||||
$data['last_name'] = $cust_info->last_name;
|
||||
$data['customer_address'] = $cust_info->address_1;
|
||||
$data['customer_location'] = $cust_info->zip . ' ' . $cust_info->city;
|
||||
$data['customer_email'] = $cust_info->email;
|
||||
$data['account_number'] = $cust_info->account_number;
|
||||
$data['customer_info'] = implode("\n", array(
|
||||
$data['customer'],
|
||||
$data['customer_address'],
|
||||
$data['customer_location'],
|
||||
$data['account_number']
|
||||
));
|
||||
}
|
||||
$data['sale_id'] = 'POS '.$sale_id;
|
||||
$data['comments'] = $sale_info['comment'];
|
||||
$data['invoice_number'] = $sale_info['invoice_number'];
|
||||
$data['company_info'] = implode("\n", array(
|
||||
$this->config->item('address'),
|
||||
$this->config->item('phone'),
|
||||
$this->config->item('account_number')
|
||||
));
|
||||
$data['barcode'] = $this->barcode_lib->generate_receipt_barcode($data['sale_id']);
|
||||
$data['print_after_sale'] = FALSE;
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
function receipt($sale_id)
|
||||
{
|
||||
$data = $this->_load_sale_data($sale_id);
|
||||
$this->load->view("sales/receipt",$data);
|
||||
$this->sale_lib->clear_all();
|
||||
$this->_remove_duplicate_cookies();
|
||||
}
|
||||
|
||||
function invoice($sale_id, $sale_info='')
|
||||
{
|
||||
if ($sale_info == '') {
|
||||
$sale_info = $this->_load_sale_data($sale_id);
|
||||
}
|
||||
$this->load->view("sales/invoice",$sale_info);
|
||||
$this->sale_lib->clear_all();
|
||||
$this->_remove_duplicate_cookies();
|
||||
}
|
||||
|
||||
function edit($sale_id)
|
||||
{
|
||||
$data = array();
|
||||
|
||||
$data['employees'] = array();
|
||||
foreach ($this->Employee->get_all()->result() as $employee)
|
||||
{
|
||||
$data['employees'][$employee->person_id] = $employee->first_name . ' '. $employee->last_name;
|
||||
}
|
||||
$this->Sale->create_sales_items_temp_table();
|
||||
|
||||
$sale_info = $this->Sale->get_info($sale_id)->row_array();
|
||||
$person_name = $sale_info['first_name'] . " " . $sale_info['last_name'];
|
||||
$data['selected_customer'] = !empty($sale_info['customer_id']) ? $sale_info['customer_id'] . "|" . $person_name : "";
|
||||
$data['sale_info'] = $sale_info;
|
||||
|
||||
$this->load->view('sales/form', $data);
|
||||
}
|
||||
|
||||
function delete($sale_id = -1, $update_inventory=TRUE)
|
||||
{
|
||||
$employee_id=$this->Employee->get_logged_in_employee_info()->person_id;
|
||||
$sale_ids= $sale_id == -1 ? $this->input->post('ids') : array($sale_id);
|
||||
|
||||
if($this->Sale->delete_list($sale_ids, $employee_id, $update_inventory))
|
||||
{
|
||||
echo json_encode(array('success'=>true,'message'=>$this->lang->line('sales_successfully_deleted').' '.
|
||||
count($sale_ids).' '.$this->lang->line('sales_one_or_multiple'),'ids'=>$sale_ids));
|
||||
}
|
||||
else
|
||||
{
|
||||
echo json_encode(array('success'=>false,'message'=>$this->lang->line('sales_unsuccessfully_deleted')));
|
||||
}
|
||||
}
|
||||
|
||||
function save($sale_id)
|
||||
{
|
||||
$start_date_formatter = date_create_from_format($this->config->item('dateformat') . ' ' . $this->config->item('timeformat'), $this->input->post('date', TRUE));
|
||||
|
||||
$sale_data = array(
|
||||
'sale_time' => $start_date_formatter->format('Y-m-d H:i:s'),
|
||||
'customer_id' => $this->input->post('customer_id') ? $this->input->post('customer_id') : NULL,
|
||||
'employee_id' => $this->input->post('employee_id'),
|
||||
'comment' => $this->input->post('comment'),
|
||||
'invoice_number' => $this->input->post('invoice_number') ? $this->input->post('invoice_number') : NULL
|
||||
);
|
||||
|
||||
if ($this->Sale->update($sale_data, $sale_id))
|
||||
{
|
||||
echo json_encode(array(
|
||||
'success'=>true,
|
||||
'message'=>$this->lang->line('sales_successfully_updated'),
|
||||
'id'=>$sale_id)
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
echo json_encode(array(
|
||||
'success'=>false,
|
||||
'message'=>$this->lang->line('sales_unsuccessfully_updated'),
|
||||
'id'=>$sale_id)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
private function _payments_cover_total()
|
||||
{
|
||||
$total_payments = 0;
|
||||
|
||||
foreach($this->sale_lib->get_payments() as $payment)
|
||||
{
|
||||
$total_payments += $payment['payment_amount'];
|
||||
}
|
||||
|
||||
/* Changed the conditional to account for floating point rounding */
|
||||
if ( ($this->sale_lib->get_mode() == 'sale') &&
|
||||
( ( to_currency_no_money( $this->sale_lib->get_total() ) - $total_payments ) > 1e-6 ) )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private function _reload($data=array())
|
||||
{
|
||||
$person_info = $this->Employee->get_logged_in_employee_info();
|
||||
$data['cart'] = $this->sale_lib->get_cart();
|
||||
$data['modes'] = array('sale'=>$this->lang->line('sales_sale'),'return'=>$this->lang->line('sales_return'));
|
||||
$data['mode'] = $this->sale_lib->get_mode();
|
||||
|
||||
$data['stock_locations'] = $this->Stock_location->get_allowed_locations('sales');
|
||||
$data['stock_location'] = $this->sale_lib->get_sale_location();
|
||||
|
||||
$data['subtotal'] = $this->sale_lib->get_subtotal(TRUE);
|
||||
$data['tax_exclusive_subtotal'] = $this->sale_lib->get_subtotal(TRUE, TRUE);
|
||||
$data['taxes'] = $this->sale_lib->get_taxes();
|
||||
$data['discount'] = $this->sale_lib->get_discount();
|
||||
$data['total'] = $this->sale_lib->get_total();
|
||||
$data['items_module_allowed'] = $this->Employee->has_grant('items', $person_info->person_id);
|
||||
$data['comment'] = $this->sale_lib->get_comment();
|
||||
$data['email_receipt'] = $this->sale_lib->get_email_receipt();
|
||||
$data['payments_total'] = $this->sale_lib->get_payments_total();
|
||||
$data['amount_due'] = $this->sale_lib->get_amount_due();
|
||||
$data['payments'] = $this->sale_lib->get_payments();
|
||||
$data['payment_options'] = array(
|
||||
$this->lang->line('sales_cash') => $this->lang->line('sales_cash'),
|
||||
$this->lang->line('sales_check') => $this->lang->line('sales_check'),
|
||||
$this->lang->line('sales_giftcard') => $this->lang->line('sales_giftcard'),
|
||||
$this->lang->line('sales_debit') => $this->lang->line('sales_debit'),
|
||||
$this->lang->line('sales_credit') => $this->lang->line('sales_credit')
|
||||
);
|
||||
|
||||
$customer_id = $this->sale_lib->get_customer();
|
||||
$cust_info = '';
|
||||
if($customer_id!=-1)
|
||||
{
|
||||
$cust_info = $this->Customer->get_info($customer_id);
|
||||
$data['customer'] = $cust_info->first_name.' '.$cust_info->last_name;
|
||||
$data['customer_email'] = $cust_info->email;
|
||||
}
|
||||
$data['invoice_number'] = $this->_substitute_invoice_number($cust_info);
|
||||
$data['invoice_number_enabled'] = $this->sale_lib->is_invoice_number_enabled();
|
||||
$data['print_after_sale'] = $this->sale_lib->is_print_after_sale();
|
||||
$data['payments_cover_total'] = $this->_payments_cover_total();
|
||||
|
||||
$this->load->view("sales/register",$data);
|
||||
|
||||
$this->_remove_duplicate_cookies();
|
||||
}
|
||||
|
||||
function cancel_sale()
|
||||
{
|
||||
$this->sale_lib->clear_all();
|
||||
$this->_reload();
|
||||
}
|
||||
|
||||
function suspend()
|
||||
{
|
||||
$data['cart'] = $this->sale_lib->get_cart();
|
||||
$data['subtotal'] = $this->sale_lib->get_subtotal();
|
||||
$data['taxes'] = $this->sale_lib->get_taxes();
|
||||
$data['total'] = $this->sale_lib->get_total();
|
||||
$data['receipt_title'] = $this->lang->line('sales_receipt');
|
||||
$data['transaction_time'] = date($this->config->item('dateformat').' '.$this->config->item('timeformat'));
|
||||
$customer_id = $this->sale_lib->get_customer();
|
||||
$employee_id = $this->Employee->get_logged_in_employee_info()->person_id;
|
||||
$comment = $this->sale_lib->get_comment();
|
||||
$invoice_number = $this->sale_lib->get_invoice_number();
|
||||
|
||||
$emp_info = $this->Employee->get_info($employee_id);
|
||||
$data['payment_type'] = $this->input->post('payment_type');
|
||||
// Multiple payments
|
||||
$data['payments'] = $this->sale_lib->get_payments();
|
||||
$data['amount_change'] = to_currency($this->sale_lib->get_amount_due() * -1);
|
||||
$data['employee'] = $emp_info->first_name.' '.$emp_info->last_name;
|
||||
|
||||
if($customer_id!=-1)
|
||||
{
|
||||
$cust_info = $this->Customer->get_info($customer_id);
|
||||
if (isset($cust_info->company_name))
|
||||
{
|
||||
$data['customer'] = $cust_info->company_name;
|
||||
}
|
||||
else
|
||||
{
|
||||
$data['customer'] = $cust_info->first_name.' '.$cust_info->last_name;
|
||||
}
|
||||
}
|
||||
|
||||
$total_payments = 0;
|
||||
|
||||
foreach($data['payments'] as $payment)
|
||||
{
|
||||
$total_payments = bcadd($total_payments, $payment['payment_amount'], PRECISION);
|
||||
}
|
||||
|
||||
//SAVE sale to database
|
||||
$data['sale_id'] = 'POS '.$this->Sale_suspended->save($data['cart'], $customer_id, $employee_id, $comment, $invoice_number, $data['payments']);
|
||||
if ($data['sale_id'] == 'POS -1')
|
||||
{
|
||||
$data['error_message'] = $this->lang->line('sales_transaction_failed');
|
||||
}
|
||||
|
||||
$this->sale_lib->clear_all();
|
||||
|
||||
$this->_reload(array('success' => $this->lang->line('sales_successfully_suspended_sale')));
|
||||
}
|
||||
|
||||
function suspended()
|
||||
{
|
||||
$data = array();
|
||||
$data['suspended_sales'] = $this->Sale_suspended->get_all()->result_array();
|
||||
$this->load->view('sales/suspended', $data);
|
||||
}
|
||||
|
||||
function unsuspend()
|
||||
{
|
||||
$sale_id = $this->input->post('suspended_sale_id');
|
||||
$this->sale_lib->clear_all();
|
||||
$this->sale_lib->copy_entire_suspended_sale($sale_id);
|
||||
$this->Sale_suspended->delete($sale_id);
|
||||
$this->_reload();
|
||||
}
|
||||
|
||||
function check_invoice_number()
|
||||
{
|
||||
$sale_id=$this->input->post('sale_id');
|
||||
$invoice_number=$this->input->post('invoice_number');
|
||||
$exists=!empty($invoice_number) && $this->Sale->invoice_number_exists($invoice_number,$sale_id);
|
||||
echo json_encode(array('success'=>!$exists, 'message'=>$this->lang->line('sales_invoice_number_duplicate')));
|
||||
}
|
||||
}
|
||||
?>
|
||||
@@ -1,115 +0,0 @@
|
||||
<?php
|
||||
class Secure_area extends CI_Controller
|
||||
{
|
||||
|
||||
private $controller_name;
|
||||
|
||||
/*
|
||||
Controllers that are considered secure extend Secure_area, optionally a $module_id can
|
||||
be set to also check if a user can access a particular module in the system.
|
||||
*/
|
||||
function __construct($module_id=null,$submodule_id=null)
|
||||
{
|
||||
parent::__construct();
|
||||
$this->load->model('Employee');
|
||||
if(!$this->Employee->is_logged_in())
|
||||
{
|
||||
redirect('login');
|
||||
}
|
||||
$employee_id=$this->Employee->get_logged_in_employee_info()->person_id;
|
||||
if(!$this->Employee->has_module_grant($module_id,$employee_id) ||
|
||||
(isset($submodule_id) && !$this->Employee->has_module_grant($submodule_id,$employee_id)))
|
||||
{
|
||||
redirect('no_access/'.$module_id.'/'.$submodule_id);
|
||||
}
|
||||
|
||||
//load up global data
|
||||
$logged_in_employee_info=$this->Employee->get_logged_in_employee_info();
|
||||
$data['allowed_modules']=$this->Module->get_allowed_modules($logged_in_employee_info->person_id);
|
||||
$data['backup_allowed']=false;
|
||||
foreach($data['allowed_modules']->result_array() as $module)
|
||||
{
|
||||
$data['backup_allowed']|=$module['module_id']==='config';
|
||||
}
|
||||
$data['user_info']=$logged_in_employee_info;
|
||||
$data['controller_name']=$module_id;
|
||||
$this->controller_name=$module_id;
|
||||
$this->load->vars($data);
|
||||
}
|
||||
|
||||
function get_controller_name() {
|
||||
return strtolower($this->controller_name);
|
||||
}
|
||||
|
||||
function _initialize_pagination($object, $lines_per_page, $limit_from = 0, $total_rows = -1, $function='index', $filter='')
|
||||
{
|
||||
$this->load->library('pagination');
|
||||
$config['base_url'] = site_url($this->get_controller_name() . "/$function/" . $filter);
|
||||
$config['total_rows'] = $total_rows > -1 ? $total_rows : call_user_func(array($object, 'get_total_rows'));
|
||||
$config['per_page'] = $lines_per_page;
|
||||
$config['num_links'] = 2;
|
||||
$config['last_link'] = $this->lang->line('common_last_page');
|
||||
$config['first_link'] = $this->lang->line('common_first_page');
|
||||
// page is calculated here instead of in pagination lib
|
||||
$config['cur_page'] = $limit_from > 0 ? $limit_from : 0;
|
||||
$config['page_query_string'] = FALSE;
|
||||
$config['uri_segment'] = 0;
|
||||
$this->pagination->initialize($config);
|
||||
return $this->pagination->create_links();
|
||||
}
|
||||
|
||||
|
||||
function _remove_duplicate_cookies ()
|
||||
{
|
||||
//php < 5.3 doesn't have header remove so this function will fatal error otherwise
|
||||
if (function_exists('header_remove'))
|
||||
{
|
||||
$CI = &get_instance();
|
||||
|
||||
// clean up all the cookies that are set...
|
||||
$headers = headers_list();
|
||||
$cookies_to_output = array ();
|
||||
$header_session_cookie = '';
|
||||
$session_cookie_name = $CI->config->item('sess_cookie_name');
|
||||
|
||||
foreach ($headers as $header)
|
||||
{
|
||||
list ($header_type, $data) = explode (':', $header, 2);
|
||||
$header_type = trim ($header_type);
|
||||
$data = trim ($data);
|
||||
|
||||
if (strtolower ($header_type) == 'set-cookie')
|
||||
{
|
||||
header_remove ('Set-Cookie');
|
||||
|
||||
$cookie_value = current(explode (';', $data));
|
||||
list ($key, $val) = explode ('=', $cookie_value);
|
||||
$key = trim ($key);
|
||||
|
||||
if ($key == $session_cookie_name)
|
||||
{
|
||||
// OVERWRITE IT (yes! do it!)
|
||||
$header_session_cookie = $data;
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Not a session related cookie, add it as normal. Might be a CSRF or some other cookie we are setting
|
||||
$cookies_to_output[] = array ('header_type' => $header_type, 'data' => $data);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( ! empty ($header_session_cookie))
|
||||
{
|
||||
$cookies_to_output[] = array ('header_type' => 'Set-Cookie', 'data' => $header_session_cookie);
|
||||
}
|
||||
|
||||
foreach ($cookies_to_output as $cookie)
|
||||
{
|
||||
header ("{$cookie['header_type']}: {$cookie['data']}", false);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
?>
|
||||
@@ -1,136 +0,0 @@
|
||||
<?php
|
||||
require_once ("person_controller.php");
|
||||
class Suppliers extends Person_controller
|
||||
{
|
||||
function __construct()
|
||||
{
|
||||
parent::__construct('suppliers');
|
||||
}
|
||||
|
||||
function index($limit_from=0)
|
||||
{
|
||||
$data['controller_name']=$this->get_controller_name();
|
||||
$data['form_width']=$this->get_form_width();
|
||||
$lines_per_page = $this->Appconfig->get('lines_per_page');
|
||||
$suppliers = $this->Supplier->get_all($lines_per_page);
|
||||
|
||||
$data['links'] = $this->_initialize_pagination($this->Supplier,$lines_per_page,$limit_from);
|
||||
$data['manage_table']=get_supplier_manage_table($suppliers,$this);
|
||||
$this->load->view('suppliers/manage',$data);
|
||||
}
|
||||
|
||||
/*
|
||||
Returns supplier table data rows. This will be called with AJAX.
|
||||
*/
|
||||
function search()
|
||||
{
|
||||
$search = $this->input->post('search');
|
||||
$limit_from = $this->input->post('limit_from');
|
||||
$lines_per_page = $this->Appconfig->get('lines_per_page');
|
||||
$suppliers = $this->Supplier->search($search, $lines_per_page, $limit_from);
|
||||
$total_rows = $this->Supplier->get_found_rows($search);
|
||||
$links = $this->_initialize_pagination($this->Supplier, $lines_per_page, $limit_from, $total_rows);
|
||||
$data_rows=get_supplier_manage_table_data_rows($suppliers,$this);
|
||||
echo json_encode(array('total_rows' => $total_rows, 'rows' => $data_rows, 'pagination' => $links));
|
||||
}
|
||||
|
||||
/*
|
||||
Gives search suggestions based on what is being searched for
|
||||
*/
|
||||
function suggest()
|
||||
{
|
||||
$suggestions = $this->Supplier->get_search_suggestions($this->input->post('q'),$this->input->post('limit'));
|
||||
echo implode("\n",$suggestions);
|
||||
}
|
||||
|
||||
/*
|
||||
Loads the supplier edit form
|
||||
*/
|
||||
function view($supplier_id=-1)
|
||||
{
|
||||
$data['person_info']=$this->Supplier->get_info($supplier_id);
|
||||
$this->load->view("suppliers/form",$data);
|
||||
}
|
||||
|
||||
/*
|
||||
Inserts/updates a supplier
|
||||
*/
|
||||
function save($supplier_id=-1)
|
||||
{
|
||||
$person_data = array(
|
||||
'first_name'=>$this->input->post('first_name'),
|
||||
'last_name'=>$this->input->post('last_name'),
|
||||
'gender'=>$this->input->post('gender'),
|
||||
'email'=>$this->input->post('email'),
|
||||
'phone_number'=>$this->input->post('phone_number'),
|
||||
'address_1'=>$this->input->post('address_1'),
|
||||
'address_2'=>$this->input->post('address_2'),
|
||||
'city'=>$this->input->post('city'),
|
||||
'state'=>$this->input->post('state'),
|
||||
'zip'=>$this->input->post('zip'),
|
||||
'country'=>$this->input->post('country'),
|
||||
'comments'=>$this->input->post('comments')
|
||||
);
|
||||
$supplier_data=array(
|
||||
'company_name'=>$this->input->post('company_name'),
|
||||
'agency_name'=>$this->input->post('agency_name'),
|
||||
'account_number'=>$this->input->post('account_number')=='' ? null:$this->input->post('account_number'),
|
||||
);
|
||||
if($this->Supplier->save($person_data,$supplier_data,$supplier_id))
|
||||
{
|
||||
//New supplier
|
||||
if($supplier_id==-1)
|
||||
{
|
||||
echo json_encode(array('success'=>true,'message'=>$this->lang->line('suppliers_successful_adding').' '.
|
||||
$supplier_data['company_name'],'person_id'=>$supplier_data['person_id']));
|
||||
}
|
||||
else //previous supplier
|
||||
{
|
||||
echo json_encode(array('success'=>true,'message'=>$this->lang->line('suppliers_successful_updating').' '.
|
||||
$supplier_data['company_name'],'person_id'=>$supplier_id));
|
||||
}
|
||||
}
|
||||
else//failure
|
||||
{
|
||||
echo json_encode(array('success'=>false,'message'=>$this->lang->line('suppliers_error_adding_updating').' '.
|
||||
$supplier_data['company_name'],'person_id'=>-1));
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
This deletes suppliers from the suppliers table
|
||||
*/
|
||||
function delete()
|
||||
{
|
||||
$suppliers_to_delete=$this->input->post('ids');
|
||||
|
||||
if($this->Supplier->delete_list($suppliers_to_delete))
|
||||
{
|
||||
echo json_encode(array('success'=>true,'message'=>$this->lang->line('suppliers_successful_deleted').' '.
|
||||
count($suppliers_to_delete).' '.$this->lang->line('suppliers_one_or_multiple')));
|
||||
}
|
||||
else
|
||||
{
|
||||
echo json_encode(array('success'=>false,'message'=>$this->lang->line('suppliers_cannot_be_deleted')));
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
Gets one row for a supplier manage table. This is called using AJAX to update one row.
|
||||
*/
|
||||
function get_row()
|
||||
{
|
||||
$person_id = $this->input->post('row_id');
|
||||
$data_row=get_supplier_data_row($this->Supplier->get_info($person_id),$this);
|
||||
echo $data_row;
|
||||
}
|
||||
|
||||
/*
|
||||
get the width for the add/edit form
|
||||
*/
|
||||
function get_form_width()
|
||||
{
|
||||
return 360;
|
||||
}
|
||||
}
|
||||
?>
|
||||
@@ -1,25 +1,19 @@
|
||||
<?php (defined('BASEPATH')) OR exit('No direct script access allowed');
|
||||
<?php if (!defined('BASEPATH')) exit('No direct script access allowed');
|
||||
|
||||
class MY_Lang extends CI_Lang
|
||||
{
|
||||
|
||||
function MY_Lang()
|
||||
{
|
||||
parent::__construct();
|
||||
}
|
||||
|
||||
function switch_to( $idiom )
|
||||
public function switch_to($idiom)
|
||||
{
|
||||
$CI =& get_instance();
|
||||
if( is_string( $idiom ) )
|
||||
if(is_string($idiom))
|
||||
{
|
||||
$CI->config->set_item( 'language', $idiom );
|
||||
$CI->config->set_item('language', $idiom);
|
||||
$loaded = $this->is_loaded;
|
||||
$this->is_loaded = array();
|
||||
|
||||
foreach($loaded as $file)
|
||||
{
|
||||
$this->load( str_replace( '_lang.php', '', $file ) );
|
||||
$this->load(strtr($file, '', '_lang.php'));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -32,7 +26,7 @@ class MY_Lang extends CI_Lang
|
||||
* @access public
|
||||
* @return mixed false if not found or the language string
|
||||
*/
|
||||
function line($line = '')
|
||||
public function line($line = '', $log_errors = TRUE)
|
||||
{
|
||||
//get the arguments passed to the function
|
||||
$args = func_get_args();
|
||||
@@ -41,31 +35,31 @@ class MY_Lang extends CI_Lang
|
||||
$c = count($args);
|
||||
|
||||
//if one or more arguments, perform the necessary processing
|
||||
if ($c)
|
||||
if($c)
|
||||
{
|
||||
//first argument should be the actual language line key
|
||||
//so remove it from the array (pop from front)
|
||||
$line = array_shift($args);
|
||||
|
||||
//check to make sure the key is valid and load the line
|
||||
if ($line == '')
|
||||
if($line == '')
|
||||
{
|
||||
$line = FALSE;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (isset($this->language[$line]))
|
||||
if(isset($this->language[$line]) && $this->language[$line] != '')
|
||||
{
|
||||
$line = $this->language[$line];
|
||||
//if the line exists and more function arguments remain
|
||||
//perform wildcard replacements
|
||||
if ($args)
|
||||
if($args)
|
||||
{
|
||||
$i = 1;
|
||||
foreach ($args as $arg)
|
||||
foreach($args as $arg)
|
||||
{
|
||||
$line = preg_replace('/\%'.$i.'/', $arg, $line);
|
||||
$i++;
|
||||
++$i;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -80,17 +74,16 @@ class MY_Lang extends CI_Lang
|
||||
else
|
||||
{
|
||||
//if no arguments given, no language line available
|
||||
$line = false;
|
||||
$line = FALSE;
|
||||
}
|
||||
|
||||
return $line;
|
||||
}
|
||||
|
||||
function line_tbd($line='')
|
||||
public function line_tbd($line = '')
|
||||
{
|
||||
return $line . ' (TBD)';
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
?>
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>403 Forbidden</title>
|
||||
@@ -7,4 +8,4 @@
|
||||
<p>Directory access is forbidden.</p>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
</html>
|
||||
|
||||
@@ -1,10 +0,0 @@
|
||||
<div style="border:1px solid #990000;padding-left:20px;margin:0 0 10px 0;">
|
||||
|
||||
<h4>A PHP Error was encountered</h4>
|
||||
|
||||
<p>Severity: <?php echo $severity; ?></p>
|
||||
<p>Message: <?php echo $message; ?></p>
|
||||
<p>Filename: <?php echo $filepath; ?></p>
|
||||
<p>Line Number: <?php echo $line; ?></p>
|
||||
|
||||
</div>
|
||||
@@ -1,29 +0,0 @@
|
||||
<?php
|
||||
function to_currency($number,$escape=FALSE)
|
||||
{
|
||||
$CI =& get_instance();
|
||||
$currency_symbol = $CI->config->item('currency_symbol') ? $CI->config->item('currency_symbol') : '$';
|
||||
$currency_symbol = $currency_symbol == '$' && $escape ? '\$' : $currency_symbol;
|
||||
$thousands_separator = $CI->config->item('thousands_separator') ? $CI->config->item('thousands_separator') : '';
|
||||
$decimal_point = $CI->config->item('decimal_point') ? $CI->config->item('decimal_point') : '.';
|
||||
if($number >= 0)
|
||||
{
|
||||
if($CI->config->item('currency_side') !== 'currency_side')
|
||||
return $currency_symbol.number_format($number, 2, $decimal_point, $thousands_separator);
|
||||
else
|
||||
return number_format($number, 2, $decimal_point, $thousands_separator).$currency_symbol;
|
||||
}
|
||||
else
|
||||
{
|
||||
if($CI->config->item('currency_side') !== 'currency_side')
|
||||
return '-'.$currency_symbol.number_format(abs($number), 2, $decimal_point, $thousands_separator);
|
||||
else
|
||||
return '-'.number_format(abs($number), 2, $decimal_point, $thousands_separator).$currency_symbol;
|
||||
}
|
||||
}
|
||||
|
||||
function to_currency_no_money($number)
|
||||
{
|
||||
return number_format($number, 2, '.', '');
|
||||
}
|
||||
?>
|
||||
@@ -1,69 +0,0 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* Matches each symbol of PHP date format standard
|
||||
* with jQuery equivalent codeword
|
||||
* @author Tristan Jahier
|
||||
*/
|
||||
function dateformat_jquery($php_format)
|
||||
{
|
||||
$SYMBOLS_MATCHING = array(
|
||||
// Day
|
||||
'd' => 'dd',
|
||||
'D' => 'D',
|
||||
'j' => 'd',
|
||||
'l' => 'DD',
|
||||
'N' => '',
|
||||
'S' => '',
|
||||
'w' => '',
|
||||
'z' => 'o',
|
||||
// Week
|
||||
'W' => '',
|
||||
// Month
|
||||
'F' => 'MM',
|
||||
'm' => 'mm',
|
||||
'M' => 'M',
|
||||
'n' => 'm',
|
||||
't' => '',
|
||||
// Year
|
||||
'L' => '',
|
||||
'o' => '',
|
||||
'Y' => 'yy',
|
||||
'y' => 'y',
|
||||
// Time
|
||||
'a' => 'tt',
|
||||
'A' => 'TT',
|
||||
'B' => '',
|
||||
'g' => 'h',
|
||||
'G' => 'H',
|
||||
'h' => 'hh',
|
||||
'H' => 'HH',
|
||||
'i' => 'mm',
|
||||
's' => 'ss',
|
||||
'u' => ''
|
||||
);
|
||||
$jqueryui_format = "";
|
||||
$escaping = false;
|
||||
for($i = 0; $i < strlen($php_format); $i++)
|
||||
{
|
||||
$char = $php_format[$i];
|
||||
if($char === '\\') // PHP date format escaping character
|
||||
{
|
||||
$i++;
|
||||
if($escaping) $jqueryui_format .= $php_format[$i];
|
||||
else $jqueryui_format .= '\'' . $php_format[$i];
|
||||
$escaping = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
if($escaping) { $jqueryui_format .= "'"; $escaping = false; }
|
||||
if(isset($SYMBOLS_MATCHING[$char]))
|
||||
$jqueryui_format .= $SYMBOLS_MATCHING[$char];
|
||||
else
|
||||
$jqueryui_format .= $char;
|
||||
}
|
||||
}
|
||||
return $jqueryui_format;
|
||||
}
|
||||
|
||||
?>
|
||||
@@ -1,76 +0,0 @@
|
||||
# How to contribute
|
||||
|
||||
- [Getting help](#getting-help)
|
||||
- [Submitting bug reports](#submitting-bug-reports)
|
||||
- [Contributing code](#contributing-code)
|
||||
|
||||
## Getting help
|
||||
|
||||
Community discussion, questions, and informal bug reporting is done on the
|
||||
[dompdf Google group](http://groups.google.com/group/dompdf). You may also
|
||||
seek help on
|
||||
[StackOverflow](http://stackoverflow.com/questions/tagged/dompdf).
|
||||
|
||||
## Submitting bug reports
|
||||
|
||||
The preferred way to report bugs is to use the
|
||||
[GitHub issue tracker](http://github.com/dompdf/dompdf/issues). Before
|
||||
reporting a bug, read these pointers.
|
||||
|
||||
**Please search inside the bug tracker to see if the bug you found is not already reported.**
|
||||
|
||||
**Note:** The issue tracker is for *bugs* and *feature requests*, not requests for help.
|
||||
Questions should be asked on the
|
||||
[dompdf Google group](http://groups.google.com/group/dompdf) instead.
|
||||
|
||||
### Reporting bugs effectively
|
||||
|
||||
- dompdf is maintained by volunteers. They don't owe you anything, so be
|
||||
polite. Reports with an indignant or belligerent tone tend to be moved to the
|
||||
bottom of the pile.
|
||||
|
||||
- Include information about **the PHP version on which the problem occurred**. Even
|
||||
if you tested several PHP version on different servers, and the problem occurred
|
||||
in all of them, mention this fact in the bug report.
|
||||
Also include the operating system it's installed on. PHP configuration can also help,
|
||||
and server error logs (like Apache logs)
|
||||
|
||||
- Mention which release of dompdf you're using (the zip, the master branch, etc).
|
||||
Preferably, try also with the current development snapshot, to ensure the
|
||||
problem has not already been fixed.
|
||||
|
||||
- Mention very precisely what went wrong. "X is broken" is not a good bug
|
||||
report. What did you expect to happen? What happened instead? Describe the
|
||||
exact steps a maintainer has to take to make the problem occur. We can not
|
||||
fix something that we can not observe.
|
||||
|
||||
- If the problem can not be reproduced in any of the demos included in the
|
||||
dompdf distribution, please provide an HTML document that demonstrates
|
||||
the problem. There are a few options to show us your code:
|
||||
- [JS Fiddle](http://jsfiddle.net/)
|
||||
- [dompdf debug helper](http://eclecticgeek.com/dompdf/debug.php) (provided by @bsweeney)
|
||||
- Include the HTML/CSS inside the bug report, with
|
||||
[code highlighting](https://github.com/adam-p/markdown-here/wiki/Markdown-Cheatsheet#wiki-code).
|
||||
|
||||
## Contributing code
|
||||
|
||||
- Make sure you have a [GitHub Account](https://github.com/signup/free)
|
||||
- Fork [dompdf](https://github.com/dompdf/dompdf/)
|
||||
([how to fork a repo](https://help.github.com/articles/fork-a-repo))
|
||||
- *Make your changes on the dev branch* or the most appropriate feature branch. Please only patch
|
||||
the master branch if you are attempting to address an urgent bug in the released code.
|
||||
- Add a simple test file in `www/test/`, with a comprehensive name.
|
||||
- Submit a pull request
|
||||
([how to create a pull request](https://help.github.com/articles/fork-a-repo))
|
||||
|
||||
### Coding standards
|
||||
|
||||
- 2 spaces per indentation level, no tabs.
|
||||
- spaces inside `if` like this:
|
||||
```php
|
||||
if ( $foo == "bar" ) {
|
||||
//
|
||||
}
|
||||
```
|
||||
- booleans in lowercase
|
||||
- opening braces *always* on the same line
|
||||
@@ -1,456 +0,0 @@
|
||||
GNU LESSER GENERAL PUBLIC LICENSE
|
||||
Version 2.1, February 1999
|
||||
|
||||
Copyright (C) 1991, 1999 Free Software Foundation, Inc.
|
||||
59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
[This is the first released version of the Lesser GPL. It also counts
|
||||
as the successor of the GNU Library Public License, version 2, hence
|
||||
the version number 2.1.]
|
||||
|
||||
Preamble
|
||||
|
||||
The licenses for most software are designed to take away your
|
||||
freedom to share and change it. By contrast, the GNU General Public
|
||||
Licenses are intended to guarantee your freedom to share and change
|
||||
free software--to make sure the software is free for all its users.
|
||||
|
||||
This license, the Lesser General Public License, applies to some
|
||||
specially designated software packages--typically libraries--of the
|
||||
Free Software Foundation and other authors who decide to use it. You
|
||||
can use it too, but we suggest you first think carefully about whether
|
||||
this license or the ordinary General Public License is the better
|
||||
strategy to use in any particular case, based on the explanations below.
|
||||
|
||||
When we speak of free software, we are referring to freedom of use,
|
||||
not price. Our General Public Licenses are designed to make sure that
|
||||
you have the freedom to distribute copies of free software (and charge
|
||||
for this service if you wish); that you receive source code or can get
|
||||
it if you want it; that you can change the software and use pieces of
|
||||
it in new free programs; and that you are informed that you can do
|
||||
these things.
|
||||
|
||||
To protect your rights, we need to make restrictions that forbid
|
||||
distributors to deny you these rights or to ask you to surrender these
|
||||
rights. These restrictions translate to certain responsibilities for
|
||||
you if you distribute copies of the library or if you modify it.
|
||||
|
||||
For example, if you distribute copies of the library, whether gratis
|
||||
or for a fee, you must give the recipients all the rights that we gave
|
||||
you. You must make sure that they, too, receive or can get the source
|
||||
code. If you link other code with the library, you must provide
|
||||
complete object files to the recipients, so that they can relink them
|
||||
with the library after making changes to the library and recompiling
|
||||
it. And you must show them these terms so they know their rights.
|
||||
|
||||
We protect your rights with a two-step method: (1) we copyright the
|
||||
library, and (2) we offer you this license, which gives you legal
|
||||
permission to copy, distribute and/or modify the library.
|
||||
|
||||
To protect each distributor, we want to make it very clear that
|
||||
there is no warranty for the free library. Also, if the library is
|
||||
modified by someone else and passed on, the recipients should know
|
||||
that what they have is not the original version, so that the original
|
||||
author's reputation will not be affected by problems that might be
|
||||
introduced by others.
|
||||
|
||||
Finally, software patents pose a constant threat to the existence of
|
||||
any free program. We wish to make sure that a company cannot
|
||||
effectively restrict the users of a free program by obtaining a
|
||||
restrictive license from a patent holder. Therefore, we insist that
|
||||
any patent license obtained for a version of the library must be
|
||||
consistent with the full freedom of use specified in this license.
|
||||
|
||||
Most GNU software, including some libraries, is covered by the
|
||||
ordinary GNU General Public License. This license, the GNU Lesser
|
||||
General Public License, applies to certain designated libraries, and
|
||||
is quite different from the ordinary General Public License. We use
|
||||
this license for certain libraries in order to permit linking those
|
||||
libraries into non-free programs.
|
||||
|
||||
When a program is linked with a library, whether statically or using
|
||||
a shared library, the combination of the two is legally speaking a
|
||||
combined work, a derivative of the original library. The ordinary
|
||||
General Public License therefore permits such linking only if the
|
||||
entire combination fits its criteria of freedom. The Lesser General
|
||||
Public License permits more lax criteria for linking other code with
|
||||
the library.
|
||||
|
||||
We call this license the "Lesser" General Public License because it
|
||||
does Less to protect the user's freedom than the ordinary General
|
||||
Public License. It also provides other free software developers Less
|
||||
of an advantage over competing non-free programs. These disadvantages
|
||||
are the reason we use the ordinary General Public License for many
|
||||
libraries. However, the Lesser license provides advantages in certain
|
||||
special circumstances.
|
||||
|
||||
For example, on rare occasions, there may be a special need to
|
||||
encourage the widest possible use of a certain library, so that it becomes
|
||||
a de-facto standard. To achieve this, non-free programs must be
|
||||
allowed to use the library. A more frequent case is that a free
|
||||
library does the same job as widely used non-free libraries. In this
|
||||
case, there is little to gain by limiting the free library to free
|
||||
software only, so we use the Lesser General Public License.
|
||||
|
||||
In other cases, permission to use a particular library in non-free
|
||||
programs enables a greater number of people to use a large body of
|
||||
free software. For example, permission to use the GNU C Library in
|
||||
non-free programs enables many more people to use the whole GNU
|
||||
operating system, as well as its variant, the GNU/Linux operating
|
||||
system.
|
||||
|
||||
Although the Lesser General Public License is Less protective of the
|
||||
users' freedom, it does ensure that the user of a program that is
|
||||
linked with the Library has the freedom and the wherewithal to run
|
||||
that program using a modified version of the Library.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow. Pay close attention to the difference between a
|
||||
"work based on the library" and a "work that uses the library". The
|
||||
former contains code derived from the library, whereas the latter must
|
||||
be combined with the library in order to run.
|
||||
|
||||
GNU LESSER GENERAL PUBLIC LICENSE
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
|
||||
0. This License Agreement applies to any software library or other
|
||||
program which contains a notice placed by the copyright holder or
|
||||
other authorized party saying it may be distributed under the terms of
|
||||
this Lesser General Public License (also called "this License").
|
||||
Each licensee is addressed as "you".
|
||||
|
||||
A "library" means a collection of software functions and/or data
|
||||
prepared so as to be conveniently linked with application programs
|
||||
(which use some of those functions and data) to form executables.
|
||||
|
||||
The "Library", below, refers to any such software library or work
|
||||
which has been distributed under these terms. A "work based on the
|
||||
Library" means either the Library or any derivative work under
|
||||
copyright law: that is to say, a work containing the Library or a
|
||||
portion of it, either verbatim or with modifications and/or translated
|
||||
straightforwardly into another language. (Hereinafter, translation is
|
||||
included without limitation in the term "modification".)
|
||||
|
||||
"Source code" for a work means the preferred form of the work for
|
||||
making modifications to it. For a library, complete source code means
|
||||
all the source code for all modules it contains, plus any associated
|
||||
interface definition files, plus the scripts used to control compilation
|
||||
and installation of the library.
|
||||
|
||||
Activities other than copying, distribution and modification are not
|
||||
covered by this License; they are outside its scope. The act of
|
||||
running a program using the Library is not restricted, and output from
|
||||
such a program is covered only if its contents constitute a work based
|
||||
on the Library (independent of the use of the Library in a tool for
|
||||
writing it). Whether that is true depends on what the Library does
|
||||
and what the program that uses the Library does.
|
||||
|
||||
1. You may copy and distribute verbatim copies of the Library's
|
||||
complete source code as you receive it, in any medium, provided that
|
||||
you conspicuously and appropriately publish on each copy an
|
||||
appropriate copyright notice and disclaimer of warranty; keep intact
|
||||
all the notices that refer to this License and to the absence of any
|
||||
warranty; and distribute a copy of this License along with the
|
||||
Library.
|
||||
|
||||
You may charge a fee for the physical act of transferring a copy,
|
||||
and you may at your option offer warranty protection in exchange for a
|
||||
fee.
|
||||
|
||||
2. You may modify your copy or copies of the Library or any portion
|
||||
of it, thus forming a work based on the Library, and copy and
|
||||
distribute such modifications or work under the terms of Section 1
|
||||
above, provided that you also meet all of these conditions:
|
||||
|
||||
a) The modified work must itself be a software library.
|
||||
|
||||
b) You must cause the files modified to carry prominent notices
|
||||
stating that you changed the files and the date of any change.
|
||||
|
||||
c) You must cause the whole of the work to be licensed at no
|
||||
charge to all third parties under the terms of this License.
|
||||
|
||||
d) If a facility in the modified Library refers to a function or a
|
||||
table of data to be supplied by an application program that uses
|
||||
the facility, other than as an argument passed when the facility
|
||||
is invoked, then you must make a good faith effort to ensure that,
|
||||
in the event an application does not supply such function or
|
||||
table, the facility still operates, and performs whatever part of
|
||||
its purpose remains meaningful.
|
||||
|
||||
(For example, a function in a library to compute square roots has
|
||||
a purpose that is entirely well-defined independent of the
|
||||
application. Therefore, Subsection 2d requires that any
|
||||
application-supplied function or table used by this function must
|
||||
be optional: if the application does not supply it, the square
|
||||
root function must still compute square roots.)
|
||||
|
||||
These requirements apply to the modified work as a whole. If
|
||||
identifiable sections of that work are not derived from the Library,
|
||||
and can be reasonably considered independent and separate works in
|
||||
themselves, then this License, and its terms, do not apply to those
|
||||
sections when you distribute them as separate works. But when you
|
||||
distribute the same sections as part of a whole which is a work based
|
||||
on the Library, the distribution of the whole must be on the terms of
|
||||
this License, whose permissions for other licensees extend to the
|
||||
entire whole, and thus to each and every part regardless of who wrote
|
||||
it.
|
||||
|
||||
Thus, it is not the intent of this section to claim rights or contest
|
||||
your rights to work written entirely by you; rather, the intent is to
|
||||
exercise the right to control the distribution of derivative or
|
||||
collective works based on the Library.
|
||||
|
||||
In addition, mere aggregation of another work not based on the Library
|
||||
with the Library (or with a work based on the Library) on a volume of
|
||||
a storage or distribution medium does not bring the other work under
|
||||
the scope of this License.
|
||||
|
||||
3. You may opt to apply the terms of the ordinary GNU General Public
|
||||
License instead of this License to a given copy of the Library. To do
|
||||
this, you must alter all the notices that refer to this License, so
|
||||
that they refer to the ordinary GNU General Public License, version 2,
|
||||
instead of to this License. (If a newer version than version 2 of the
|
||||
ordinary GNU General Public License has appeared, then you can specify
|
||||
that version instead if you wish.) Do not make any other change in
|
||||
these notices.
|
||||
|
||||
Once this change is made in a given copy, it is irreversible for
|
||||
that copy, so the ordinary GNU General Public License applies to all
|
||||
subsequent copies and derivative works made from that copy.
|
||||
|
||||
This option is useful when you wish to copy part of the code of
|
||||
the Library into a program that is not a library.
|
||||
|
||||
4. You may copy and distribute the Library (or a portion or
|
||||
derivative of it, under Section 2) in object code or executable form
|
||||
under the terms of Sections 1 and 2 above provided that you accompany
|
||||
it with the complete corresponding machine-readable source code, which
|
||||
must be distributed under the terms of Sections 1 and 2 above on a
|
||||
medium customarily used for software interchange.
|
||||
|
||||
If distribution of object code is made by offering access to copy
|
||||
from a designated place, then offering equivalent access to copy the
|
||||
source code from the same place satisfies the requirement to
|
||||
distribute the source code, even though third parties are not
|
||||
compelled to copy the source along with the object code.
|
||||
|
||||
5. A program that contains no derivative of any portion of the
|
||||
Library, but is designed to work with the Library by being compiled or
|
||||
linked with it, is called a "work that uses the Library". Such a
|
||||
work, in isolation, is not a derivative work of the Library, and
|
||||
therefore falls outside the scope of this License.
|
||||
|
||||
However, linking a "work that uses the Library" with the Library
|
||||
creates an executable that is a derivative of the Library (because it
|
||||
contains portions of the Library), rather than a "work that uses the
|
||||
library". The executable is therefore covered by this License.
|
||||
Section 6 states terms for distribution of such executables.
|
||||
|
||||
When a "work that uses the Library" uses material from a header file
|
||||
that is part of the Library, the object code for the work may be a
|
||||
derivative work of the Library even though the source code is not.
|
||||
Whether this is true is especially significant if the work can be
|
||||
linked without the Library, or if the work is itself a library. The
|
||||
threshold for this to be true is not precisely defined by law.
|
||||
|
||||
If such an object file uses only numerical parameters, data
|
||||
structure layouts and accessors, and small macros and small inline
|
||||
functions (ten lines or less in length), then the use of the object
|
||||
file is unrestricted, regardless of whether it is legally a derivative
|
||||
work. (Executables containing this object code plus portions of the
|
||||
Library will still fall under Section 6.)
|
||||
|
||||
Otherwise, if the work is a derivative of the Library, you may
|
||||
distribute the object code for the work under the terms of Section 6.
|
||||
Any executables containing that work also fall under Section 6,
|
||||
whether or not they are linked directly with the Library itself.
|
||||
|
||||
6. As an exception to the Sections above, you may also combine or
|
||||
link a "work that uses the Library" with the Library to produce a
|
||||
work containing portions of the Library, and distribute that work
|
||||
under terms of your choice, provided that the terms permit
|
||||
modification of the work for the customer's own use and reverse
|
||||
engineering for debugging such modifications.
|
||||
|
||||
You must give prominent notice with each copy of the work that the
|
||||
Library is used in it and that the Library and its use are covered by
|
||||
this License. You must supply a copy of this License. If the work
|
||||
during execution displays copyright notices, you must include the
|
||||
copyright notice for the Library among them, as well as a reference
|
||||
directing the user to the copy of this License. Also, you must do one
|
||||
of these things:
|
||||
|
||||
a) Accompany the work with the complete corresponding
|
||||
machine-readable source code for the Library including whatever
|
||||
changes were used in the work (which must be distributed under
|
||||
Sections 1 and 2 above); and, if the work is an executable linked
|
||||
with the Library, with the complete machine-readable "work that
|
||||
uses the Library", as object code and/or source code, so that the
|
||||
user can modify the Library and then relink to produce a modified
|
||||
executable containing the modified Library. (It is understood
|
||||
that the user who changes the contents of definitions files in the
|
||||
Library will not necessarily be able to recompile the application
|
||||
to use the modified definitions.)
|
||||
|
||||
b) Use a suitable shared library mechanism for linking with the
|
||||
Library. A suitable mechanism is one that (1) uses at run time a
|
||||
copy of the library already present on the user's computer system,
|
||||
rather than copying library functions into the executable, and (2)
|
||||
will operate properly with a modified version of the library, if
|
||||
the user installs one, as long as the modified version is
|
||||
interface-compatible with the version that the work was made with.
|
||||
|
||||
c) Accompany the work with a written offer, valid for at
|
||||
least three years, to give the same user the materials
|
||||
specified in Subsection 6a, above, for a charge no more
|
||||
than the cost of performing this distribution.
|
||||
|
||||
d) If distribution of the work is made by offering access to copy
|
||||
from a designated place, offer equivalent access to copy the above
|
||||
specified materials from the same place.
|
||||
|
||||
e) Verify that the user has already received a copy of these
|
||||
materials or that you have already sent this user a copy.
|
||||
|
||||
For an executable, the required form of the "work that uses the
|
||||
Library" must include any data and utility programs needed for
|
||||
reproducing the executable from it. However, as a special exception,
|
||||
the materials to be distributed need not include anything that is
|
||||
normally distributed (in either source or binary form) with the major
|
||||
components (compiler, kernel, and so on) of the operating system on
|
||||
which the executable runs, unless that component itself accompanies
|
||||
the executable.
|
||||
|
||||
It may happen that this requirement contradicts the license
|
||||
restrictions of other proprietary libraries that do not normally
|
||||
accompany the operating system. Such a contradiction means you cannot
|
||||
use both them and the Library together in an executable that you
|
||||
distribute.
|
||||
|
||||
7. You may place library facilities that are a work based on the
|
||||
Library side-by-side in a single library together with other library
|
||||
facilities not covered by this License, and distribute such a combined
|
||||
library, provided that the separate distribution of the work based on
|
||||
the Library and of the other library facilities is otherwise
|
||||
permitted, and provided that you do these two things:
|
||||
|
||||
a) Accompany the combined library with a copy of the same work
|
||||
based on the Library, uncombined with any other library
|
||||
facilities. This must be distributed under the terms of the
|
||||
Sections above.
|
||||
|
||||
b) Give prominent notice with the combined library of the fact
|
||||
that part of it is a work based on the Library, and explaining
|
||||
where to find the accompanying uncombined form of the same work.
|
||||
|
||||
8. You may not copy, modify, sublicense, link with, or distribute
|
||||
the Library except as expressly provided under this License. Any
|
||||
attempt otherwise to copy, modify, sublicense, link with, or
|
||||
distribute the Library is void, and will automatically terminate your
|
||||
rights under this License. However, parties who have received copies,
|
||||
or rights, from you under this License will not have their licenses
|
||||
terminated so long as such parties remain in full compliance.
|
||||
|
||||
9. You are not required to accept this License, since you have not
|
||||
signed it. However, nothing else grants you permission to modify or
|
||||
distribute the Library or its derivative works. These actions are
|
||||
prohibited by law if you do not accept this License. Therefore, by
|
||||
modifying or distributing the Library (or any work based on the
|
||||
Library), you indicate your acceptance of this License to do so, and
|
||||
all its terms and conditions for copying, distributing or modifying
|
||||
the Library or works based on it.
|
||||
|
||||
10. Each time you redistribute the Library (or any work based on the
|
||||
Library), the recipient automatically receives a license from the
|
||||
original licensor to copy, distribute, link with or modify the Library
|
||||
subject to these terms and conditions. You may not impose any further
|
||||
restrictions on the recipients' exercise of the rights granted herein.
|
||||
You are not responsible for enforcing compliance by third parties with
|
||||
this License.
|
||||
|
||||
11. If, as a consequence of a court judgment or allegation of patent
|
||||
infringement or for any other reason (not limited to patent issues),
|
||||
conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot
|
||||
distribute so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you
|
||||
may not distribute the Library at all. For example, if a patent
|
||||
license would not permit royalty-free redistribution of the Library by
|
||||
all those who receive copies directly or indirectly through you, then
|
||||
the only way you could satisfy both it and this License would be to
|
||||
refrain entirely from distribution of the Library.
|
||||
|
||||
If any portion of this section is held invalid or unenforceable under any
|
||||
particular circumstance, the balance of the section is intended to apply,
|
||||
and the section as a whole is intended to apply in other circumstances.
|
||||
|
||||
It is not the purpose of this section to induce you to infringe any
|
||||
patents or other property right claims or to contest validity of any
|
||||
such claims; this section has the sole purpose of protecting the
|
||||
integrity of the free software distribution system which is
|
||||
implemented by public license practices. Many people have made
|
||||
generous contributions to the wide range of software distributed
|
||||
through that system in reliance on consistent application of that
|
||||
system; it is up to the author/donor to decide if he or she is willing
|
||||
to distribute software through any other system and a licensee cannot
|
||||
impose that choice.
|
||||
|
||||
This section is intended to make thoroughly clear what is believed to
|
||||
be a consequence of the rest of this License.
|
||||
|
||||
12. If the distribution and/or use of the Library is restricted in
|
||||
certain countries either by patents or by copyrighted interfaces, the
|
||||
original copyright holder who places the Library under this License may add
|
||||
an explicit geographical distribution limitation excluding those countries,
|
||||
so that distribution is permitted only in or among countries not thus
|
||||
excluded. In such case, this License incorporates the limitation as if
|
||||
written in the body of this License.
|
||||
|
||||
13. The Free Software Foundation may publish revised and/or new
|
||||
versions of the Lesser General Public License from time to time.
|
||||
Such new versions will be similar in spirit to the present version,
|
||||
but may differ in detail to address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the Library
|
||||
specifies a version number of this License which applies to it and
|
||||
"any later version", you have the option of following the terms and
|
||||
conditions either of that version or of any later version published by
|
||||
the Free Software Foundation. If the Library does not specify a
|
||||
license version number, you may choose any version ever published by
|
||||
the Free Software Foundation.
|
||||
|
||||
14. If you wish to incorporate parts of the Library into other free
|
||||
programs whose distribution conditions are incompatible with these,
|
||||
write to the author to ask for permission. For software which is
|
||||
copyrighted by the Free Software Foundation, write to the Free
|
||||
Software Foundation; we sometimes make exceptions for this. Our
|
||||
decision will be guided by the two goals of preserving the free status
|
||||
of all derivatives of our free software and of promoting the sharing
|
||||
and reuse of software generally.
|
||||
|
||||
NO WARRANTY
|
||||
|
||||
15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
|
||||
WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
|
||||
EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
|
||||
OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
|
||||
KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
|
||||
LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
|
||||
THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
|
||||
|
||||
16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
|
||||
WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
|
||||
AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
|
||||
FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
|
||||
CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
|
||||
LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
|
||||
RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
|
||||
FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
|
||||
SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
|
||||
DAMAGES.
|
||||
@@ -1,131 +0,0 @@
|
||||
**dompdf is an HTML to PDF converter**.
|
||||
At its heart, dompdf is (mostly) [CSS 2.1](http://www.w3.org/TR/CSS2/) compliant
|
||||
HTML layout and rendering engine written in PHP. It is a style-driven renderer:
|
||||
it will download and read external stylesheets, inline style tags, and the style
|
||||
attributes of individual HTML elements. It also supports most presentational
|
||||
HTML attributes.
|
||||
|
||||
----
|
||||
|
||||
**Check out the [Demo](http://pxd.me/dompdf/www/examples.php) and ask any
|
||||
question on [StackOverflow](http://stackoverflow.com/questions/tagged/dompdf) or
|
||||
on the [Google Groups](http://groups.google.com/group/dompdf)**
|
||||
|
||||
----
|
||||
|
||||
[](http://www.twitter.com/dompdf)
|
||||
[](https://plus.google.com/108710008521858993320?prsrc=3)
|
||||
|
||||
Features
|
||||
========
|
||||
* handles most CSS 2.1 and a few CSS3 properties, including @import, @media &
|
||||
@page rules
|
||||
* supports most presentational HTML 4.0 attributes
|
||||
* supports external stylesheets, either local or through http/ftp (via
|
||||
fopen-wrappers)
|
||||
* supports complex tables, including row & column spans, separate & collapsed
|
||||
border models, individual cell styling
|
||||
* image support (gif, png (8, 24 and 32 bit with alpha channel), bmp & jpeg)
|
||||
* no dependencies on external PDF libraries, thanks to the R&OS PDF class
|
||||
* inline PHP support
|
||||
|
||||
Requirements
|
||||
============
|
||||
* PHP 5.0+ (5.3+ recommended)
|
||||
* DOM extension
|
||||
* GD extension
|
||||
|
||||
Recommendations
|
||||
============
|
||||
* MBString extension: provides internationalization support. This extension is
|
||||
*not* enabled by default. dompdf has limited internationalization support
|
||||
when this extension is not enabled.
|
||||
* opcache (OPcache, XCache, APC, etc.): improves performance
|
||||
|
||||
About Fonts & Character Encoding
|
||||
============
|
||||
PDF documents internally support the following fonts: Helvetica, Times-Roman,
|
||||
Courier, Zapf-Dingbats, & Symbol. These fonts only support Windows ANSI
|
||||
encoding. In order for a PDF to display characters that are not available in
|
||||
Windows ANSI you must supply an external font. dompdf will embed any referenced
|
||||
font in the PDF so long as it has been pre-loaded or is accessible to dompdf and
|
||||
reference in CSS @font-face rules. See the
|
||||
[font overview](https://github.com/dompdf/dompdf/wiki/About-Fonts-and-Character-Encoding)
|
||||
for more information on how to use fonts.
|
||||
|
||||
The [DejaVu TrueType fonts](http://dejavu-fonts.org) have been pre-installed to
|
||||
give dompdf decent Unicode character coverage by default. To use the DejaVu
|
||||
fonts reference the font in your stylesheet, e.g. `body { font-family: Deja Vu
|
||||
Sans; }` (for DejaVu Sans).
|
||||
|
||||
Easy Installation
|
||||
============
|
||||
Install with git
|
||||
---
|
||||
From the command line switch to the directory where dompdf will reside and run
|
||||
the following commands:
|
||||
|
||||
```sh
|
||||
git clone https://github.com/dompdf/dompdf.git
|
||||
git submodule init
|
||||
git submodule update
|
||||
```
|
||||
|
||||
Install with composer
|
||||
---
|
||||
To install with Composer, simply add the requirement to your `composer.json`
|
||||
file:
|
||||
|
||||
```json
|
||||
{
|
||||
"require" : {
|
||||
"dompdf/dompdf" : "0.6.*"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
And run Composer to update your dependencies:
|
||||
|
||||
```bash
|
||||
$ curl -sS http://getcomposer.org/installer | php
|
||||
$ php composer.phar update
|
||||
```
|
||||
|
||||
Before you can use the Composer installation of DOMPDF in your application you
|
||||
must disable dompdf's default auto-loader, include the Composer autoloader, and
|
||||
load the dompdf configuration file:
|
||||
|
||||
```php
|
||||
// somewhere early in your project's loading, require the Composer autoloader
|
||||
// see: http://getcomposer.org/doc/00-intro.md
|
||||
require 'vendor/autoload.php';
|
||||
|
||||
// disable DOMPDF's internal autoloader if you are using Composer
|
||||
define('DOMPDF_ENABLE_AUTOLOAD', false);
|
||||
|
||||
// include DOMPDF's default configuration
|
||||
require_once '/path/to/vendor/dompdf/dompdf/dompdf_config.inc.php';
|
||||
```
|
||||
|
||||
Download and install
|
||||
---
|
||||
Download an archive of dompdf and extract it into the directory where dompdf
|
||||
will reside
|
||||
* You can download stable copies of dompdf from
|
||||
https://github.com/dompdf/dompdf/tags
|
||||
* Or download a nightly (the latest, unreleased code) from
|
||||
http://eclecticgeek.com/dompdf
|
||||
|
||||
Limitations (Known Issues)
|
||||
==========================
|
||||
* not particularly tolerant to poorly-formed HTML input. To avoid any
|
||||
unexpected rendering issues you should either enable the built-in HTML5
|
||||
parser (via the `DOMPDF_ENABLE_HTML5PARSER` configuration constant) or run
|
||||
your HTML through a HTML validator/cleaner (such as Tidy).
|
||||
* large files or large tables can take a while to render
|
||||
* CSS float is not supported (but is in the works, enable it through the
|
||||
`DOMPDF_ENABLE_CSS_FLOAT` configuration constant).
|
||||
* If you find this project useful, please consider making a donation.
|
||||
|
||||
(Any funds donated will be used to help further development on this project.)
|
||||
[](http://goo.gl/DSvWf)
|
||||
@@ -1,23 +0,0 @@
|
||||
{
|
||||
"name": "dompdf/dompdf",
|
||||
"type": "library",
|
||||
"description": "DOMPDF is a CSS 2.1 compliant HTML to PDF converter",
|
||||
"homepage": "https://github.com/dompdf/dompdf",
|
||||
"license": "LGPL",
|
||||
"authors": [
|
||||
{
|
||||
"name": "Fabien Ménager",
|
||||
"email": "fabien.menager@gmail.com"
|
||||
},
|
||||
{
|
||||
"name": "Brian Sweeney",
|
||||
"email": "eclecticgeek@gmail.com"
|
||||
}
|
||||
],
|
||||
"autoload": {
|
||||
"classmap": ["include/"]
|
||||
},
|
||||
"require": {
|
||||
"phenx/php-font-lib": "0.2.*"
|
||||
}
|
||||
}
|
||||
@@ -1,289 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* Command line utility to use dompdf.
|
||||
* Can also be used with HTTP GET parameters
|
||||
*
|
||||
* @package dompdf
|
||||
* @link http://dompdf.github.com/
|
||||
* @author Benj Carson <benjcarson@digitaljunkies.ca>
|
||||
* @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License
|
||||
*/
|
||||
|
||||
/**
|
||||
* Display command line usage
|
||||
*/
|
||||
function dompdf_usage() {
|
||||
$default_paper_size = DOMPDF_DEFAULT_PAPER_SIZE;
|
||||
|
||||
echo <<<EOD
|
||||
|
||||
Usage: {$_SERVER["argv"][0]} [options] html_file
|
||||
|
||||
html_file can be a filename, a url if fopen_wrappers are enabled, or the '-' character to read from standard input.
|
||||
|
||||
Options:
|
||||
-h Show this message
|
||||
-l List available paper sizes
|
||||
-p size Paper size; something like 'letter', 'A4', 'legal', etc.
|
||||
The default is '$default_paper_size'
|
||||
-o orientation Either 'portrait' or 'landscape'. Default is 'portrait'
|
||||
-b path Set the 'document root' of the html_file.
|
||||
Relative urls (for stylesheets) are resolved using this directory.
|
||||
Default is the directory of html_file.
|
||||
-f file The output filename. Default is the input [html_file].pdf
|
||||
-v Verbose: display html parsing warnings and file not found errors.
|
||||
-d Very verbose: display oodles of debugging output: every frame
|
||||
in the tree printed to stdout.
|
||||
-t Comma separated list of debugging types (page-break,reflow,split)
|
||||
|
||||
EOD;
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses command line options
|
||||
*
|
||||
* @return array The command line options
|
||||
*/
|
||||
function getoptions() {
|
||||
|
||||
$opts = array();
|
||||
|
||||
if ( $_SERVER["argc"] == 1 )
|
||||
return $opts;
|
||||
|
||||
$i = 1;
|
||||
while ($i < $_SERVER["argc"]) {
|
||||
|
||||
switch ($_SERVER["argv"][$i]) {
|
||||
|
||||
case "--help":
|
||||
case "-h":
|
||||
$opts["h"] = true;
|
||||
$i++;
|
||||
break;
|
||||
|
||||
case "-l":
|
||||
$opts["l"] = true;
|
||||
$i++;
|
||||
break;
|
||||
|
||||
case "-p":
|
||||
if ( !isset($_SERVER["argv"][$i+1]) )
|
||||
die("-p switch requires a size parameter\n");
|
||||
$opts["p"] = $_SERVER["argv"][$i+1];
|
||||
$i += 2;
|
||||
break;
|
||||
|
||||
case "-o":
|
||||
if ( !isset($_SERVER["argv"][$i+1]) )
|
||||
die("-o switch requires an orientation parameter\n");
|
||||
$opts["o"] = $_SERVER["argv"][$i+1];
|
||||
$i += 2;
|
||||
break;
|
||||
|
||||
case "-b":
|
||||
if ( !isset($_SERVER["argv"][$i+1]) )
|
||||
die("-b switch requires a path parameter\n");
|
||||
$opts["b"] = $_SERVER["argv"][$i+1];
|
||||
$i += 2;
|
||||
break;
|
||||
|
||||
case "-f":
|
||||
if ( !isset($_SERVER["argv"][$i+1]) )
|
||||
die("-f switch requires a filename parameter\n");
|
||||
$opts["f"] = $_SERVER["argv"][$i+1];
|
||||
$i += 2;
|
||||
break;
|
||||
|
||||
case "-v":
|
||||
$opts["v"] = true;
|
||||
$i++;
|
||||
break;
|
||||
|
||||
case "-d":
|
||||
$opts["d"] = true;
|
||||
$i++;
|
||||
break;
|
||||
|
||||
case "-t":
|
||||
if ( !isset($_SERVER['argv'][$i + 1]) )
|
||||
die("-t switch requires a comma separated list of types\n");
|
||||
$opts["t"] = $_SERVER['argv'][$i+1];
|
||||
$i += 2;
|
||||
break;
|
||||
|
||||
default:
|
||||
$opts["filename"] = $_SERVER["argv"][$i];
|
||||
$i++;
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
return $opts;
|
||||
}
|
||||
|
||||
require_once("dompdf_config.inc.php");
|
||||
global $_dompdf_show_warnings, $_dompdf_debug, $_DOMPDF_DEBUG_TYPES;
|
||||
|
||||
$sapi = php_sapi_name();
|
||||
$options = array();
|
||||
|
||||
switch ( $sapi ) {
|
||||
|
||||
case "cli":
|
||||
|
||||
$opts = getoptions();
|
||||
|
||||
if ( isset($opts["h"]) || (!isset($opts["filename"]) && !isset($opts["l"])) ) {
|
||||
dompdf_usage();
|
||||
exit;
|
||||
}
|
||||
|
||||
if ( isset($opts["l"]) ) {
|
||||
echo "\nUnderstood paper sizes:\n";
|
||||
|
||||
foreach (array_keys(CPDF_Adapter::$PAPER_SIZES) as $size)
|
||||
echo " " . mb_strtoupper($size) . "\n";
|
||||
exit;
|
||||
}
|
||||
$file = $opts["filename"];
|
||||
|
||||
if ( isset($opts["p"]) )
|
||||
$paper = $opts["p"];
|
||||
else
|
||||
$paper = DOMPDF_DEFAULT_PAPER_SIZE;
|
||||
|
||||
if ( isset($opts["o"]) )
|
||||
$orientation = $opts["o"];
|
||||
else
|
||||
$orientation = "portrait";
|
||||
|
||||
if ( isset($opts["b"]) )
|
||||
$base_path = $opts["b"];
|
||||
|
||||
if ( isset($opts["f"]) )
|
||||
$outfile = $opts["f"];
|
||||
else {
|
||||
if ( $file === "-" )
|
||||
$outfile = "dompdf_out.pdf";
|
||||
else
|
||||
$outfile = str_ireplace(array(".html", ".htm", ".php"), "", $file) . ".pdf";
|
||||
}
|
||||
|
||||
if ( isset($opts["v"]) )
|
||||
$_dompdf_show_warnings = true;
|
||||
|
||||
if ( isset($opts["d"]) ) {
|
||||
$_dompdf_show_warnings = true;
|
||||
$_dompdf_debug = true;
|
||||
}
|
||||
|
||||
if ( isset($opts['t']) ) {
|
||||
$arr = split(',',$opts['t']);
|
||||
$types = array();
|
||||
foreach ($arr as $type)
|
||||
$types[ trim($type) ] = 1;
|
||||
$_DOMPDF_DEBUG_TYPES = $types;
|
||||
}
|
||||
|
||||
$save_file = true;
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
|
||||
if ( isset($_GET["input_file"]) )
|
||||
$file = rawurldecode($_GET["input_file"]);
|
||||
else
|
||||
throw new DOMPDF_Exception("An input file is required (i.e. input_file _GET variable).");
|
||||
|
||||
if ( isset($_GET["paper"]) )
|
||||
$paper = rawurldecode($_GET["paper"]);
|
||||
else
|
||||
$paper = DOMPDF_DEFAULT_PAPER_SIZE;
|
||||
|
||||
if ( isset($_GET["orientation"]) )
|
||||
$orientation = rawurldecode($_GET["orientation"]);
|
||||
else
|
||||
$orientation = "portrait";
|
||||
|
||||
if ( isset($_GET["base_path"]) ) {
|
||||
$base_path = rawurldecode($_GET["base_path"]);
|
||||
$file = $base_path . $file; # Set the input file
|
||||
}
|
||||
|
||||
if ( isset($_GET["options"]) ) {
|
||||
$options = $_GET["options"];
|
||||
}
|
||||
|
||||
$file_parts = explode_url($file);
|
||||
|
||||
/* Check to see if the input file is local and, if so, that the base path falls within that specified by DOMDPF_CHROOT */
|
||||
if(($file_parts['protocol'] == '' || $file_parts['protocol'] === 'file://')) {
|
||||
$file = realpath($file);
|
||||
if ( strpos($file, DOMPDF_CHROOT) !== 0 ) {
|
||||
throw new DOMPDF_Exception("Permission denied on $file. The file could not be found under the directory specified by DOMPDF_CHROOT.");
|
||||
}
|
||||
}
|
||||
|
||||
if($file_parts['protocol'] === 'php://') {
|
||||
throw new DOMPDF_Exception("Permission denied on $file. This script does not allow PHP streams.");
|
||||
}
|
||||
|
||||
$outfile = "dompdf_out.pdf"; # Don't allow them to set the output file
|
||||
$save_file = false; # Don't save the file
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
$dompdf = new DOMPDF();
|
||||
|
||||
if ( $file === "-" ) {
|
||||
$str = "";
|
||||
while ( !feof(STDIN) )
|
||||
$str .= fread(STDIN, 4096);
|
||||
|
||||
$dompdf->load_html($str);
|
||||
|
||||
} else
|
||||
$dompdf->load_html_file($file);
|
||||
|
||||
if ( isset($base_path) ) {
|
||||
$dompdf->set_base_path($base_path);
|
||||
}
|
||||
|
||||
$dompdf->set_paper($paper, $orientation);
|
||||
|
||||
$dompdf->render();
|
||||
|
||||
if ( $_dompdf_show_warnings ) {
|
||||
global $_dompdf_warnings;
|
||||
foreach ($_dompdf_warnings as $msg)
|
||||
echo $msg . "\n";
|
||||
echo $dompdf->get_canvas()->get_cpdf()->messages;
|
||||
flush();
|
||||
}
|
||||
|
||||
if ( $save_file ) {
|
||||
// if ( !is_writable($outfile) )
|
||||
// throw new DOMPDF_Exception("'$outfile' is not writable.");
|
||||
if ( strtolower(DOMPDF_PDF_BACKEND) === "gd" )
|
||||
$outfile = str_replace(".pdf", ".png", $outfile);
|
||||
|
||||
list($proto, $host, $path, $file) = explode_url($outfile);
|
||||
if ( $proto != "" ) // i.e. not file://
|
||||
$outfile = $file; // just save it locally, FIXME? could save it like wget: ./host/basepath/file
|
||||
|
||||
$outfile = realpath(dirname($outfile)) . DIRECTORY_SEPARATOR . basename($outfile);
|
||||
|
||||
if ( strpos($outfile, DOMPDF_CHROOT) !== 0 )
|
||||
throw new DOMPDF_Exception("Permission denied.");
|
||||
|
||||
file_put_contents($outfile, $dompdf->output( array("compress" => 0) ));
|
||||
exit(0);
|
||||
}
|
||||
|
||||
if ( !headers_sent() ) {
|
||||
$dompdf->stream($outfile, $options);
|
||||
}
|
||||
@@ -1,31 +0,0 @@
|
||||
<?php
|
||||
//define("DOMPDF_TEMP_DIR", "/tmp");
|
||||
//define("DOMPDF_CHROOT", DOMPDF_DIR);
|
||||
//define("DOMPDF_FONT_DIR", DOMPDF_DIR."/lib/fonts/");
|
||||
//define("DOMPDF_FONT_CACHE", DOMPDF_DIR."/lib/fonts/");
|
||||
//define("DOMPDF_UNICODE_ENABLED", true);
|
||||
//define("DOMPDF_PDF_BACKEND", "PDFLib");
|
||||
//define("DOMPDF_DEFAULT_MEDIA_TYPE", "print");
|
||||
//define("DOMPDF_DEFAULT_PAPER_SIZE", "letter");
|
||||
//define("DOMPDF_DEFAULT_FONT", "serif");
|
||||
//define("DOMPDF_DPI", 72);
|
||||
//define("DOMPDF_ENABLE_PHP", true);
|
||||
//define("DOMPDF_ENABLE_REMOTE", true);
|
||||
//define("DOMPDF_ENABLE_CSS_FLOAT", true);
|
||||
//define("DOMPDF_ENABLE_JAVASCRIPT", false);
|
||||
//define("DEBUGPNG", true);
|
||||
//define("DEBUGKEEPTEMP", true);
|
||||
//define("DEBUGCSS", true);
|
||||
//define("DEBUG_LAYOUT", true);
|
||||
//define("DEBUG_LAYOUT_LINES", false);
|
||||
//define("DEBUG_LAYOUT_BLOCKS", false);
|
||||
//define("DEBUG_LAYOUT_INLINE", false);
|
||||
//define("DOMPDF_FONT_HEIGHT_RATIO", 1.0);
|
||||
//define("DEBUG_LAYOUT_PADDINGBOX", false);
|
||||
//define("DOMPDF_LOG_OUTPUT_FILE", DOMPDF_FONT_DIR."log.htm");
|
||||
//define("DOMPDF_ENABLE_HTML5PARSER", true);
|
||||
//define("DOMPDF_ENABLE_FONTSUBSETTING", true);
|
||||
|
||||
// DOMPDF authentication
|
||||
//define("DOMPDF_ADMIN_USERNAME", "user");
|
||||
//define("DOMPDF_ADMIN_PASSWORD", "password");
|
||||
@@ -1,393 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* @package dompdf
|
||||
* @link http://dompdf.github.com/
|
||||
* @author Benj Carson <benjcarson@digitaljunkies.ca>
|
||||
* @author Helmut Tischer <htischer@weihenstephan.org>
|
||||
* @author Fabien Ménager <fabien.menager@gmail.com>
|
||||
* @autho Brian Sweeney <eclecticgeek@gmail.com>
|
||||
* @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License
|
||||
*/
|
||||
|
||||
if ( class_exists( 'DOMPDF' , false ) ) { return; }
|
||||
|
||||
PHP_VERSION >= 5.0 or die("DOMPDF requires PHP 5.0+");
|
||||
|
||||
/**
|
||||
* The root of your DOMPDF installation
|
||||
*/
|
||||
define("DOMPDF_DIR", str_replace(DIRECTORY_SEPARATOR, '/', realpath(dirname(__FILE__))));
|
||||
|
||||
/**
|
||||
* The location of the DOMPDF include directory
|
||||
*/
|
||||
define("DOMPDF_INC_DIR", DOMPDF_DIR . "/include");
|
||||
|
||||
/**
|
||||
* The location of the DOMPDF lib directory
|
||||
*/
|
||||
define("DOMPDF_LIB_DIR", DOMPDF_DIR . "/lib");
|
||||
|
||||
/**
|
||||
* Some installations don't have $_SERVER['DOCUMENT_ROOT']
|
||||
* http://fyneworks.blogspot.com/2007/08/php-documentroot-in-iis-windows-servers.html
|
||||
*/
|
||||
if( !isset($_SERVER['DOCUMENT_ROOT']) ) {
|
||||
$path = "";
|
||||
|
||||
if ( isset($_SERVER['SCRIPT_FILENAME']) )
|
||||
$path = $_SERVER['SCRIPT_FILENAME'];
|
||||
elseif ( isset($_SERVER['PATH_TRANSLATED']) )
|
||||
$path = str_replace('\\\\', '\\', $_SERVER['PATH_TRANSLATED']);
|
||||
|
||||
$_SERVER['DOCUMENT_ROOT'] = str_replace( '\\', '/', substr($path, 0, 0-strlen($_SERVER['PHP_SELF'])));
|
||||
}
|
||||
|
||||
/** Include the custom config file if it exists */
|
||||
if ( file_exists(DOMPDF_DIR . "/dompdf_config.custom.inc.php") ){
|
||||
require_once(DOMPDF_DIR . "/dompdf_config.custom.inc.php");
|
||||
}
|
||||
|
||||
//FIXME: Some function definitions rely on the constants defined by DOMPDF. However, might this location prove problematic?
|
||||
require_once(DOMPDF_INC_DIR . "/functions.inc.php");
|
||||
|
||||
/**
|
||||
* Username and password used by the configuration utility in www/
|
||||
*/
|
||||
def("DOMPDF_ADMIN_USERNAME", "user");
|
||||
def("DOMPDF_ADMIN_PASSWORD", "password");
|
||||
|
||||
/**
|
||||
* The location of the DOMPDF font directory
|
||||
*
|
||||
* The location of the directory where DOMPDF will store fonts and font metrics
|
||||
* Note: This directory must exist and be writable by the webserver process.
|
||||
* *Please note the trailing slash.*
|
||||
*
|
||||
* Notes regarding fonts:
|
||||
* Additional .afm font metrics can be added by executing load_font.php from command line.
|
||||
*
|
||||
* Only the original "Base 14 fonts" are present on all pdf viewers. Additional fonts must
|
||||
* be embedded in the pdf file or the PDF may not display correctly. This can significantly
|
||||
* increase file size unless font subsetting is enabled. Before embedding a font please
|
||||
* review your rights under the font license.
|
||||
*
|
||||
* Any font specification in the source HTML is translated to the closest font available
|
||||
* in the font directory.
|
||||
*
|
||||
* The pdf standard "Base 14 fonts" are:
|
||||
* Courier, Courier-Bold, Courier-BoldOblique, Courier-Oblique,
|
||||
* Helvetica, Helvetica-Bold, Helvetica-BoldOblique, Helvetica-Oblique,
|
||||
* Times-Roman, Times-Bold, Times-BoldItalic, Times-Italic,
|
||||
* Symbol, ZapfDingbats.
|
||||
*/
|
||||
def("DOMPDF_FONT_DIR", DOMPDF_DIR . "/lib/fonts/");
|
||||
|
||||
/**
|
||||
* The location of the DOMPDF font cache directory
|
||||
*
|
||||
* This directory contains the cached font metrics for the fonts used by DOMPDF.
|
||||
* This directory can be the same as DOMPDF_FONT_DIR
|
||||
*
|
||||
* Note: This directory must exist and be writable by the webserver process.
|
||||
*/
|
||||
def("DOMPDF_FONT_CACHE", DOMPDF_FONT_DIR);
|
||||
|
||||
/**
|
||||
* The location of a temporary directory.
|
||||
*
|
||||
* The directory specified must be writeable by the webserver process.
|
||||
* The temporary directory is required to download remote images and when
|
||||
* using the PFDLib back end.
|
||||
*/
|
||||
def("DOMPDF_TEMP_DIR", sys_get_temp_dir());
|
||||
|
||||
/**
|
||||
* ==== IMPORTANT ====
|
||||
*
|
||||
* dompdf's "chroot": Prevents dompdf from accessing system files or other
|
||||
* files on the webserver. All local files opened by dompdf must be in a
|
||||
* subdirectory of this directory. DO NOT set it to '/' since this could
|
||||
* allow an attacker to use dompdf to read any files on the server. This
|
||||
* should be an absolute path.
|
||||
* This is only checked on command line call by dompdf.php, but not by
|
||||
* direct class use like:
|
||||
* $dompdf = new DOMPDF(); $dompdf->load_html($htmldata); $dompdf->render(); $pdfdata = $dompdf->output();
|
||||
*/
|
||||
def("DOMPDF_CHROOT", realpath(DOMPDF_DIR));
|
||||
|
||||
/**
|
||||
* Whether to use Unicode fonts or not.
|
||||
*
|
||||
* When set to true the PDF backend must be set to "CPDF" and fonts must be
|
||||
* loaded via load_font.php.
|
||||
*
|
||||
* When enabled, dompdf can support all Unicode glyphs. Any glyphs used in a
|
||||
* document must be present in your fonts, however.
|
||||
*/
|
||||
def("DOMPDF_UNICODE_ENABLED", true);
|
||||
|
||||
/**
|
||||
* Whether to enable font subsetting or not.
|
||||
*/
|
||||
def("DOMPDF_ENABLE_FONTSUBSETTING", true);
|
||||
|
||||
/**
|
||||
* The PDF rendering backend to use
|
||||
*
|
||||
* Valid settings are 'PDFLib', 'CPDF' (the bundled R&OS PDF class), 'GD' and
|
||||
* 'auto'. 'auto' will look for PDFLib and use it if found, or if not it will
|
||||
* fall back on CPDF. 'GD' renders PDFs to graphic files. {@link
|
||||
* Canvas_Factory} ultimately determines which rendering class to instantiate
|
||||
* based on this setting.
|
||||
*
|
||||
* Both PDFLib & CPDF rendering backends provide sufficient rendering
|
||||
* capabilities for dompdf, however additional features (e.g. object,
|
||||
* image and font support, etc.) differ between backends. Please see
|
||||
* {@link PDFLib_Adapter} for more information on the PDFLib backend
|
||||
* and {@link CPDF_Adapter} and lib/class.pdf.php for more information
|
||||
* on CPDF. Also see the documentation for each backend at the links
|
||||
* below.
|
||||
*
|
||||
* The GD rendering backend is a little different than PDFLib and
|
||||
* CPDF. Several features of CPDF and PDFLib are not supported or do
|
||||
* not make any sense when creating image files. For example,
|
||||
* multiple pages are not supported, nor are PDF 'objects'. Have a
|
||||
* look at {@link GD_Adapter} for more information. GD support is
|
||||
* experimental, so use it at your own risk.
|
||||
*
|
||||
* @link http://www.pdflib.com
|
||||
* @link http://www.ros.co.nz/pdf
|
||||
* @link http://www.php.net/image
|
||||
*/
|
||||
def("DOMPDF_PDF_BACKEND", "CPDF");
|
||||
|
||||
/**
|
||||
* PDFlib license key
|
||||
*
|
||||
* If you are using a licensed, commercial version of PDFlib, specify
|
||||
* your license key here. If you are using PDFlib-Lite or are evaluating
|
||||
* the commercial version of PDFlib, comment out this setting.
|
||||
*
|
||||
* @link http://www.pdflib.com
|
||||
*
|
||||
* If pdflib present in web server and auto or selected explicitely above,
|
||||
* a real license code must exist!
|
||||
*/
|
||||
//def("DOMPDF_PDFLIB_LICENSE", "your license key here");
|
||||
|
||||
/**
|
||||
* html target media view which should be rendered into pdf.
|
||||
* List of types and parsing rules for future extensions:
|
||||
* http://www.w3.org/TR/REC-html40/types.html
|
||||
* screen, tty, tv, projection, handheld, print, braille, aural, all
|
||||
* Note: aural is deprecated in CSS 2.1 because it is replaced by speech in CSS 3.
|
||||
* Note, even though the generated pdf file is intended for print output,
|
||||
* the desired content might be different (e.g. screen or projection view of html file).
|
||||
* Therefore allow specification of content here.
|
||||
*/
|
||||
def("DOMPDF_DEFAULT_MEDIA_TYPE", "screen");
|
||||
|
||||
/**
|
||||
* The default paper size.
|
||||
*
|
||||
* North America standard is "letter"; other countries generally "a4"
|
||||
*
|
||||
* @see CPDF_Adapter::PAPER_SIZES for valid sizes
|
||||
*/
|
||||
def("DOMPDF_DEFAULT_PAPER_SIZE", "letter");
|
||||
|
||||
/**
|
||||
* The default font family
|
||||
*
|
||||
* Used if no suitable fonts can be found. This must exist in the font folder.
|
||||
* @var string
|
||||
*/
|
||||
def("DOMPDF_DEFAULT_FONT", "Helvetica");
|
||||
|
||||
/**
|
||||
* Image DPI setting
|
||||
*
|
||||
* This setting determines the default DPI setting for images and fonts. The
|
||||
* DPI may be overridden for inline images by explictly setting the
|
||||
* image's width & height style attributes (i.e. if the image's native
|
||||
* width is 600 pixels and you specify the image's width as 72 points,
|
||||
* the image will have a DPI of 600 in the rendered PDF. The DPI of
|
||||
* background images can not be overridden and is controlled entirely
|
||||
* via this parameter.
|
||||
*
|
||||
* For the purposes of DOMPDF, pixels per inch (PPI) = dots per inch (DPI).
|
||||
* If a size in html is given as px (or without unit as image size),
|
||||
* this tells the corresponding size in pt at 72 DPI.
|
||||
* This adjusts the relative sizes to be similar to the rendering of the
|
||||
* html page in a reference browser.
|
||||
*
|
||||
* In pdf, always 1 pt = 1/72 inch
|
||||
*
|
||||
* Rendering resolution of various browsers in px per inch:
|
||||
* Windows Firefox and Internet Explorer:
|
||||
* SystemControl->Display properties->FontResolution: Default:96, largefonts:120, custom:?
|
||||
* Linux Firefox:
|
||||
* about:config *resolution: Default:96
|
||||
* (xorg screen dimension in mm and Desktop font dpi settings are ignored)
|
||||
*
|
||||
* Take care about extra font/image zoom factor of browser.
|
||||
*
|
||||
* In images, <img> size in pixel attribute, img css style, are overriding
|
||||
* the real image dimension in px for rendering.
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
def("DOMPDF_DPI", 96);
|
||||
|
||||
/**
|
||||
* Enable inline PHP
|
||||
*
|
||||
* If this setting is set to true then DOMPDF will automatically evaluate
|
||||
* inline PHP contained within <script type="text/php"> ... </script> tags.
|
||||
*
|
||||
* Enabling this for documents you do not trust (e.g. arbitrary remote html
|
||||
* pages) is a security risk. Set this option to false if you wish to process
|
||||
* untrusted documents.
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
def("DOMPDF_ENABLE_PHP", false);
|
||||
|
||||
/**
|
||||
* Enable inline Javascript
|
||||
*
|
||||
* If this setting is set to true then DOMPDF will automatically insert
|
||||
* JavaScript code contained within <script type="text/javascript"> ... </script> tags.
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
def("DOMPDF_ENABLE_JAVASCRIPT", true);
|
||||
|
||||
/**
|
||||
* Enable remote file access
|
||||
*
|
||||
* If this setting is set to true, DOMPDF will access remote sites for
|
||||
* images and CSS files as required.
|
||||
* This is required for part of test case www/test/image_variants.html through www/examples.php
|
||||
*
|
||||
* Attention!
|
||||
* This can be a security risk, in particular in combination with DOMPDF_ENABLE_PHP and
|
||||
* allowing remote access to dompdf.php or on allowing remote html code to be passed to
|
||||
* $dompdf = new DOMPDF(); $dompdf->load_html(...);
|
||||
* This allows anonymous users to download legally doubtful internet content which on
|
||||
* tracing back appears to being downloaded by your server, or allows malicious php code
|
||||
* in remote html pages to be executed by your server with your account privileges.
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
def("DOMPDF_ENABLE_REMOTE", false);
|
||||
|
||||
/**
|
||||
* The debug output log
|
||||
* @var string
|
||||
*/
|
||||
def("DOMPDF_LOG_OUTPUT_FILE", DOMPDF_FONT_DIR."log.htm");
|
||||
|
||||
/**
|
||||
* A ratio applied to the fonts height to be more like browsers' line height
|
||||
*/
|
||||
def("DOMPDF_FONT_HEIGHT_RATIO", 1.1);
|
||||
|
||||
/**
|
||||
* Enable CSS float
|
||||
*
|
||||
* Allows people to disabled CSS float support
|
||||
* @var bool
|
||||
*/
|
||||
def("DOMPDF_ENABLE_CSS_FLOAT", true);
|
||||
|
||||
/**
|
||||
* Enable the built in DOMPDF autoloader
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
def("DOMPDF_ENABLE_AUTOLOAD", true);
|
||||
|
||||
/**
|
||||
* Prepend the DOMPDF autoload function to the spl_autoload stack
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
def("DOMPDF_AUTOLOAD_PREPEND", false);
|
||||
|
||||
/**
|
||||
* Use the more-than-experimental HTML5 Lib parser
|
||||
*/
|
||||
def("DOMPDF_ENABLE_HTML5PARSER", false);
|
||||
require_once(DOMPDF_LIB_DIR . "/html5lib/Parser.php");
|
||||
|
||||
// ### End of user-configurable options ###
|
||||
|
||||
/**
|
||||
* Load autoloader
|
||||
*/
|
||||
if (DOMPDF_ENABLE_AUTOLOAD) {
|
||||
require_once(DOMPDF_INC_DIR . "/autoload.inc.php");
|
||||
require_once(DOMPDF_LIB_DIR . "/php-font-lib/classes/Font.php");
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensure that PHP is working with text internally using UTF8 character encoding.
|
||||
*/
|
||||
mb_internal_encoding('UTF-8');
|
||||
|
||||
/**
|
||||
* Global array of warnings generated by DomDocument parser and
|
||||
* stylesheet class
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
global $_dompdf_warnings;
|
||||
$_dompdf_warnings = array();
|
||||
|
||||
/**
|
||||
* If true, $_dompdf_warnings is dumped on script termination when using
|
||||
* dompdf/dompdf.php or after rendering when using the DOMPDF class.
|
||||
* When using the class, setting this value to true will prevent you from
|
||||
* streaming the PDF.
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
global $_dompdf_show_warnings;
|
||||
$_dompdf_show_warnings = false;
|
||||
|
||||
/**
|
||||
* If true, the entire tree is dumped to stdout in dompdf.cls.php.
|
||||
* Setting this value to true will prevent you from streaming the PDF.
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
global $_dompdf_debug;
|
||||
$_dompdf_debug = false;
|
||||
|
||||
/**
|
||||
* Array of enabled debug message types
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
global $_DOMPDF_DEBUG_TYPES;
|
||||
$_DOMPDF_DEBUG_TYPES = array(); //array("page-break" => 1);
|
||||
|
||||
/* Optionally enable different classes of debug output before the pdf content.
|
||||
* Visible if displaying pdf as text,
|
||||
* E.g. on repeated display of same pdf in browser when pdf is not taken out of
|
||||
* the browser cache and the premature output prevents setting of the mime type.
|
||||
*/
|
||||
def('DEBUGPNG', false);
|
||||
def('DEBUGKEEPTEMP', false);
|
||||
def('DEBUGCSS', false);
|
||||
|
||||
/* Layout debugging. Will display rectangles around different block levels.
|
||||
* Visible in the PDF itself.
|
||||
*/
|
||||
def('DEBUG_LAYOUT', false);
|
||||
def('DEBUG_LAYOUT_LINES', false);
|
||||
def('DEBUG_LAYOUT_BLOCKS', false);
|
||||
def('DEBUG_LAYOUT_INLINE', false);
|
||||
def('DEBUG_LAYOUT_PADDINGBOX', false);
|
||||
@@ -1,125 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* @package dompdf
|
||||
* @link http://dompdf.github.com/
|
||||
* @author Benj Carson <benjcarson@digitaljunkies.ca>
|
||||
* @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License
|
||||
*/
|
||||
|
||||
/**
|
||||
* Positions absolutely positioned frames
|
||||
*/
|
||||
class Absolute_Positioner extends Positioner {
|
||||
|
||||
function __construct(Frame_Decorator $frame) { parent::__construct($frame); }
|
||||
|
||||
function position() {
|
||||
|
||||
$frame = $this->_frame;
|
||||
$style = $frame->get_style();
|
||||
|
||||
$p = $frame->find_positionned_parent();
|
||||
|
||||
list($x, $y, $w, $h) = $frame->get_containing_block();
|
||||
|
||||
$top = $style->length_in_pt($style->top, $h);
|
||||
$right = $style->length_in_pt($style->right, $w);
|
||||
$bottom = $style->length_in_pt($style->bottom, $h);
|
||||
$left = $style->length_in_pt($style->left, $w);
|
||||
|
||||
if ( $p && !($left === "auto" && $right === "auto") ) {
|
||||
// Get the parent's padding box (see http://www.w3.org/TR/CSS21/visuren.html#propdef-top)
|
||||
list($x, $y, $w, $h) = $p->get_padding_box();
|
||||
}
|
||||
|
||||
list($width, $height) = array($frame->get_margin_width(), $frame->get_margin_height());
|
||||
|
||||
$orig_style = $this->_frame->get_original_style();
|
||||
$orig_width = $orig_style->width;
|
||||
$orig_height = $orig_style->height;
|
||||
|
||||
/****************************
|
||||
|
||||
Width auto:
|
||||
____________| left=auto | left=fixed |
|
||||
right=auto | A | B |
|
||||
right=fixed | C | D |
|
||||
|
||||
Width fixed:
|
||||
____________| left=auto | left=fixed |
|
||||
right=auto | E | F |
|
||||
right=fixed | G | H |
|
||||
|
||||
*****************************/
|
||||
|
||||
if ( $left === "auto" ) {
|
||||
if ( $right === "auto" ) {
|
||||
// A or E - Keep the frame at the same position
|
||||
$x = $x + $frame->find_block_parent()->get_current_line_box()->w;
|
||||
}
|
||||
else {
|
||||
if ( $orig_width === "auto" ) {
|
||||
// C
|
||||
$x += $w - $width - $right;
|
||||
}
|
||||
else {
|
||||
// G
|
||||
$x += $w - $width - $right;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
if ( $right === "auto" ) {
|
||||
// B or F
|
||||
$x += $left;
|
||||
}
|
||||
else {
|
||||
if ( $orig_width === "auto" ) {
|
||||
// D - TODO change width
|
||||
$x += $left;
|
||||
}
|
||||
else {
|
||||
// H - Everything is fixed: left + width win
|
||||
$x += $left;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// The same vertically
|
||||
if ( $top === "auto" ) {
|
||||
if ( $bottom === "auto" ) {
|
||||
// A or E - Keep the frame at the same position
|
||||
$y = $frame->find_block_parent()->get_current_line_box()->y;
|
||||
}
|
||||
else {
|
||||
if ( $orig_height === "auto" ) {
|
||||
// C
|
||||
$y += $h - $height - $bottom;
|
||||
}
|
||||
else {
|
||||
// G
|
||||
$y += $h - $height - $bottom;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
if ( $bottom === "auto" ) {
|
||||
// B or F
|
||||
$y += $top;
|
||||
}
|
||||
else {
|
||||
if ( $orig_height === "auto" ) {
|
||||
// D - TODO change height
|
||||
$y += $top;
|
||||
}
|
||||
else {
|
||||
// H - Everything is fixed: top + height win
|
||||
$y += $top;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$frame->set_position($x, $y);
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,759 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* @package dompdf
|
||||
* @link http://dompdf.github.com/
|
||||
* @author Benj Carson <benjcarson@digitaljunkies.ca>
|
||||
* @author Helmut Tischer <htischer@weihenstephan.org>
|
||||
* @author Fabien Ménager <fabien.menager@gmail.com>
|
||||
* @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License
|
||||
*/
|
||||
|
||||
/**
|
||||
* Base renderer class
|
||||
*
|
||||
* @access private
|
||||
* @package dompdf
|
||||
*/
|
||||
abstract class Abstract_Renderer {
|
||||
|
||||
/**
|
||||
* Rendering backend
|
||||
*
|
||||
* @var Canvas
|
||||
*/
|
||||
protected $_canvas;
|
||||
|
||||
/**
|
||||
* Current dompdf instance
|
||||
*
|
||||
* @var DOMPDF
|
||||
*/
|
||||
protected $_dompdf;
|
||||
|
||||
/**
|
||||
* Class constructor
|
||||
*
|
||||
* @param DOMPDF $dompdf The current dompdf instance
|
||||
*/
|
||||
function __construct(DOMPDF $dompdf) {
|
||||
$this->_dompdf = $dompdf;
|
||||
$this->_canvas = $dompdf->get_canvas();
|
||||
}
|
||||
|
||||
/**
|
||||
* Render a frame.
|
||||
*
|
||||
* Specialized in child classes
|
||||
*
|
||||
* @param Frame $frame The frame to render
|
||||
*/
|
||||
abstract function render(Frame $frame);
|
||||
|
||||
//........................................................................
|
||||
|
||||
/**
|
||||
* Render a background image over a rectangular area
|
||||
*
|
||||
* @param string $url The background image to load
|
||||
* @param float $x The left edge of the rectangular area
|
||||
* @param float $y The top edge of the rectangular area
|
||||
* @param float $width The width of the rectangular area
|
||||
* @param float $height The height of the rectangular area
|
||||
* @param Style $style The associated Style object
|
||||
*
|
||||
* @throws Exception
|
||||
*/
|
||||
protected function _background_image($url, $x, $y, $width, $height, $style) {
|
||||
if ( !function_exists("imagecreatetruecolor") ) {
|
||||
throw new Exception("The PHP GD extension is required, but is not installed.");
|
||||
}
|
||||
|
||||
$sheet = $style->get_stylesheet();
|
||||
|
||||
// Skip degenerate cases
|
||||
if ( $width == 0 || $height == 0 ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$box_width = $width;
|
||||
$box_height = $height;
|
||||
|
||||
//debugpng
|
||||
if (DEBUGPNG) print '[_background_image '.$url.']';
|
||||
|
||||
list($img, $type, /*$msg*/) = Image_Cache::resolve_url(
|
||||
$url,
|
||||
$sheet->get_protocol(),
|
||||
$sheet->get_host(),
|
||||
$sheet->get_base_path(),
|
||||
$this->_dompdf
|
||||
);
|
||||
|
||||
// Bail if the image is no good
|
||||
if ( Image_Cache::is_broken($img) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
//Try to optimize away reading and composing of same background multiple times
|
||||
//Postponing read with imagecreatefrom ...()
|
||||
//final composition parameters and name not known yet
|
||||
//Therefore read dimension directly from file, instead of creating gd object first.
|
||||
//$img_w = imagesx($src); $img_h = imagesy($src);
|
||||
|
||||
list($img_w, $img_h) = dompdf_getimagesize($img);
|
||||
if (!isset($img_w) || $img_w == 0 || !isset($img_h) || $img_h == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
$repeat = $style->background_repeat;
|
||||
$dpi = $this->_dompdf->get_option("dpi");
|
||||
|
||||
//Increase background resolution and dependent box size according to image resolution to be placed in
|
||||
//Then image can be copied in without resize
|
||||
$bg_width = round((float)($width * $dpi) / 72);
|
||||
$bg_height = round((float)($height * $dpi) / 72);
|
||||
|
||||
//Need %bg_x, $bg_y as background pos, where img starts, converted to pixel
|
||||
|
||||
list($bg_x, $bg_y) = $style->background_position;
|
||||
|
||||
if ( is_percent($bg_x) ) {
|
||||
// The point $bg_x % from the left edge of the image is placed
|
||||
// $bg_x % from the left edge of the background rectangle
|
||||
$p = ((float)$bg_x)/100.0;
|
||||
$x1 = $p * $img_w;
|
||||
$x2 = $p * $bg_width;
|
||||
|
||||
$bg_x = $x2 - $x1;
|
||||
}
|
||||
else {
|
||||
$bg_x = (float)($style->length_in_pt($bg_x)*$dpi) / 72;
|
||||
}
|
||||
|
||||
$bg_x = round($bg_x + $style->length_in_pt($style->border_left_width)*$dpi / 72);
|
||||
|
||||
if ( is_percent($bg_y) ) {
|
||||
// The point $bg_y % from the left edge of the image is placed
|
||||
// $bg_y % from the left edge of the background rectangle
|
||||
$p = ((float)$bg_y)/100.0;
|
||||
$y1 = $p * $img_h;
|
||||
$y2 = $p * $bg_height;
|
||||
|
||||
$bg_y = $y2 - $y1;
|
||||
}
|
||||
else {
|
||||
$bg_y = (float)($style->length_in_pt($bg_y)*$dpi) / 72;
|
||||
}
|
||||
|
||||
$bg_y = round($bg_y + $style->length_in_pt($style->border_top_width)*$dpi / 72);
|
||||
|
||||
//clip background to the image area on partial repeat. Nothing to do if img off area
|
||||
//On repeat, normalize start position to the tile at immediate left/top or 0/0 of area
|
||||
//On no repeat with positive offset: move size/start to have offset==0
|
||||
//Handle x/y Dimensions separately
|
||||
|
||||
if ( $repeat !== "repeat" && $repeat !== "repeat-x" ) {
|
||||
//No repeat x
|
||||
if ($bg_x < 0) {
|
||||
$bg_width = $img_w + $bg_x;
|
||||
}
|
||||
else {
|
||||
$x += ($bg_x * 72)/$dpi;
|
||||
$bg_width = $bg_width - $bg_x;
|
||||
if ($bg_width > $img_w) {
|
||||
$bg_width = $img_w;
|
||||
}
|
||||
$bg_x = 0;
|
||||
}
|
||||
|
||||
if ($bg_width <= 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
$width = (float)($bg_width * 72)/$dpi;
|
||||
}
|
||||
else {
|
||||
//repeat x
|
||||
if ($bg_x < 0) {
|
||||
$bg_x = - ((-$bg_x) % $img_w);
|
||||
}
|
||||
else {
|
||||
$bg_x = $bg_x % $img_w;
|
||||
if ($bg_x > 0) {
|
||||
$bg_x -= $img_w;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( $repeat !== "repeat" && $repeat !== "repeat-y" ) {
|
||||
//no repeat y
|
||||
if ($bg_y < 0) {
|
||||
$bg_height = $img_h + $bg_y;
|
||||
}
|
||||
else {
|
||||
$y += ($bg_y * 72)/$dpi;
|
||||
$bg_height = $bg_height - $bg_y;
|
||||
if ($bg_height > $img_h) {
|
||||
$bg_height = $img_h;
|
||||
}
|
||||
$bg_y = 0;
|
||||
}
|
||||
if ($bg_height <= 0) {
|
||||
return;
|
||||
}
|
||||
$height = (float)($bg_height * 72)/$dpi;
|
||||
}
|
||||
else {
|
||||
//repeat y
|
||||
if ($bg_y < 0) {
|
||||
$bg_y = - ((-$bg_y) % $img_h);
|
||||
}
|
||||
else {
|
||||
$bg_y = $bg_y % $img_h;
|
||||
if ($bg_y > 0) {
|
||||
$bg_y -= $img_h;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//Optimization, if repeat has no effect
|
||||
if ( $repeat === "repeat" && $bg_y <= 0 && $img_h+$bg_y >= $bg_height ) {
|
||||
$repeat = "repeat-x";
|
||||
}
|
||||
|
||||
if ( $repeat === "repeat" && $bg_x <= 0 && $img_w+$bg_x >= $bg_width ) {
|
||||
$repeat = "repeat-y";
|
||||
}
|
||||
|
||||
if ( ($repeat === "repeat-x" && $bg_x <= 0 && $img_w+$bg_x >= $bg_width) ||
|
||||
($repeat === "repeat-y" && $bg_y <= 0 && $img_h+$bg_y >= $bg_height) ) {
|
||||
$repeat = "no-repeat";
|
||||
}
|
||||
|
||||
//Use filename as indicator only
|
||||
//different names for different variants to have different copies in the pdf
|
||||
//This is not dependent of background color of box! .'_'.(is_array($bg_color) ? $bg_color["hex"] : $bg_color)
|
||||
//Note: Here, bg_* are the start values, not end values after going through the tile loops!
|
||||
|
||||
$filedummy = $img;
|
||||
|
||||
$is_png = false;
|
||||
$filedummy .= '_'.$bg_width.'_'.$bg_height.'_'.$bg_x.'_'.$bg_y.'_'.$repeat;
|
||||
|
||||
//Optimization to avoid multiple times rendering the same image.
|
||||
//If check functions are existing and identical image already cached,
|
||||
//then skip creation of duplicate, because it is not needed by addImagePng
|
||||
if ( $this->_canvas instanceof CPDF_Adapter &&
|
||||
$this->_canvas->get_cpdf()->image_iscached($filedummy) ) {
|
||||
$bg = null;
|
||||
}
|
||||
|
||||
else {
|
||||
|
||||
// Create a new image to fit over the background rectangle
|
||||
$bg = imagecreatetruecolor($bg_width, $bg_height);
|
||||
|
||||
switch (strtolower($type)) {
|
||||
case IMAGETYPE_PNG:
|
||||
$is_png = true;
|
||||
imagesavealpha($bg, true);
|
||||
imagealphablending($bg, false);
|
||||
$src = imagecreatefrompng($img);
|
||||
break;
|
||||
|
||||
case IMAGETYPE_JPEG:
|
||||
$src = imagecreatefromjpeg($img);
|
||||
break;
|
||||
|
||||
case IMAGETYPE_GIF:
|
||||
$src = imagecreatefromgif($img);
|
||||
break;
|
||||
|
||||
case IMAGETYPE_BMP:
|
||||
$src = imagecreatefrombmp($img);
|
||||
break;
|
||||
|
||||
default:
|
||||
return; // Unsupported image type
|
||||
}
|
||||
|
||||
if ( $src == null ) {
|
||||
return;
|
||||
}
|
||||
|
||||
//Background color if box is not relevant here
|
||||
//Non transparent image: box clipped to real size. Background non relevant.
|
||||
//Transparent image: The image controls the transparency and lets shine through whatever background.
|
||||
//However on transparent image preset the composed image with the transparency color,
|
||||
//to keep the transparency when copying over the non transparent parts of the tiles.
|
||||
$ti = imagecolortransparent($src);
|
||||
|
||||
if ( $ti >= 0 ) {
|
||||
$tc = imagecolorsforindex($src, $ti);
|
||||
$ti = imagecolorallocate($bg, $tc['red'], $tc['green'], $tc['blue']);
|
||||
imagefill($bg, 0, 0, $ti);
|
||||
imagecolortransparent($bg, $ti);
|
||||
}
|
||||
|
||||
//This has only an effect for the non repeatable dimension.
|
||||
//compute start of src and dest coordinates of the single copy
|
||||
if ( $bg_x < 0 ) {
|
||||
$dst_x = 0;
|
||||
$src_x = -$bg_x;
|
||||
}
|
||||
else {
|
||||
$src_x = 0;
|
||||
$dst_x = $bg_x;
|
||||
}
|
||||
|
||||
if ( $bg_y < 0 ) {
|
||||
$dst_y = 0;
|
||||
$src_y = -$bg_y;
|
||||
}
|
||||
else {
|
||||
$src_y = 0;
|
||||
$dst_y = $bg_y;
|
||||
}
|
||||
|
||||
//For historical reasons exchange meanings of variables:
|
||||
//start_* will be the start values, while bg_* will be the temporary start values in the loops
|
||||
$start_x = $bg_x;
|
||||
$start_y = $bg_y;
|
||||
|
||||
// Copy regions from the source image to the background
|
||||
if ( $repeat === "no-repeat" ) {
|
||||
|
||||
// Simply place the image on the background
|
||||
imagecopy($bg, $src, $dst_x, $dst_y, $src_x, $src_y, $img_w, $img_h);
|
||||
|
||||
}
|
||||
else if ( $repeat === "repeat-x" ) {
|
||||
|
||||
for ( $bg_x = $start_x; $bg_x < $bg_width; $bg_x += $img_w ) {
|
||||
if ( $bg_x < 0 ) {
|
||||
$dst_x = 0;
|
||||
$src_x = -$bg_x;
|
||||
$w = $img_w + $bg_x;
|
||||
}
|
||||
else {
|
||||
$dst_x = $bg_x;
|
||||
$src_x = 0;
|
||||
$w = $img_w;
|
||||
}
|
||||
imagecopy($bg, $src, $dst_x, $dst_y, $src_x, $src_y, $w, $img_h);
|
||||
}
|
||||
|
||||
}
|
||||
else if ( $repeat === "repeat-y" ) {
|
||||
|
||||
for ( $bg_y = $start_y; $bg_y < $bg_height; $bg_y += $img_h ) {
|
||||
if ( $bg_y < 0 ) {
|
||||
$dst_y = 0;
|
||||
$src_y = -$bg_y;
|
||||
$h = $img_h + $bg_y;
|
||||
}
|
||||
else {
|
||||
$dst_y = $bg_y;
|
||||
$src_y = 0;
|
||||
$h = $img_h;
|
||||
}
|
||||
imagecopy($bg, $src, $dst_x, $dst_y, $src_x, $src_y, $img_w, $h);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
else if ( $repeat === "repeat" ) {
|
||||
|
||||
for ( $bg_y = $start_y; $bg_y < $bg_height; $bg_y += $img_h ) {
|
||||
for ( $bg_x = $start_x; $bg_x < $bg_width; $bg_x += $img_w ) {
|
||||
|
||||
if ( $bg_x < 0 ) {
|
||||
$dst_x = 0;
|
||||
$src_x = -$bg_x;
|
||||
$w = $img_w + $bg_x;
|
||||
}
|
||||
else {
|
||||
$dst_x = $bg_x;
|
||||
$src_x = 0;
|
||||
$w = $img_w;
|
||||
}
|
||||
|
||||
if ( $bg_y < 0 ) {
|
||||
$dst_y = 0;
|
||||
$src_y = -$bg_y;
|
||||
$h = $img_h + $bg_y;
|
||||
}
|
||||
else {
|
||||
$dst_y = $bg_y;
|
||||
$src_y = 0;
|
||||
$h = $img_h;
|
||||
}
|
||||
imagecopy($bg, $src, $dst_x, $dst_y, $src_x, $src_y, $w, $h);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
else {
|
||||
print 'Unknown repeat!';
|
||||
}
|
||||
|
||||
imagedestroy($src);
|
||||
|
||||
} /* End optimize away creation of duplicates */
|
||||
|
||||
$this->_canvas->clipping_rectangle($x, $y, $box_width, $box_height);
|
||||
|
||||
//img: image url string
|
||||
//img_w, img_h: original image size in px
|
||||
//width, height: box size in pt
|
||||
//bg_width, bg_height: box size in px
|
||||
//x, y: left/top edge of box on page in pt
|
||||
//start_x, start_y: placement of image relative to pattern
|
||||
//$repeat: repeat mode
|
||||
//$bg: GD object of result image
|
||||
//$src: GD object of original image
|
||||
//When using cpdf and optimization to direct png creation from gd object is available,
|
||||
//don't create temp file, but place gd object directly into the pdf
|
||||
if ( !$is_png && $this->_canvas instanceof CPDF_Adapter ) {
|
||||
// Note: CPDF_Adapter image converts y position
|
||||
$this->_canvas->get_cpdf()->addImagePng($filedummy, $x, $this->_canvas->get_height() - $y - $height, $width, $height, $bg);
|
||||
}
|
||||
|
||||
else {
|
||||
$tmp_dir = $this->_dompdf->get_option("temp_dir");
|
||||
$tmp_name = tempnam($tmp_dir, "bg_dompdf_img_");
|
||||
@unlink($tmp_name);
|
||||
$tmp_file = "$tmp_name.png";
|
||||
|
||||
//debugpng
|
||||
if (DEBUGPNG) print '[_background_image '.$tmp_file.']';
|
||||
|
||||
imagepng($bg, $tmp_file);
|
||||
$this->_canvas->image($tmp_file, $x, $y, $width, $height);
|
||||
imagedestroy($bg);
|
||||
|
||||
//debugpng
|
||||
if (DEBUGPNG) print '[_background_image unlink '.$tmp_file.']';
|
||||
|
||||
if (!DEBUGKEEPTEMP) {
|
||||
unlink($tmp_file);
|
||||
}
|
||||
}
|
||||
|
||||
$this->_canvas->clipping_end();
|
||||
}
|
||||
|
||||
protected function _get_dash_pattern($style, $width) {
|
||||
$pattern = array();
|
||||
|
||||
switch ($style) {
|
||||
default:
|
||||
/*case "solid":
|
||||
case "double":
|
||||
case "groove":
|
||||
case "inset":
|
||||
case "outset":
|
||||
case "ridge":*/
|
||||
case "none": break;
|
||||
|
||||
case "dotted":
|
||||
if ( $width <= 1 )
|
||||
$pattern = array($width, $width*2);
|
||||
else
|
||||
$pattern = array($width);
|
||||
break;
|
||||
|
||||
case "dashed":
|
||||
$pattern = array(3 * $width);
|
||||
break;
|
||||
}
|
||||
|
||||
return $pattern;
|
||||
}
|
||||
|
||||
protected function _border_none($x, $y, $length, $color, $widths, $side, $corner_style = "bevel", $r1 = 0, $r2 = 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
protected function _border_hidden($x, $y, $length, $color, $widths, $side, $corner_style = "bevel", $r1 = 0, $r2 = 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Border rendering functions
|
||||
|
||||
protected function _border_dotted($x, $y, $length, $color, $widths, $side, $corner_style = "bevel", $r1 = 0, $r2 = 0) {
|
||||
$this->_border_line($x, $y, $length, $color, $widths, $side, $corner_style, "dotted", $r1, $r2);
|
||||
}
|
||||
|
||||
|
||||
protected function _border_dashed($x, $y, $length, $color, $widths, $side, $corner_style = "bevel", $r1 = 0, $r2 = 0) {
|
||||
$this->_border_line($x, $y, $length, $color, $widths, $side, $corner_style, "dashed", $r1, $r2);
|
||||
}
|
||||
|
||||
|
||||
protected function _border_solid($x, $y, $length, $color, $widths, $side, $corner_style = "bevel", $r1 = 0, $r2 = 0) {
|
||||
// TODO: Solve rendering where one corner is beveled (radius == 0), one corner isn't.
|
||||
if ( $corner_style !== "bevel" || $r1 > 0 || $r2 > 0 ) {
|
||||
// do it the simple way
|
||||
$this->_border_line($x, $y, $length, $color, $widths, $side, $corner_style, "solid", $r1, $r2);
|
||||
return;
|
||||
}
|
||||
|
||||
list($top, $right, $bottom, $left) = $widths;
|
||||
|
||||
// All this polygon business is for beveled corners...
|
||||
switch ($side) {
|
||||
case "top":
|
||||
$points = array($x, $y,
|
||||
$x + $length, $y,
|
||||
$x + $length - $right, $y + $top,
|
||||
$x + $left, $y + $top);
|
||||
$this->_canvas->polygon($points, $color, null, null, true);
|
||||
break;
|
||||
|
||||
case "bottom":
|
||||
$points = array($x, $y,
|
||||
$x + $length, $y,
|
||||
$x + $length - $right, $y - $bottom,
|
||||
$x + $left, $y - $bottom);
|
||||
$this->_canvas->polygon($points, $color, null, null, true);
|
||||
break;
|
||||
|
||||
case "left":
|
||||
$points = array($x, $y,
|
||||
$x, $y + $length,
|
||||
$x + $left, $y + $length - $bottom,
|
||||
$x + $left, $y + $top);
|
||||
$this->_canvas->polygon($points, $color, null, null, true);
|
||||
break;
|
||||
|
||||
case "right":
|
||||
$points = array($x, $y,
|
||||
$x, $y + $length,
|
||||
$x - $right, $y + $length - $bottom,
|
||||
$x - $right, $y + $top);
|
||||
$this->_canvas->polygon($points, $color, null, null, true);
|
||||
break;
|
||||
|
||||
default:
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
protected function _apply_ratio($side, $ratio, $top, $right, $bottom, $left, &$x, &$y, &$length, &$r1, &$r2) {
|
||||
switch ($side) {
|
||||
|
||||
case "top":
|
||||
$r1 -= $left * $ratio;
|
||||
$r2 -= $right * $ratio;
|
||||
$x += $left * $ratio;
|
||||
$y += $top * $ratio;
|
||||
$length -= $left * $ratio + $right * $ratio;
|
||||
break;
|
||||
|
||||
case "bottom":
|
||||
$r1 -= $right * $ratio;
|
||||
$r2 -= $left * $ratio;
|
||||
$x += $left * $ratio;
|
||||
$y -= $bottom * $ratio;
|
||||
$length -= $left * $ratio + $right * $ratio;
|
||||
break;
|
||||
|
||||
case "left":
|
||||
$r1 -= $top * $ratio;
|
||||
$r2 -= $bottom * $ratio;
|
||||
$x += $left * $ratio;
|
||||
$y += $top * $ratio;
|
||||
$length -= $top * $ratio + $bottom * $ratio;
|
||||
break;
|
||||
|
||||
case "right":
|
||||
$r1 -= $bottom * $ratio;
|
||||
$r2 -= $top * $ratio;
|
||||
$x -= $right * $ratio;
|
||||
$y += $top * $ratio;
|
||||
$length -= $top * $ratio + $bottom * $ratio;
|
||||
break;
|
||||
|
||||
default:
|
||||
return;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
protected function _border_double($x, $y, $length, $color, $widths, $side, $corner_style = "bevel", $r1 = 0, $r2 = 0) {
|
||||
list($top, $right, $bottom, $left) = $widths;
|
||||
|
||||
$third_widths = array($top / 3, $right / 3, $bottom / 3, $left / 3);
|
||||
|
||||
// draw the outer border
|
||||
$this->_border_solid($x, $y, $length, $color, $third_widths, $side, $corner_style, $r1, $r2);
|
||||
|
||||
$this->_apply_ratio($side, 2/3, $top, $right, $bottom, $left, $x, $y, $length, $r1, $r2);
|
||||
|
||||
$this->_border_solid($x, $y, $length, $color, $third_widths, $side, $corner_style, $r1, $r2);
|
||||
}
|
||||
|
||||
protected function _border_groove($x, $y, $length, $color, $widths, $side, $corner_style = "bevel", $r1 = 0, $r2 = 0) {
|
||||
list($top, $right, $bottom, $left) = $widths;
|
||||
|
||||
$half_widths = array($top / 2, $right / 2, $bottom / 2, $left / 2);
|
||||
|
||||
$this->_border_inset($x, $y, $length, $color, $half_widths, $side, $corner_style, $r1, $r2);
|
||||
|
||||
$this->_apply_ratio($side, 0.5, $top, $right, $bottom, $left, $x, $y, $length, $r1, $r2);
|
||||
|
||||
$this->_border_outset($x, $y, $length, $color, $half_widths, $side, $corner_style, $r1, $r2);
|
||||
|
||||
}
|
||||
|
||||
protected function _border_ridge($x, $y, $length, $color, $widths, $side, $corner_style = "bevel", $r1 = 0, $r2 = 0) {
|
||||
list($top, $right, $bottom, $left) = $widths;
|
||||
|
||||
$half_widths = array($top / 2, $right / 2, $bottom / 2, $left / 2);
|
||||
|
||||
$this->_border_outset($x, $y, $length, $color, $half_widths, $side, $corner_style, $r1, $r2);
|
||||
|
||||
$this->_apply_ratio($side, 0.5, $top, $right, $bottom, $left, $x, $y, $length, $r1, $r2);
|
||||
|
||||
$this->_border_inset($x, $y, $length, $color, $half_widths, $side, $corner_style, $r1, $r2);
|
||||
|
||||
}
|
||||
|
||||
protected function _tint($c) {
|
||||
if ( !is_numeric($c) )
|
||||
return $c;
|
||||
|
||||
return min(1, $c + 0.16);
|
||||
}
|
||||
|
||||
protected function _shade($c) {
|
||||
if ( !is_numeric($c) )
|
||||
return $c;
|
||||
|
||||
return max(0, $c - 0.33);
|
||||
}
|
||||
|
||||
protected function _border_inset($x, $y, $length, $color, $widths, $side, $corner_style = "bevel", $r1 = 0, $r2 = 0) {
|
||||
switch ($side) {
|
||||
case "top":
|
||||
case "left":
|
||||
$shade = array_map(array($this, "_shade"), $color);
|
||||
$this->_border_solid($x, $y, $length, $shade, $widths, $side, $corner_style, $r1, $r2);
|
||||
break;
|
||||
|
||||
case "bottom":
|
||||
case "right":
|
||||
$tint = array_map(array($this, "_tint"), $color);
|
||||
$this->_border_solid($x, $y, $length, $tint, $widths, $side, $corner_style, $r1, $r2);
|
||||
break;
|
||||
|
||||
default:
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
protected function _border_outset($x, $y, $length, $color, $widths, $side, $corner_style = "bevel", $r1 = 0, $r2 = 0) {
|
||||
switch ($side) {
|
||||
case "top":
|
||||
case "left":
|
||||
$tint = array_map(array($this, "_tint"), $color);
|
||||
$this->_border_solid($x, $y, $length, $tint, $widths, $side, $corner_style, $r1, $r2);
|
||||
break;
|
||||
|
||||
case "bottom":
|
||||
case "right":
|
||||
$shade = array_map(array($this, "_shade"), $color);
|
||||
$this->_border_solid($x, $y, $length, $shade, $widths, $side, $corner_style, $r1, $r2);
|
||||
break;
|
||||
|
||||
default:
|
||||
return;
|
||||
}
|
||||
}
|
||||
// Draws a solid, dotted, or dashed line, observing the border radius
|
||||
protected function _border_line($x, $y, $length, $color, $widths, $side, $corner_style = "bevel", $pattern_name, $r1 = 0, $r2 = 0) {
|
||||
list($top, $right, $bottom, $left) = $widths;
|
||||
|
||||
$width = $$side;
|
||||
$pattern = $this->_get_dash_pattern($pattern_name, $width);
|
||||
|
||||
$half_width = $width/2;
|
||||
$r1 -= $half_width;
|
||||
$r2 -= $half_width;
|
||||
$adjust = $r1/80;
|
||||
$length -= $width;
|
||||
|
||||
switch ($side) {
|
||||
case "top":
|
||||
$x += $half_width;
|
||||
$y += $half_width;
|
||||
|
||||
if ( $r1 > 0 ) {
|
||||
$this->_canvas->arc($x + $r1, $y + $r1, $r1, $r1, 90-$adjust, 135+$adjust, $color, $width, $pattern);
|
||||
}
|
||||
|
||||
$this->_canvas->line($x + $r1, $y, $x + $length - $r2, $y, $color, $width, $pattern);
|
||||
|
||||
if ( $r2 > 0 ) {
|
||||
$this->_canvas->arc($x + $length - $r2, $y + $r2, $r2, $r2, 45-$adjust, 90+$adjust, $color, $width, $pattern);
|
||||
}
|
||||
break;
|
||||
|
||||
case "bottom":
|
||||
$x += $half_width;
|
||||
$y -= $half_width;
|
||||
|
||||
if ( $r1 > 0 ) {
|
||||
$this->_canvas->arc($x + $r1, $y - $r1, $r1, $r1, 225-$adjust, 270+$adjust, $color, $width, $pattern);
|
||||
}
|
||||
|
||||
$this->_canvas->line($x + $r1, $y, $x + $length - $r2, $y, $color, $width, $pattern);
|
||||
|
||||
if ( $r2 > 0 ) {
|
||||
$this->_canvas->arc($x + $length - $r2, $y - $r2, $r2, $r2, 270-$adjust, 315+$adjust, $color, $width, $pattern);
|
||||
}
|
||||
break;
|
||||
|
||||
case "left":
|
||||
$y += $half_width;
|
||||
$x += $half_width;
|
||||
|
||||
if ( $r1 > 0 ) {
|
||||
$this->_canvas->arc($x + $r1, $y + $r1, $r1, $r1, 135-$adjust, 180+$adjust, $color, $width, $pattern);
|
||||
}
|
||||
|
||||
$this->_canvas->line($x, $y + $r1, $x, $y + $length - $r2, $color, $width, $pattern);
|
||||
|
||||
if ( $r2 > 0 ) {
|
||||
$this->_canvas->arc($x + $r2, $y + $length - $r2, $r2, $r2, 180-$adjust, 225+$adjust, $color, $width, $pattern);
|
||||
}
|
||||
break;
|
||||
|
||||
case "right":
|
||||
$y += $half_width;
|
||||
$x -= $half_width;
|
||||
|
||||
if ( $r1 > 0 ) {
|
||||
$this->_canvas->arc($x - $r1, $y + $r1, $r1, $r1, 0-$adjust, 45+$adjust, $color, $width, $pattern);
|
||||
}
|
||||
|
||||
$this->_canvas->line($x, $y + $r1, $x, $y + $length - $r2, $color, $width, $pattern);
|
||||
|
||||
if ( $r2 > 0 ) {
|
||||
$this->_canvas->arc($x - $r2, $y + $length - $r2, $r2, $r2, 315-$adjust, 360+$adjust, $color, $width, $pattern);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
protected function _set_opacity($opacity) {
|
||||
if ( is_numeric($opacity) && $opacity <= 1.0 && $opacity >= 0.0 ) {
|
||||
$this->_canvas->set_opacity( $opacity );
|
||||
}
|
||||
}
|
||||
|
||||
protected function _debug_layout($box, $color = "red", $style = array()) {
|
||||
$this->_canvas->rectangle($box[0], $box[1], $box[2], $box[3], CSS_Color::parse($color), 0.1, $style);
|
||||
}
|
||||
}
|
||||
@@ -1,592 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* @package dompdf
|
||||
* @link http://dompdf.github.com/
|
||||
* @author Benj Carson <benjcarson@digitaljunkies.ca>
|
||||
* @author Fabien Ménager <fabien.menager@gmail.com>
|
||||
* @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License
|
||||
*/
|
||||
|
||||
/**
|
||||
* Translates HTML 4.0 attributes into CSS rules
|
||||
*
|
||||
* @package dompdf
|
||||
*/
|
||||
class Attribute_Translator {
|
||||
static $_style_attr = "_html_style_attribute";
|
||||
|
||||
// Munged data originally from
|
||||
// http://www.w3.org/TR/REC-html40/index/attributes.html
|
||||
// http://www.cs.tut.fi/~jkorpela/html2css.html
|
||||
static private $__ATTRIBUTE_LOOKUP = array(
|
||||
//'caption' => array ( 'align' => '', ),
|
||||
'img' => array(
|
||||
'align' => array(
|
||||
'bottom' => 'vertical-align: baseline;',
|
||||
'middle' => 'vertical-align: middle;',
|
||||
'top' => 'vertical-align: top;',
|
||||
'left' => 'float: left;',
|
||||
'right' => 'float: right;'
|
||||
),
|
||||
'border' => 'border: %0.2F px solid;',
|
||||
'height' => 'height: %s px;',
|
||||
'hspace' => 'padding-left: %1$0.2F px; padding-right: %1$0.2F px;',
|
||||
'vspace' => 'padding-top: %1$0.2F px; padding-bottom: %1$0.2F px;',
|
||||
'width' => 'width: %s px;',
|
||||
),
|
||||
'table' => array(
|
||||
'align' => array(
|
||||
'left' => 'margin-left: 0; margin-right: auto;',
|
||||
'center' => 'margin-left: auto; margin-right: auto;',
|
||||
'right' => 'margin-left: auto; margin-right: 0;'
|
||||
),
|
||||
'bgcolor' => 'background-color: %s;',
|
||||
'border' => '!set_table_border',
|
||||
'cellpadding' => '!set_table_cellpadding',//'border-spacing: %0.2F; border-collapse: separate;',
|
||||
'cellspacing' => '!set_table_cellspacing',
|
||||
'frame' => array(
|
||||
'void' => 'border-style: none;',
|
||||
'above' => 'border-top-style: solid;',
|
||||
'below' => 'border-bottom-style: solid;',
|
||||
'hsides' => 'border-left-style: solid; border-right-style: solid;',
|
||||
'vsides' => 'border-top-style: solid; border-bottom-style: solid;',
|
||||
'lhs' => 'border-left-style: solid;',
|
||||
'rhs' => 'border-right-style: solid;',
|
||||
'box' => 'border-style: solid;',
|
||||
'border' => 'border-style: solid;'
|
||||
),
|
||||
'rules' => '!set_table_rules',
|
||||
'width' => 'width: %s;',
|
||||
),
|
||||
'hr' => array(
|
||||
'align' => '!set_hr_align', // Need to grab width to set 'left' & 'right' correctly
|
||||
'noshade' => 'border-style: solid;',
|
||||
'size' => '!set_hr_size', //'border-width: %0.2F px;',
|
||||
'width' => 'width: %s;',
|
||||
),
|
||||
'div' => array(
|
||||
'align' => 'text-align: %s;',
|
||||
),
|
||||
'h1' => array(
|
||||
'align' => 'text-align: %s;',
|
||||
),
|
||||
'h2' => array(
|
||||
'align' => 'text-align: %s;',
|
||||
),
|
||||
'h3' => array(
|
||||
'align' => 'text-align: %s;',
|
||||
),
|
||||
'h4' => array(
|
||||
'align' => 'text-align: %s;',
|
||||
),
|
||||
'h5' => array(
|
||||
'align' => 'text-align: %s;',
|
||||
),
|
||||
'h6' => array(
|
||||
'align' => 'text-align: %s;',
|
||||
),
|
||||
'p' => array(
|
||||
'align' => 'text-align: %s;',
|
||||
),
|
||||
// 'col' => array(
|
||||
// 'align' => '',
|
||||
// 'valign' => '',
|
||||
// ),
|
||||
// 'colgroup' => array(
|
||||
// 'align' => '',
|
||||
// 'valign' => '',
|
||||
// ),
|
||||
'tbody' => array(
|
||||
'align' => '!set_table_row_align',
|
||||
'valign' => '!set_table_row_valign',
|
||||
),
|
||||
'td' => array(
|
||||
'align' => 'text-align: %s;',
|
||||
'bgcolor' => '!set_background_color',
|
||||
'height' => 'height: %s;',
|
||||
'nowrap' => 'white-space: nowrap;',
|
||||
'valign' => 'vertical-align: %s;',
|
||||
'width' => 'width: %s;',
|
||||
),
|
||||
'tfoot' => array(
|
||||
'align' => '!set_table_row_align',
|
||||
'valign' => '!set_table_row_valign',
|
||||
),
|
||||
'th' => array(
|
||||
'align' => 'text-align: %s;',
|
||||
'bgcolor' => '!set_background_color',
|
||||
'height' => 'height: %s;',
|
||||
'nowrap' => 'white-space: nowrap;',
|
||||
'valign' => 'vertical-align: %s;',
|
||||
'width' => 'width: %s;',
|
||||
),
|
||||
'thead' => array(
|
||||
'align' => '!set_table_row_align',
|
||||
'valign' => '!set_table_row_valign',
|
||||
),
|
||||
'tr' => array(
|
||||
'align' => '!set_table_row_align',
|
||||
'bgcolor' => '!set_table_row_bgcolor',
|
||||
'valign' => '!set_table_row_valign',
|
||||
),
|
||||
'body' => array(
|
||||
'background' => 'background-image: url(%s);',
|
||||
'bgcolor' => '!set_background_color',
|
||||
'link' => '!set_body_link',
|
||||
'text' => '!set_color',
|
||||
),
|
||||
'br' => array(
|
||||
'clear' => 'clear: %s;',
|
||||
),
|
||||
'basefont' => array(
|
||||
'color' => '!set_color',
|
||||
'face' => 'font-family: %s;',
|
||||
'size' => '!set_basefont_size',
|
||||
),
|
||||
'font' => array(
|
||||
'color' => '!set_color',
|
||||
'face' => 'font-family: %s;',
|
||||
'size' => '!set_font_size',
|
||||
),
|
||||
'dir' => array(
|
||||
'compact' => 'margin: 0.5em 0;',
|
||||
),
|
||||
'dl' => array(
|
||||
'compact' => 'margin: 0.5em 0;',
|
||||
),
|
||||
'menu' => array(
|
||||
'compact' => 'margin: 0.5em 0;',
|
||||
),
|
||||
'ol' => array(
|
||||
'compact' => 'margin: 0.5em 0;',
|
||||
'start' => 'counter-reset: -dompdf-default-counter %d;',
|
||||
'type' => 'list-style-type: %s;',
|
||||
),
|
||||
'ul' => array(
|
||||
'compact' => 'margin: 0.5em 0;',
|
||||
'type' => 'list-style-type: %s;',
|
||||
),
|
||||
'li' => array(
|
||||
'type' => 'list-style-type: %s;',
|
||||
'value' => 'counter-reset: -dompdf-default-counter %d;',
|
||||
),
|
||||
'pre' => array(
|
||||
'width' => 'width: %s;',
|
||||
),
|
||||
);
|
||||
|
||||
static protected $_last_basefont_size = 3;
|
||||
static protected $_font_size_lookup = array(
|
||||
// For basefont support
|
||||
-3 => "4pt",
|
||||
-2 => "5pt",
|
||||
-1 => "6pt",
|
||||
0 => "7pt",
|
||||
|
||||
1 => "8pt",
|
||||
2 => "10pt",
|
||||
3 => "12pt",
|
||||
4 => "14pt",
|
||||
5 => "18pt",
|
||||
6 => "24pt",
|
||||
7 => "34pt",
|
||||
|
||||
// For basefont support
|
||||
8 => "48pt",
|
||||
9 => "44pt",
|
||||
10 => "52pt",
|
||||
11 => "60pt",
|
||||
);
|
||||
|
||||
/**
|
||||
* @param Frame $frame
|
||||
*/
|
||||
static function translate_attributes(Frame $frame) {
|
||||
$node = $frame->get_node();
|
||||
$tag = $node->nodeName;
|
||||
|
||||
if ( !isset(self::$__ATTRIBUTE_LOOKUP[$tag]) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$valid_attrs = self::$__ATTRIBUTE_LOOKUP[$tag];
|
||||
$attrs = $node->attributes;
|
||||
$style = rtrim($node->getAttribute(self::$_style_attr), "; ");
|
||||
if ( $style != "" ) {
|
||||
$style .= ";";
|
||||
}
|
||||
|
||||
foreach ($attrs as $attr => $attr_node ) {
|
||||
if ( !isset($valid_attrs[$attr]) ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$value = $attr_node->value;
|
||||
|
||||
$target = $valid_attrs[$attr];
|
||||
|
||||
// Look up $value in $target, if $target is an array:
|
||||
if ( is_array($target) ) {
|
||||
if ( isset($target[$value]) ) {
|
||||
$style .= " " . self::_resolve_target($node, $target[$value], $value);
|
||||
}
|
||||
}
|
||||
else {
|
||||
// otherwise use target directly
|
||||
$style .= " " . self::_resolve_target($node, $target, $value);
|
||||
}
|
||||
}
|
||||
|
||||
if ( !is_null($style) ) {
|
||||
$style = ltrim($style);
|
||||
$node->setAttribute(self::$_style_attr, $style);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @param DOMNode $node
|
||||
* @param string $target
|
||||
* @param string $value
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
static protected function _resolve_target(DOMNode $node, $target, $value) {
|
||||
if ( $target[0] === "!" ) {
|
||||
// Function call
|
||||
$func = "_" . mb_substr($target, 1);
|
||||
return self::$func($node, $value);
|
||||
}
|
||||
|
||||
return $value ? sprintf($target, $value) : "";
|
||||
}
|
||||
|
||||
/**
|
||||
* @param DOMElement $node
|
||||
* @param string $new_style
|
||||
*/
|
||||
static function append_style(DOMElement $node, $new_style) {
|
||||
$style = rtrim($node->getAttribute(self::$_style_attr), ";");
|
||||
$style .= $new_style;
|
||||
$style = ltrim($style, ";");
|
||||
$node->setAttribute(self::$_style_attr, $style);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param DOMNode $node
|
||||
*
|
||||
* @return DOMNodeList|DOMElement[]
|
||||
*/
|
||||
static protected function get_cell_list(DOMNode $node) {
|
||||
$xpath = new DOMXpath($node->ownerDocument);
|
||||
|
||||
switch($node->nodeName) {
|
||||
default:
|
||||
case "table":
|
||||
$query = "tr/td | thead/tr/td | tbody/tr/td | tfoot/tr/td | tr/th | thead/tr/th | tbody/tr/th | tfoot/tr/th";
|
||||
break;
|
||||
|
||||
case "tbody":
|
||||
case "tfoot":
|
||||
case "thead":
|
||||
$query = "tr/td | tr/th";
|
||||
break;
|
||||
|
||||
case "tr":
|
||||
$query = "td | th";
|
||||
break;
|
||||
}
|
||||
|
||||
return $xpath->query($query, $node);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $value
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
static protected function _get_valid_color($value) {
|
||||
if ( preg_match('/^#?([0-9A-F]{6})$/i', $value, $matches) ) {
|
||||
$value = "#$matches[1]";
|
||||
}
|
||||
|
||||
return $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param DOMElement $node
|
||||
* @param string $value
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
static protected function _set_color(DOMElement $node, $value) {
|
||||
$value = self::_get_valid_color($value);
|
||||
return "color: $value;";
|
||||
}
|
||||
|
||||
/**
|
||||
* @param DOMElement $node
|
||||
* @param string $value
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
static protected function _set_background_color(DOMElement $node, $value) {
|
||||
$value = self::_get_valid_color($value);
|
||||
return "background-color: $value;";
|
||||
}
|
||||
|
||||
/**
|
||||
* @param DOMElement $node
|
||||
* @param string $value
|
||||
*
|
||||
* @return null
|
||||
*/
|
||||
static protected function _set_table_cellpadding(DOMElement $node, $value) {
|
||||
$cell_list = self::get_cell_list($node);
|
||||
|
||||
foreach ($cell_list as $cell) {
|
||||
self::append_style($cell, "; padding: {$value}px;");
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param DOMElement $node
|
||||
* @param string $value
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
static protected function _set_table_border(DOMElement $node, $value) {
|
||||
$cell_list = self::get_cell_list($node);
|
||||
|
||||
foreach ($cell_list as $cell) {
|
||||
$style = rtrim($cell->getAttribute(self::$_style_attr));
|
||||
$style .= "; border-width: " . ($value > 0 ? 1 : 0) . "pt; border-style: inset;";
|
||||
$style = ltrim($style, ";");
|
||||
$cell->setAttribute(self::$_style_attr, $style);
|
||||
}
|
||||
|
||||
$style = rtrim($node->getAttribute(self::$_style_attr), ";");
|
||||
$style .= "; border-width: $value" . "px; ";
|
||||
return ltrim($style, "; ");
|
||||
}
|
||||
|
||||
/**
|
||||
* @param DOMElement $node
|
||||
* @param string $value
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
static protected function _set_table_cellspacing(DOMElement $node, $value) {
|
||||
$style = rtrim($node->getAttribute(self::$_style_attr), ";");
|
||||
|
||||
if ( $value == 0 ) {
|
||||
$style .= "; border-collapse: collapse;";
|
||||
}
|
||||
else {
|
||||
$style .= "; border-spacing: {$value}px; border-collapse: separate;";
|
||||
}
|
||||
|
||||
return ltrim($style, ";");
|
||||
}
|
||||
|
||||
/**
|
||||
* @param DOMElement $node
|
||||
* @param string $value
|
||||
*
|
||||
* @return null|string
|
||||
*/
|
||||
static protected function _set_table_rules(DOMElement $node, $value) {
|
||||
$new_style = "; border-collapse: collapse;";
|
||||
|
||||
switch ($value) {
|
||||
case "none":
|
||||
$new_style .= "border-style: none;";
|
||||
break;
|
||||
|
||||
case "groups":
|
||||
// FIXME: unsupported
|
||||
return null;
|
||||
|
||||
case "rows":
|
||||
$new_style .= "border-style: solid none solid none; border-width: 1px; ";
|
||||
break;
|
||||
|
||||
case "cols":
|
||||
$new_style .= "border-style: none solid none solid; border-width: 1px; ";
|
||||
break;
|
||||
|
||||
case "all":
|
||||
$new_style .= "border-style: solid; border-width: 1px; ";
|
||||
break;
|
||||
|
||||
default:
|
||||
// Invalid value
|
||||
return null;
|
||||
}
|
||||
|
||||
$cell_list = self::get_cell_list($node);
|
||||
|
||||
foreach ($cell_list as $cell) {
|
||||
$style = $cell->getAttribute(self::$_style_attr);
|
||||
$style .= $new_style;
|
||||
$cell->setAttribute(self::$_style_attr, $style);
|
||||
}
|
||||
|
||||
$style = rtrim($node->getAttribute(self::$_style_attr), ";");
|
||||
$style .= "; border-collapse: collapse; ";
|
||||
|
||||
return ltrim($style, "; ");
|
||||
}
|
||||
|
||||
/**
|
||||
* @param DOMElement $node
|
||||
* @param string $value
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
static protected function _set_hr_size(DOMElement $node, $value) {
|
||||
$style = rtrim($node->getAttribute(self::$_style_attr), ";");
|
||||
$style .= "; border-width: ".max(0, $value-2)."; ";
|
||||
return ltrim($style, "; ");
|
||||
}
|
||||
|
||||
/**
|
||||
* @param DOMElement $node
|
||||
* @param string $value
|
||||
*
|
||||
* @return null|string
|
||||
*/
|
||||
static protected function _set_hr_align(DOMElement $node, $value) {
|
||||
$style = rtrim($node->getAttribute(self::$_style_attr),";");
|
||||
$width = $node->getAttribute("width");
|
||||
|
||||
if ( $width == "" ) {
|
||||
$width = "100%";
|
||||
}
|
||||
|
||||
$remainder = 100 - (double)rtrim($width, "% ");
|
||||
|
||||
switch ($value) {
|
||||
case "left":
|
||||
$style .= "; margin-right: $remainder %;";
|
||||
break;
|
||||
|
||||
case "right":
|
||||
$style .= "; margin-left: $remainder %;";
|
||||
break;
|
||||
|
||||
case "center":
|
||||
$style .= "; margin-left: auto; margin-right: auto;";
|
||||
break;
|
||||
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
|
||||
return ltrim($style, "; ");
|
||||
}
|
||||
|
||||
/**
|
||||
* @param DOMElement $node
|
||||
* @param string $value
|
||||
*
|
||||
* @return null
|
||||
*/
|
||||
static protected function _set_table_row_align(DOMElement $node, $value) {
|
||||
$cell_list = self::get_cell_list($node);
|
||||
|
||||
foreach ($cell_list as $cell) {
|
||||
self::append_style($cell, "; text-align: $value;");
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param DOMElement $node
|
||||
* @param string $value
|
||||
*
|
||||
* @return null
|
||||
*/
|
||||
static protected function _set_table_row_valign(DOMElement $node, $value) {
|
||||
$cell_list = self::get_cell_list($node);
|
||||
|
||||
foreach ($cell_list as $cell) {
|
||||
self::append_style($cell, "; vertical-align: $value;");
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param DOMElement $node
|
||||
* @param string $value
|
||||
*
|
||||
* @return null
|
||||
*/
|
||||
static protected function _set_table_row_bgcolor(DOMElement $node, $value) {
|
||||
$cell_list = self::get_cell_list($node);
|
||||
$value = self::_get_valid_color($value);
|
||||
|
||||
foreach ($cell_list as $cell) {
|
||||
self::append_style($cell, "; background-color: $value;");
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param DOMElement $node
|
||||
* @param string $value
|
||||
*
|
||||
* @return null
|
||||
*/
|
||||
static protected function _set_body_link(DOMElement $node, $value) {
|
||||
$a_list = $node->getElementsByTagName("a");
|
||||
$value = self::_get_valid_color($value);
|
||||
|
||||
foreach ($a_list as $a) {
|
||||
self::append_style($a, "; color: $value;");
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param DOMElement $node
|
||||
* @param string $value
|
||||
*
|
||||
* @return null
|
||||
*/
|
||||
static protected function _set_basefont_size(DOMElement $node, $value) {
|
||||
// FIXME: ? we don't actually set the font size of anything here, just
|
||||
// the base size for later modification by <font> tags.
|
||||
self::$_last_basefont_size = $value;
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param DOMElement $node
|
||||
* @param string $value
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
static protected function _set_font_size(DOMElement $node, $value) {
|
||||
$style = $node->getAttribute(self::$_style_attr);
|
||||
|
||||
if ( $value[0] === "-" || $value[0] === "+" ) {
|
||||
$value = self::$_last_basefont_size + (int)$value;
|
||||
}
|
||||
|
||||
if ( isset(self::$_font_size_lookup[$value]) ) {
|
||||
$style .= "; font-size: " . self::$_font_size_lookup[$value] . ";";
|
||||
}
|
||||
else {
|
||||
$style .= "; font-size: $value;";
|
||||
}
|
||||
|
||||
return ltrim($style, "; ");
|
||||
}
|
||||
}
|
||||
@@ -1,86 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* @package dompdf
|
||||
* @link http://dompdf.github.com/
|
||||
* @author Benj Carson <benjcarson@digitaljunkies.ca>
|
||||
* @author Fabien Ménager <fabien.menager@gmail.com>
|
||||
* @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License
|
||||
*/
|
||||
|
||||
/**
|
||||
* DOMPDF autoload function
|
||||
*
|
||||
* If you have an existing autoload function, add a call to this function
|
||||
* from your existing __autoload() implementation.
|
||||
*
|
||||
* @param string $class
|
||||
*/
|
||||
function DOMPDF_autoload($class) {
|
||||
$filename = DOMPDF_INC_DIR . "/" . mb_strtolower($class) . ".cls.php";
|
||||
|
||||
if ( is_file($filename) ) {
|
||||
include_once $filename;
|
||||
}
|
||||
}
|
||||
|
||||
// If SPL autoload functions are available (PHP >= 5.1.2)
|
||||
if ( function_exists("spl_autoload_register") ) {
|
||||
$autoload = "DOMPDF_autoload";
|
||||
$funcs = spl_autoload_functions();
|
||||
|
||||
// No functions currently in the stack.
|
||||
if ( !DOMPDF_AUTOLOAD_PREPEND || $funcs === false ) {
|
||||
spl_autoload_register($autoload);
|
||||
}
|
||||
|
||||
// If PHP >= 5.3 the $prepend argument is available
|
||||
else if ( PHP_VERSION_ID >= 50300 ) {
|
||||
spl_autoload_register($autoload, true, true);
|
||||
}
|
||||
|
||||
else {
|
||||
// Unregister existing autoloaders...
|
||||
$compat = (PHP_VERSION_ID <= 50102 && PHP_VERSION_ID >= 50100);
|
||||
|
||||
foreach ($funcs as $func) {
|
||||
if (is_array($func)) {
|
||||
// :TRICKY: There are some compatibility issues and some
|
||||
// places where we need to error out
|
||||
$reflector = new ReflectionMethod($func[0], $func[1]);
|
||||
if (!$reflector->isStatic()) {
|
||||
throw new Exception('This function is not compatible with non-static object methods due to PHP Bug #44144.');
|
||||
}
|
||||
|
||||
// Suprisingly, spl_autoload_register supports the
|
||||
// Class::staticMethod callback format, although call_user_func doesn't
|
||||
if ($compat) $func = implode('::', $func);
|
||||
}
|
||||
|
||||
spl_autoload_unregister($func);
|
||||
}
|
||||
|
||||
// Register the new one, thus putting it at the front of the stack...
|
||||
spl_autoload_register($autoload);
|
||||
|
||||
// Now, go back and re-register all of our old ones.
|
||||
foreach ($funcs as $func) {
|
||||
spl_autoload_register($func);
|
||||
}
|
||||
|
||||
// Be polite and ensure that userland autoload gets retained
|
||||
if ( function_exists("__autoload") ) {
|
||||
spl_autoload_register("__autoload");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
else if ( !function_exists("__autoload") ) {
|
||||
/**
|
||||
* Default __autoload() function
|
||||
*
|
||||
* @param string $class
|
||||
*/
|
||||
function __autoload($class) {
|
||||
DOMPDF_autoload($class);
|
||||
}
|
||||
}
|
||||
@@ -1,234 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* @package dompdf
|
||||
* @link http://dompdf.github.com/
|
||||
* @author Benj Carson <benjcarson@digitaljunkies.ca>
|
||||
* @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License
|
||||
*/
|
||||
|
||||
/**
|
||||
* Decorates frames for block layout
|
||||
*
|
||||
* @access private
|
||||
* @package dompdf
|
||||
*/
|
||||
class Block_Frame_Decorator extends Frame_Decorator {
|
||||
/**
|
||||
* Current line index
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
protected $_cl;
|
||||
|
||||
/**
|
||||
* The block's line boxes
|
||||
*
|
||||
* @var Line_Box[]
|
||||
*/
|
||||
protected $_line_boxes;
|
||||
|
||||
function __construct(Frame $frame, DOMPDF $dompdf) {
|
||||
parent::__construct($frame, $dompdf);
|
||||
|
||||
$this->_line_boxes = array(new Line_Box($this));
|
||||
$this->_cl = 0;
|
||||
}
|
||||
|
||||
function reset() {
|
||||
parent::reset();
|
||||
|
||||
$this->_line_boxes = array(new Line_Box($this));
|
||||
$this->_cl = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Line_Box
|
||||
*/
|
||||
function get_current_line_box() {
|
||||
return $this->_line_boxes[$this->_cl];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return integer
|
||||
*/
|
||||
function get_current_line_number() {
|
||||
return $this->_cl;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Line_Box[]
|
||||
*/
|
||||
function get_line_boxes() {
|
||||
return $this->_line_boxes;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param integer $i
|
||||
*/
|
||||
function clear_line($i) {
|
||||
if ( isset($this->_line_boxes[$i]) ) {
|
||||
unset($this->_line_boxes[$i]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Frame $frame
|
||||
*/
|
||||
function add_frame_to_line(Frame $frame) {
|
||||
if ( !$frame->is_in_flow() ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$style = $frame->get_style();
|
||||
|
||||
$frame->set_containing_line($this->_line_boxes[$this->_cl]);
|
||||
|
||||
/*
|
||||
// Adds a new line after a block, only if certain conditions are met
|
||||
if ((($frame instanceof Inline_Frame_Decorator && $frame->get_node()->nodeName !== "br") ||
|
||||
$frame instanceof Text_Frame_Decorator && trim($frame->get_text())) &&
|
||||
($frame->get_prev_sibling() && $frame->get_prev_sibling()->get_style()->display === "block" &&
|
||||
$this->_line_boxes[$this->_cl]->w > 0 )) {
|
||||
|
||||
$this->maximize_line_height( $style->length_in_pt($style->line_height), $frame );
|
||||
$this->add_line();
|
||||
|
||||
// Add each child of the inline frame to the line individually
|
||||
foreach ($frame->get_children() as $child)
|
||||
$this->add_frame_to_line( $child );
|
||||
}
|
||||
else*/
|
||||
|
||||
// Handle inline frames (which are effectively wrappers)
|
||||
if ( $frame instanceof Inline_Frame_Decorator ) {
|
||||
|
||||
// Handle line breaks
|
||||
if ( $frame->get_node()->nodeName === "br" ) {
|
||||
$this->maximize_line_height( $style->length_in_pt($style->line_height), $frame );
|
||||
$this->add_line(true);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// Trim leading text if this is an empty line. Kinda a hack to put it here,
|
||||
// but what can you do...
|
||||
if ( $this->get_current_line_box()->w == 0 &&
|
||||
$frame->is_text_node() &&
|
||||
!$frame->is_pre() ) {
|
||||
|
||||
$frame->set_text( ltrim($frame->get_text()) );
|
||||
$frame->recalculate_width();
|
||||
}
|
||||
|
||||
$w = $frame->get_margin_width();
|
||||
|
||||
if ( $w == 0 ) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Debugging code:
|
||||
/*
|
||||
pre_r("\n<h3>Adding frame to line:</h3>");
|
||||
|
||||
// pre_r("Me: " . $this->get_node()->nodeName . " (" . spl_object_hash($this->get_node()) . ")");
|
||||
// pre_r("Node: " . $frame->get_node()->nodeName . " (" . spl_object_hash($frame->get_node()) . ")");
|
||||
if ( $frame->is_text_node() )
|
||||
pre_r('"'.$frame->get_node()->nodeValue.'"');
|
||||
|
||||
pre_r("Line width: " . $this->_line_boxes[$this->_cl]->w);
|
||||
pre_r("Frame: " . get_class($frame));
|
||||
pre_r("Frame width: " . $w);
|
||||
pre_r("Frame height: " . $frame->get_margin_height());
|
||||
pre_r("Containing block width: " . $this->get_containing_block("w"));
|
||||
*/
|
||||
// End debugging
|
||||
|
||||
$line = $this->_line_boxes[$this->_cl];
|
||||
if ( $line->left + $line->w + $line->right + $w > $this->get_containing_block("w")) {
|
||||
$this->add_line();
|
||||
}
|
||||
|
||||
$frame->position();
|
||||
|
||||
$current_line = $this->_line_boxes[$this->_cl];
|
||||
$current_line->add_frame($frame);
|
||||
|
||||
if ( $frame->is_text_node() ) {
|
||||
$current_line->wc += count(preg_split("/\s+/", trim($frame->get_text())));
|
||||
}
|
||||
|
||||
$this->increase_line_width($w);
|
||||
|
||||
$this->maximize_line_height($frame->get_margin_height(), $frame);
|
||||
}
|
||||
|
||||
function remove_frames_from_line(Frame $frame) {
|
||||
// Search backwards through the lines for $frame
|
||||
$i = $this->_cl;
|
||||
$j = null;
|
||||
|
||||
while ($i >= 0) {
|
||||
if ( ($j = in_array($frame, $this->_line_boxes[$i]->get_frames(), true)) !== false ) {
|
||||
break;
|
||||
}
|
||||
|
||||
$i--;
|
||||
}
|
||||
|
||||
if ( $j === false ) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Remove $frame and all frames that follow
|
||||
while ($j < count($this->_line_boxes[$i]->get_frames())) {
|
||||
$frames = $this->_line_boxes[$i]->get_frames();
|
||||
$f = $frames[$j];
|
||||
$frames[$j] = null;
|
||||
unset($frames[$j]);
|
||||
$j++;
|
||||
$this->_line_boxes[$i]->w -= $f->get_margin_width();
|
||||
}
|
||||
|
||||
// Recalculate the height of the line
|
||||
$h = 0;
|
||||
foreach ($this->_line_boxes[$i]->get_frames() as $f) {
|
||||
$h = max( $h, $f->get_margin_height() );
|
||||
}
|
||||
|
||||
$this->_line_boxes[$i]->h = $h;
|
||||
|
||||
// Remove all lines that follow
|
||||
while ($this->_cl > $i) {
|
||||
$this->_line_boxes[ $this->_cl ] = null;
|
||||
unset($this->_line_boxes[ $this->_cl ]);
|
||||
$this->_cl--;
|
||||
}
|
||||
}
|
||||
|
||||
function increase_line_width($w) {
|
||||
$this->_line_boxes[ $this->_cl ]->w += $w;
|
||||
}
|
||||
|
||||
function maximize_line_height($val, Frame $frame) {
|
||||
if ( $val > $this->_line_boxes[ $this->_cl ]->h ) {
|
||||
$this->_line_boxes[ $this->_cl ]->tallest_frame = $frame;
|
||||
$this->_line_boxes[ $this->_cl ]->h = $val;
|
||||
}
|
||||
}
|
||||
|
||||
function add_line($br = false) {
|
||||
|
||||
// if ( $this->_line_boxes[$this->_cl]["h"] == 0 ) //count($this->_line_boxes[$i]["frames"]) == 0 ||
|
||||
// return;
|
||||
|
||||
$this->_line_boxes[$this->_cl]->br = $br;
|
||||
$y = $this->_line_boxes[$this->_cl]->y + $this->_line_boxes[$this->_cl]->h;
|
||||
|
||||
$new_line = new Line_Box($this, $y);
|
||||
|
||||
$this->_line_boxes[ ++$this->_cl ] = $new_line;
|
||||
}
|
||||
|
||||
//........................................................................
|
||||
}
|
||||
@@ -1,805 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* @package dompdf
|
||||
* @link http://dompdf.github.com/
|
||||
* @author Benj Carson <benjcarson@digitaljunkies.ca>
|
||||
* @author Fabien Ménager <fabien.menager@gmail.com>
|
||||
* @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License
|
||||
*/
|
||||
|
||||
/**
|
||||
* Reflows block frames
|
||||
*
|
||||
* @access private
|
||||
* @package dompdf
|
||||
*/
|
||||
class Block_Frame_Reflower extends Frame_Reflower {
|
||||
// Minimum line width to justify, as fraction of available width
|
||||
const MIN_JUSTIFY_WIDTH = 0.80;
|
||||
|
||||
/**
|
||||
* @var Block_Frame_Decorator
|
||||
*/
|
||||
protected $_frame;
|
||||
|
||||
function __construct(Block_Frame_Decorator $frame) { parent::__construct($frame); }
|
||||
|
||||
/**
|
||||
* Calculate the ideal used value for the width property as per:
|
||||
* http://www.w3.org/TR/CSS21/visudet.html#Computing_widths_and_margins
|
||||
*
|
||||
* @param float $width
|
||||
* @return array
|
||||
*/
|
||||
protected function _calculate_width($width) {
|
||||
$frame = $this->_frame;
|
||||
$style = $frame->get_style();
|
||||
$w = $frame->get_containing_block("w");
|
||||
|
||||
if ( $style->position === "fixed" ) {
|
||||
$w = $frame->get_parent()->get_containing_block("w");
|
||||
}
|
||||
|
||||
$rm = $style->length_in_pt($style->margin_right, $w);
|
||||
$lm = $style->length_in_pt($style->margin_left, $w);
|
||||
|
||||
$left = $style->length_in_pt($style->left, $w);
|
||||
$right = $style->length_in_pt($style->right, $w);
|
||||
|
||||
// Handle 'auto' values
|
||||
$dims = array($style->border_left_width,
|
||||
$style->border_right_width,
|
||||
$style->padding_left,
|
||||
$style->padding_right,
|
||||
$width !== "auto" ? $width : 0,
|
||||
$rm !== "auto" ? $rm : 0,
|
||||
$lm !== "auto" ? $lm : 0);
|
||||
|
||||
// absolutely positioned boxes take the 'left' and 'right' properties into account
|
||||
if ( $frame->is_absolute() ) {
|
||||
$absolute = true;
|
||||
$dims[] = $left !== "auto" ? $left : 0;
|
||||
$dims[] = $right !== "auto" ? $right : 0;
|
||||
}
|
||||
else {
|
||||
$absolute = false;
|
||||
}
|
||||
|
||||
$sum = $style->length_in_pt($dims, $w);
|
||||
|
||||
// Compare to the containing block
|
||||
$diff = $w - $sum;
|
||||
|
||||
if ( $diff > 0 ) {
|
||||
|
||||
if ( $absolute ) {
|
||||
|
||||
// resolve auto properties: see
|
||||
// http://www.w3.org/TR/CSS21/visudet.html#abs-non-replaced-width
|
||||
|
||||
if ( $width === "auto" && $left === "auto" && $right === "auto" ) {
|
||||
|
||||
if ( $lm === "auto" ) $lm = 0;
|
||||
if ( $rm === "auto" ) $rm = 0;
|
||||
|
||||
// Technically, the width should be "shrink-to-fit" i.e. based on the
|
||||
// preferred width of the content... a little too costly here as a
|
||||
// special case. Just get the width to take up the slack:
|
||||
$left = 0;
|
||||
$right = 0;
|
||||
$width = $diff;
|
||||
}
|
||||
else if ( $width === "auto" ) {
|
||||
|
||||
if ( $lm === "auto" ) $lm = 0;
|
||||
if ( $rm === "auto" ) $rm = 0;
|
||||
if ( $left === "auto" ) $left = 0;
|
||||
if ( $right === "auto" ) $right = 0;
|
||||
|
||||
$width = $diff;
|
||||
}
|
||||
else if ( $left === "auto" ) {
|
||||
|
||||
if ( $lm === "auto" ) $lm = 0;
|
||||
if ( $rm === "auto" ) $rm = 0;
|
||||
if ( $right === "auto" ) $right = 0;
|
||||
|
||||
$left = $diff;
|
||||
}
|
||||
else if ( $right === "auto" ) {
|
||||
|
||||
if ( $lm === "auto" ) $lm = 0;
|
||||
if ( $rm === "auto" ) $rm = 0;
|
||||
|
||||
$right = $diff;
|
||||
}
|
||||
|
||||
}
|
||||
else {
|
||||
|
||||
// Find auto properties and get them to take up the slack
|
||||
if ( $width === "auto" ) {
|
||||
$width = $diff;
|
||||
}
|
||||
else if ( $lm === "auto" && $rm === "auto" ) {
|
||||
$lm = $rm = round($diff / 2);
|
||||
}
|
||||
else if ( $lm === "auto" ) {
|
||||
$lm = $diff;
|
||||
}
|
||||
else if ( $rm === "auto" ) {
|
||||
$rm = $diff;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
else if ($diff < 0) {
|
||||
|
||||
// We are over constrained--set margin-right to the difference
|
||||
$rm = $diff;
|
||||
|
||||
}
|
||||
|
||||
return array(
|
||||
"width" => $width,
|
||||
"margin_left" => $lm,
|
||||
"margin_right" => $rm,
|
||||
"left" => $left,
|
||||
"right" => $right,
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Call the above function, but resolve max/min widths
|
||||
*
|
||||
* @throws DOMPDF_Exception
|
||||
* @return array
|
||||
*/
|
||||
protected function _calculate_restricted_width() {
|
||||
$frame = $this->_frame;
|
||||
$style = $frame->get_style();
|
||||
$cb = $frame->get_containing_block();
|
||||
|
||||
if ( $style->position === "fixed" ) {
|
||||
$cb = $frame->get_root()->get_containing_block();
|
||||
}
|
||||
|
||||
//if ( $style->position === "absolute" )
|
||||
// $cb = $frame->find_positionned_parent()->get_containing_block();
|
||||
|
||||
if ( !isset($cb["w"]) ) {
|
||||
throw new DOMPDF_Exception("Box property calculation requires containing block width");
|
||||
}
|
||||
|
||||
// Treat width 100% as auto
|
||||
if ( $style->width === "100%" ) {
|
||||
$width = "auto";
|
||||
}
|
||||
else {
|
||||
$width = $style->length_in_pt($style->width, $cb["w"]);
|
||||
}
|
||||
|
||||
extract($this->_calculate_width($width));
|
||||
|
||||
// Handle min/max width
|
||||
$min_width = $style->length_in_pt($style->min_width, $cb["w"]);
|
||||
$max_width = $style->length_in_pt($style->max_width, $cb["w"]);
|
||||
|
||||
if ( $max_width !== "none" && $min_width > $max_width ) {
|
||||
list($max_width, $min_width) = array($min_width, $max_width);
|
||||
}
|
||||
|
||||
if ( $max_width !== "none" && $width > $max_width ) {
|
||||
extract($this->_calculate_width($max_width));
|
||||
}
|
||||
|
||||
if ( $width < $min_width ) {
|
||||
extract($this->_calculate_width($min_width));
|
||||
}
|
||||
|
||||
return array($width, $margin_left, $margin_right, $left, $right);
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine the unrestricted height of content within the block
|
||||
* not by adding each line's height, but by getting the last line's position.
|
||||
* This because lines could have been pushed lower by a clearing element.
|
||||
*
|
||||
* @return float
|
||||
*/
|
||||
protected function _calculate_content_height() {
|
||||
$lines = $this->_frame->get_line_boxes();
|
||||
$height = 0;
|
||||
|
||||
foreach ($lines as $line) {
|
||||
$height += $line->h;
|
||||
}
|
||||
|
||||
/*
|
||||
$first_line = reset($lines);
|
||||
$last_line = end($lines);
|
||||
$height2 = $last_line->y + $last_line->h - $first_line->y;
|
||||
*/
|
||||
|
||||
return $height;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine the frame's restricted height
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected function _calculate_restricted_height() {
|
||||
$frame = $this->_frame;
|
||||
$style = $frame->get_style();
|
||||
$content_height = $this->_calculate_content_height();
|
||||
$cb = $frame->get_containing_block();
|
||||
|
||||
$height = $style->length_in_pt($style->height, $cb["h"]);
|
||||
|
||||
$top = $style->length_in_pt($style->top, $cb["h"]);
|
||||
$bottom = $style->length_in_pt($style->bottom, $cb["h"]);
|
||||
|
||||
$margin_top = $style->length_in_pt($style->margin_top, $cb["h"]);
|
||||
$margin_bottom = $style->length_in_pt($style->margin_bottom, $cb["h"]);
|
||||
|
||||
if ( $frame->is_absolute() ) {
|
||||
|
||||
// see http://www.w3.org/TR/CSS21/visudet.html#abs-non-replaced-height
|
||||
|
||||
$dims = array($top !== "auto" ? $top : 0,
|
||||
$style->margin_top !== "auto" ? $style->margin_top : 0,
|
||||
$style->padding_top,
|
||||
$style->border_top_width,
|
||||
$height !== "auto" ? $height : 0,
|
||||
$style->border_bottom_width,
|
||||
$style->padding_bottom,
|
||||
$style->margin_bottom !== "auto" ? $style->margin_bottom : 0,
|
||||
$bottom !== "auto" ? $bottom : 0);
|
||||
|
||||
$sum = $style->length_in_pt($dims, $cb["h"]);
|
||||
|
||||
$diff = $cb["h"] - $sum;
|
||||
|
||||
if ( $diff > 0 ) {
|
||||
|
||||
if ( $height === "auto" && $top === "auto" && $bottom === "auto" ) {
|
||||
|
||||
if ( $margin_top === "auto" ) $margin_top = 0;
|
||||
if ( $margin_bottom === "auto" ) $margin_bottom = 0;
|
||||
|
||||
$height = $diff;
|
||||
}
|
||||
else if ( $height === "auto" && $top === "auto" ) {
|
||||
|
||||
if ( $margin_top === "auto" ) $margin_top = 0;
|
||||
if ( $margin_bottom === "auto" ) $margin_bottom = 0;
|
||||
|
||||
$height = $content_height;
|
||||
$top = $diff - $content_height;
|
||||
}
|
||||
else if ( $height === "auto" && $bottom === "auto" ) {
|
||||
|
||||
if ( $margin_top === "auto" ) $margin_top = 0;
|
||||
if ( $margin_bottom === "auto" ) $margin_bottom = 0;
|
||||
|
||||
$height = $content_height;
|
||||
$bottom = $diff - $content_height;
|
||||
}
|
||||
else if ( $top === "auto" && $bottom === "auto" ) {
|
||||
|
||||
if ( $margin_top === "auto" ) $margin_top = 0;
|
||||
if ( $margin_bottom === "auto" ) $margin_bottom = 0;
|
||||
|
||||
$bottom = $diff;
|
||||
}
|
||||
else if ( $top === "auto" ) {
|
||||
|
||||
if ( $margin_top === "auto" ) $margin_top = 0;
|
||||
if ( $margin_bottom === "auto" ) $margin_bottom = 0;
|
||||
|
||||
$top = $diff;
|
||||
}
|
||||
else if ( $height === "auto" ) {
|
||||
|
||||
if ( $margin_top === "auto" ) $margin_top = 0;
|
||||
if ( $margin_bottom === "auto" ) $margin_bottom = 0;
|
||||
|
||||
$height = $diff;
|
||||
}
|
||||
else if ( $bottom === "auto" ) {
|
||||
|
||||
if ( $margin_top === "auto" ) $margin_top = 0;
|
||||
if ( $margin_bottom === "auto" ) $margin_bottom = 0;
|
||||
|
||||
$bottom = $diff;
|
||||
}
|
||||
else {
|
||||
|
||||
if ( $style->overflow === "visible" ) {
|
||||
// set all autos to zero
|
||||
if ( $margin_top === "auto" ) $margin_top = 0;
|
||||
if ( $margin_bottom === "auto" ) $margin_bottom = 0;
|
||||
if ( $top === "auto" ) $top = 0;
|
||||
if ( $bottom === "auto" ) $bottom = 0;
|
||||
if ( $height === "auto" ) $height = $content_height;
|
||||
}
|
||||
|
||||
// FIXME: overflow hidden
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
else {
|
||||
|
||||
// Expand the height if overflow is visible
|
||||
if ( $height === "auto" && $content_height > $height /* && $style->overflow === "visible" */) {
|
||||
$height = $content_height;
|
||||
}
|
||||
|
||||
// FIXME: this should probably be moved to a seperate function as per
|
||||
// _calculate_restricted_width
|
||||
|
||||
// Only handle min/max height if the height is independent of the frame's content
|
||||
if ( !($style->overflow === "visible" ||
|
||||
($style->overflow === "hidden" && $height === "auto")) ) {
|
||||
|
||||
$min_height = $style->min_height;
|
||||
$max_height = $style->max_height;
|
||||
|
||||
if ( isset($cb["h"]) ) {
|
||||
$min_height = $style->length_in_pt($min_height, $cb["h"]);
|
||||
$max_height = $style->length_in_pt($max_height, $cb["h"]);
|
||||
|
||||
}
|
||||
else if ( isset($cb["w"]) ) {
|
||||
|
||||
if ( mb_strpos($min_height, "%") !== false ) {
|
||||
$min_height = 0;
|
||||
}
|
||||
else {
|
||||
$min_height = $style->length_in_pt($min_height, $cb["w"]);
|
||||
}
|
||||
|
||||
if ( mb_strpos($max_height, "%") !== false ) {
|
||||
$max_height = "none";
|
||||
}
|
||||
else {
|
||||
$max_height = $style->length_in_pt($max_height, $cb["w"]);
|
||||
}
|
||||
}
|
||||
|
||||
if ( $max_height !== "none" && $min_height > $max_height ) {
|
||||
// Swap 'em
|
||||
list($max_height, $min_height) = array($min_height, $max_height);
|
||||
}
|
||||
|
||||
if ( $max_height !== "none" && $height > $max_height ) {
|
||||
$height = $max_height;
|
||||
}
|
||||
|
||||
if ( $height < $min_height ) {
|
||||
$height = $min_height;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return array($height, $margin_top, $margin_bottom, $top, $bottom);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Adjust the justification of each of our lines.
|
||||
* http://www.w3.org/TR/CSS21/text.html#propdef-text-align
|
||||
*/
|
||||
protected function _text_align() {
|
||||
$style = $this->_frame->get_style();
|
||||
$w = $this->_frame->get_containing_block("w");
|
||||
$width = $style->length_in_pt($style->width, $w);
|
||||
|
||||
switch ($style->text_align) {
|
||||
default:
|
||||
case "left":
|
||||
foreach ($this->_frame->get_line_boxes() as $line) {
|
||||
if ( !$line->left ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
foreach($line->get_frames() as $frame) {
|
||||
if ( $frame instanceof Block_Frame_Decorator) {
|
||||
continue;
|
||||
}
|
||||
$frame->set_position( $frame->get_position("x") + $line->left );
|
||||
}
|
||||
}
|
||||
return;
|
||||
|
||||
case "right":
|
||||
foreach ($this->_frame->get_line_boxes() as $line) {
|
||||
// Move each child over by $dx
|
||||
$dx = $width - $line->w - $line->right;
|
||||
|
||||
foreach($line->get_frames() as $frame) {
|
||||
// Block frames are not aligned by text-align
|
||||
if ($frame instanceof Block_Frame_Decorator) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$frame->set_position( $frame->get_position("x") + $dx );
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
case "justify":
|
||||
// We justify all lines except the last one
|
||||
$lines = $this->_frame->get_line_boxes(); // needs to be a variable (strict standards)
|
||||
array_pop($lines);
|
||||
|
||||
foreach($lines as $i => $line) {
|
||||
if ( $line->br ) {
|
||||
unset($lines[$i]);
|
||||
}
|
||||
}
|
||||
|
||||
// One space character's width. Will be used to get a more accurate spacing
|
||||
$space_width = Font_Metrics::get_text_width(" ", $style->font_family, $style->font_size);
|
||||
|
||||
foreach ($lines as $line) {
|
||||
if ( $line->left ) {
|
||||
foreach ( $line->get_frames() as $frame ) {
|
||||
if ( !$frame instanceof Text_Frame_Decorator ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$frame->set_position( $frame->get_position("x") + $line->left );
|
||||
}
|
||||
}
|
||||
|
||||
// Only set the spacing if the line is long enough. This is really
|
||||
// just an aesthetic choice ;)
|
||||
//if ( $line["left"] + $line["w"] + $line["right"] > self::MIN_JUSTIFY_WIDTH * $width ) {
|
||||
|
||||
// Set the spacing for each child
|
||||
if ( $line->wc > 1 ) {
|
||||
$spacing = ($width - ($line->left + $line->w + $line->right) + $space_width) / ($line->wc - 1);
|
||||
}
|
||||
else {
|
||||
$spacing = 0;
|
||||
}
|
||||
|
||||
$dx = 0;
|
||||
foreach($line->get_frames() as $frame) {
|
||||
if ( !$frame instanceof Text_Frame_Decorator ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$text = $frame->get_text();
|
||||
$spaces = mb_substr_count($text, " ");
|
||||
|
||||
$char_spacing = $style->length_in_pt($style->letter_spacing);
|
||||
$_spacing = $spacing + $char_spacing;
|
||||
|
||||
$frame->set_position( $frame->get_position("x") + $dx );
|
||||
$frame->set_text_spacing($_spacing);
|
||||
|
||||
$dx += $spaces * $_spacing;
|
||||
}
|
||||
|
||||
// The line (should) now occupy the entire width
|
||||
$line->w = $width;
|
||||
|
||||
//}
|
||||
}
|
||||
break;
|
||||
|
||||
case "center":
|
||||
case "centre":
|
||||
foreach ($this->_frame->get_line_boxes() as $line) {
|
||||
// Centre each line by moving each frame in the line by:
|
||||
$dx = ($width + $line->left - $line->w - $line->right ) / 2;
|
||||
|
||||
foreach ($line->get_frames() as $frame) {
|
||||
// Block frames are not aligned by text-align
|
||||
if ($frame instanceof Block_Frame_Decorator) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$frame->set_position( $frame->get_position("x") + $dx );
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Align inline children vertically.
|
||||
* Aligns each child vertically after each line is reflowed
|
||||
*/
|
||||
function vertical_align() {
|
||||
|
||||
$canvas = null;
|
||||
|
||||
foreach ( $this->_frame->get_line_boxes() as $line ) {
|
||||
|
||||
$height = $line->h;
|
||||
|
||||
foreach ( $line->get_frames() as $frame ) {
|
||||
$style = $frame->get_style();
|
||||
|
||||
if ( $style->display !== "inline" ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$align = $frame->get_parent()->get_style()->vertical_align;
|
||||
|
||||
if ( !isset($canvas) ) {
|
||||
$canvas = $frame->get_root()->get_dompdf()->get_canvas();
|
||||
}
|
||||
|
||||
$baseline = $canvas->get_font_baseline($style->font_family, $style->font_size);
|
||||
$y_offset = 0;
|
||||
|
||||
switch ($align) {
|
||||
case "baseline":
|
||||
$y_offset = $height*0.8 - $baseline; // The 0.8 ratio is arbitrary until we find it's meaning
|
||||
break;
|
||||
|
||||
case "middle":
|
||||
$y_offset = ($height*0.8 - $baseline) / 2;
|
||||
break;
|
||||
|
||||
case "sub":
|
||||
$y_offset = 0.3 * $height;
|
||||
break;
|
||||
|
||||
case "super":
|
||||
$y_offset = -0.2 * $height;
|
||||
break;
|
||||
|
||||
case "text-top":
|
||||
case "top": // Not strictly accurate, but good enough for now
|
||||
break;
|
||||
|
||||
case "text-bottom":
|
||||
case "bottom":
|
||||
$y_offset = $height*0.8 - $baseline;
|
||||
break;
|
||||
}
|
||||
|
||||
if ( $y_offset ) {
|
||||
$frame->move(0, $y_offset);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Frame $child
|
||||
*/
|
||||
function process_clear(Frame $child){
|
||||
$enable_css_float = $this->get_dompdf()->get_option("enable_css_float");
|
||||
if ( !$enable_css_float ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$child_style = $child->get_style();
|
||||
$root = $this->_frame->get_root();
|
||||
|
||||
// Handle "clear"
|
||||
if ( $child_style->clear !== "none" ) {
|
||||
$lowest_y = $root->get_lowest_float_offset($child);
|
||||
|
||||
// If a float is still applying, we handle it
|
||||
if ( $lowest_y ) {
|
||||
if ( $child->is_in_flow() ) {
|
||||
$line_box = $this->_frame->get_current_line_box();
|
||||
$line_box->y = $lowest_y + $child->get_margin_height();
|
||||
$line_box->left = 0;
|
||||
$line_box->right = 0;
|
||||
}
|
||||
|
||||
$child->move(0, $lowest_y - $child->get_position("y"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Frame $child
|
||||
* @param float $cb_x
|
||||
* @param float $cb_w
|
||||
*/
|
||||
function process_float(Frame $child, $cb_x, $cb_w){
|
||||
$enable_css_float = $this->_frame->get_dompdf()->get_option("enable_css_float");
|
||||
if ( !$enable_css_float ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$child_style = $child->get_style();
|
||||
$root = $this->_frame->get_root();
|
||||
|
||||
// Handle "float"
|
||||
if ( $child_style->float !== "none" ) {
|
||||
$root->add_floating_frame($child);
|
||||
|
||||
// Remove next frame's beginning whitespace
|
||||
$next = $child->get_next_sibling();
|
||||
if ( $next && $next instanceof Text_Frame_Decorator) {
|
||||
$next->set_text(ltrim($next->get_text()));
|
||||
}
|
||||
|
||||
$line_box = $this->_frame->get_current_line_box();
|
||||
list($old_x, $old_y) = $child->get_position();
|
||||
|
||||
$float_x = $cb_x;
|
||||
$float_y = $old_y;
|
||||
$float_w = $child->get_margin_width();
|
||||
|
||||
if ( $child_style->clear === "none" ) {
|
||||
switch( $child_style->float ) {
|
||||
case "left":
|
||||
$float_x += $line_box->left;
|
||||
break;
|
||||
case "right":
|
||||
$float_x += ($cb_w - $line_box->right - $float_w);
|
||||
break;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if ( $child_style->float === "right" ) {
|
||||
$float_x += ($cb_w - $float_w);
|
||||
}
|
||||
}
|
||||
|
||||
if ( $cb_w < $float_x + $float_w - $old_x ) {
|
||||
// TODO handle when floating elements don't fit
|
||||
}
|
||||
|
||||
$line_box->get_float_offsets();
|
||||
|
||||
if ( $child->_float_next_line ) {
|
||||
$float_y += $line_box->h;
|
||||
}
|
||||
|
||||
$child->set_position($float_x, $float_y);
|
||||
$child->move($float_x - $old_x, $float_y - $old_y, true);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Frame_Decorator $block
|
||||
*/
|
||||
function reflow(Block_Frame_Decorator $block = null) {
|
||||
|
||||
// Check if a page break is forced
|
||||
$page = $this->_frame->get_root();
|
||||
$page->check_forced_page_break($this->_frame);
|
||||
|
||||
// Bail if the page is full
|
||||
if ( $page->is_full() ) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Generated content
|
||||
$this->_set_content();
|
||||
|
||||
// Collapse margins if required
|
||||
$this->_collapse_margins();
|
||||
|
||||
$style = $this->_frame->get_style();
|
||||
$cb = $this->_frame->get_containing_block();
|
||||
|
||||
if ( $style->position === "fixed" ) {
|
||||
$cb = $this->_frame->get_root()->get_containing_block();
|
||||
}
|
||||
|
||||
// Determine the constraints imposed by this frame: calculate the width
|
||||
// of the content area:
|
||||
list($w, $left_margin, $right_margin, $left, $right) = $this->_calculate_restricted_width();
|
||||
|
||||
// Store the calculated properties
|
||||
$style->width = $w . "pt";
|
||||
$style->margin_left = $left_margin."pt";
|
||||
$style->margin_right = $right_margin."pt";
|
||||
$style->left = $left ."pt";
|
||||
$style->right = $right . "pt";
|
||||
|
||||
// Update the position
|
||||
$this->_frame->position();
|
||||
list($x, $y) = $this->_frame->get_position();
|
||||
|
||||
// Adjust the first line based on the text-indent property
|
||||
$indent = $style->length_in_pt($style->text_indent, $cb["w"]);
|
||||
$this->_frame->increase_line_width($indent);
|
||||
|
||||
// Determine the content edge
|
||||
$top = $style->length_in_pt(array($style->margin_top,
|
||||
$style->padding_top,
|
||||
$style->border_top_width), $cb["h"]);
|
||||
|
||||
$bottom = $style->length_in_pt(array($style->border_bottom_width,
|
||||
$style->margin_bottom,
|
||||
$style->padding_bottom), $cb["h"]);
|
||||
|
||||
$cb_x = $x + $left_margin + $style->length_in_pt(array($style->border_left_width,
|
||||
$style->padding_left), $cb["w"]);
|
||||
|
||||
$cb_y = $y + $top;
|
||||
|
||||
$cb_h = ($cb["h"] + $cb["y"]) - $bottom - $cb_y;
|
||||
|
||||
// Set the y position of the first line in this block
|
||||
$line_box = $this->_frame->get_current_line_box();
|
||||
$line_box->y = $cb_y;
|
||||
$line_box->get_float_offsets();
|
||||
|
||||
// Set the containing blocks and reflow each child
|
||||
foreach ( $this->_frame->get_children() as $child ) {
|
||||
|
||||
// Bail out if the page is full
|
||||
if ( $page->is_full() ) {
|
||||
break;
|
||||
}
|
||||
|
||||
$child->set_containing_block($cb_x, $cb_y, $w, $cb_h);
|
||||
|
||||
$this->process_clear($child);
|
||||
|
||||
$child->reflow($this->_frame);
|
||||
|
||||
// Don't add the child to the line if a page break has occurred
|
||||
if ( $page->check_page_break($child) ) {
|
||||
break;
|
||||
}
|
||||
|
||||
$this->process_float($child, $cb_x, $w);
|
||||
}
|
||||
|
||||
// Determine our height
|
||||
list($height, $margin_top, $margin_bottom, $top, $bottom) = $this->_calculate_restricted_height();
|
||||
$style->height = $height;
|
||||
$style->margin_top = $margin_top;
|
||||
$style->margin_bottom = $margin_bottom;
|
||||
$style->top = $top;
|
||||
$style->bottom = $bottom;
|
||||
|
||||
$needs_reposition = ($style->position === "absolute" && ($style->right !== "auto" || $style->bottom !== "auto"));
|
||||
|
||||
// Absolute positioning measurement
|
||||
if ( $needs_reposition ) {
|
||||
$orig_style = $this->_frame->get_original_style();
|
||||
if ( $orig_style->width === "auto" && ($orig_style->left === "auto" || $orig_style->right === "auto") ) {
|
||||
$width = 0;
|
||||
foreach ($this->_frame->get_line_boxes() as $line) {
|
||||
$width = max($line->w, $width);
|
||||
}
|
||||
$style->width = $width;
|
||||
}
|
||||
|
||||
$style->left = $orig_style->left;
|
||||
$style->right = $orig_style->right;
|
||||
}
|
||||
|
||||
$this->_text_align();
|
||||
$this->vertical_align();
|
||||
|
||||
// Absolute positioning
|
||||
if ( $needs_reposition ) {
|
||||
list($x, $y) = $this->_frame->get_position();
|
||||
$this->_frame->position();
|
||||
list($new_x, $new_y) = $this->_frame->get_position();
|
||||
$this->_frame->move($new_x-$x, $new_y-$y, true);
|
||||
}
|
||||
|
||||
if ( $block && $this->_frame->is_in_flow() ) {
|
||||
$block->add_frame_to_line($this->_frame);
|
||||
|
||||
// May be inline-block
|
||||
if ( $style->display === "block" ) {
|
||||
$block->add_line();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,57 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* @package dompdf
|
||||
* @link http://dompdf.github.com/
|
||||
* @author Benj Carson <benjcarson@digitaljunkies.ca>
|
||||
* @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License
|
||||
*/
|
||||
|
||||
/**
|
||||
* Positions block frames
|
||||
*
|
||||
* @access private
|
||||
* @package dompdf
|
||||
*/
|
||||
class Block_Positioner extends Positioner {
|
||||
|
||||
|
||||
function __construct(Frame_Decorator $frame) { parent::__construct($frame); }
|
||||
|
||||
//........................................................................
|
||||
|
||||
function position() {
|
||||
$frame = $this->_frame;
|
||||
$style = $frame->get_style();
|
||||
$cb = $frame->get_containing_block();
|
||||
$p = $frame->find_block_parent();
|
||||
|
||||
if ( $p ) {
|
||||
$float = $style->float;
|
||||
|
||||
$enable_css_float = $frame->get_dompdf()->get_option("enable_css_float");
|
||||
if ( !$enable_css_float || !$float || $float === "none" ) {
|
||||
$p->add_line(true);
|
||||
}
|
||||
$y = $p->get_current_line_box()->y;
|
||||
|
||||
}
|
||||
else {
|
||||
$y = $cb["y"];
|
||||
}
|
||||
|
||||
$x = $cb["x"];
|
||||
|
||||
// Relative positionning
|
||||
if ( $style->position === "relative" ) {
|
||||
$top = $style->length_in_pt($style->top, $cb["h"]);
|
||||
//$right = $style->length_in_pt($style->right, $cb["w"]);
|
||||
//$bottom = $style->length_in_pt($style->bottom, $cb["h"]);
|
||||
$left = $style->length_in_pt($style->left, $cb["w"]);
|
||||
|
||||
$x += $left;
|
||||
$y += $top;
|
||||
}
|
||||
|
||||
$frame->set_position($x, $y);
|
||||
}
|
||||
}
|
||||
@@ -1,230 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* @package dompdf
|
||||
* @link http://dompdf.github.com/
|
||||
* @author Benj Carson <benjcarson@digitaljunkies.ca>
|
||||
* @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License
|
||||
*/
|
||||
|
||||
/**
|
||||
* Renders block frames
|
||||
*
|
||||
* @access private
|
||||
* @package dompdf
|
||||
*/
|
||||
class Block_Renderer extends Abstract_Renderer {
|
||||
|
||||
//........................................................................
|
||||
|
||||
function render(Frame $frame) {
|
||||
$style = $frame->get_style();
|
||||
$node = $frame->get_node();
|
||||
|
||||
list($x, $y, $w, $h) = $frame->get_border_box();
|
||||
|
||||
$this->_set_opacity( $frame->get_opacity( $style->opacity ) );
|
||||
|
||||
if ( $node->nodeName === "body" ) {
|
||||
$h = $frame->get_containing_block("h") - $style->length_in_pt(array(
|
||||
$style->margin_top,
|
||||
$style->border_top_width,
|
||||
$style->border_bottom_width,
|
||||
$style->margin_bottom),
|
||||
$style->width);
|
||||
}
|
||||
|
||||
// Handle anchors & links
|
||||
if ( $node->nodeName === "a" && $href = $node->getAttribute("href") ) {
|
||||
$this->_canvas->add_link($href, $x, $y, $w, $h);
|
||||
}
|
||||
|
||||
// Draw our background, border and content
|
||||
list($tl, $tr, $br, $bl) = $style->get_computed_border_radius($w, $h);
|
||||
|
||||
if ( $tl + $tr + $br + $bl > 0 ) {
|
||||
$this->_canvas->clipping_roundrectangle( $x, $y, $w, $h, $tl, $tr, $br, $bl );
|
||||
}
|
||||
|
||||
if ( ($bg = $style->background_color) !== "transparent" ) {
|
||||
$this->_canvas->filled_rectangle( $x, $y, $w, $h, $bg );
|
||||
}
|
||||
|
||||
if ( ($url = $style->background_image) && $url !== "none" ) {
|
||||
$this->_background_image($url, $x, $y, $w, $h, $style);
|
||||
}
|
||||
|
||||
if ( $tl + $tr + $br + $bl > 0 ) {
|
||||
$this->_canvas->clipping_end();
|
||||
}
|
||||
|
||||
$border_box = array($x, $y, $w, $h);
|
||||
$this->_render_border($frame, $border_box);
|
||||
$this->_render_outline($frame, $border_box);
|
||||
|
||||
if (DEBUG_LAYOUT && DEBUG_LAYOUT_BLOCKS) {
|
||||
$this->_debug_layout($frame->get_border_box(), "red");
|
||||
if (DEBUG_LAYOUT_PADDINGBOX) {
|
||||
$this->_debug_layout($frame->get_padding_box(), "red", array(0.5, 0.5));
|
||||
}
|
||||
}
|
||||
|
||||
if (DEBUG_LAYOUT && DEBUG_LAYOUT_LINES && $frame->get_decorator()) {
|
||||
foreach ($frame->get_decorator()->get_line_boxes() as $line) {
|
||||
$frame->_debug_layout(array($line->x, $line->y, $line->w, $line->h), "orange");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected function _render_border(Frame_Decorator $frame, $border_box = null, $corner_style = "bevel") {
|
||||
$style = $frame->get_style();
|
||||
$bp = $style->get_border_properties();
|
||||
|
||||
if ( empty($border_box) ) {
|
||||
$border_box = $frame->get_border_box();
|
||||
}
|
||||
|
||||
// find the radius
|
||||
$radius = $style->get_computed_border_radius($border_box[2], $border_box[3]); // w, h
|
||||
|
||||
// Short-cut: If all the borders are "solid" with the same color and style, and no radius, we'd better draw a rectangle
|
||||
if (
|
||||
in_array($bp["top"]["style"], array("solid", "dashed", "dotted")) &&
|
||||
$bp["top"] == $bp["right"] &&
|
||||
$bp["right"] == $bp["bottom"] &&
|
||||
$bp["bottom"] == $bp["left"] &&
|
||||
array_sum($radius) == 0
|
||||
) {
|
||||
$props = $bp["top"];
|
||||
if ( $props["color"] === "transparent" || $props["width"] <= 0 ) return;
|
||||
|
||||
list($x, $y, $w, $h) = $border_box;
|
||||
$width = $style->length_in_pt($props["width"]);
|
||||
$pattern = $this->_get_dash_pattern($props["style"], $width);
|
||||
$this->_canvas->rectangle($x + $width / 2, $y + $width / 2, $w - $width, $h - $width, $props["color"], $width, $pattern);
|
||||
return;
|
||||
}
|
||||
|
||||
// Do it the long way
|
||||
$widths = array($style->length_in_pt($bp["top"]["width"]),
|
||||
$style->length_in_pt($bp["right"]["width"]),
|
||||
$style->length_in_pt($bp["bottom"]["width"]),
|
||||
$style->length_in_pt($bp["left"]["width"]));
|
||||
|
||||
foreach ($bp as $side => $props) {
|
||||
list($x, $y, $w, $h) = $border_box;
|
||||
$length = 0;
|
||||
$r1 = 0;
|
||||
$r2 = 0;
|
||||
|
||||
if ( !$props["style"] ||
|
||||
$props["style"] === "none" ||
|
||||
$props["width"] <= 0 ||
|
||||
$props["color"] == "transparent" )
|
||||
continue;
|
||||
|
||||
switch($side) {
|
||||
case "top":
|
||||
$length = $w;
|
||||
$r1 = $radius["top-left"];
|
||||
$r2 = $radius["top-right"];
|
||||
break;
|
||||
|
||||
case "bottom":
|
||||
$length = $w;
|
||||
$y += $h;
|
||||
$r1 = $radius["bottom-left"];
|
||||
$r2 = $radius["bottom-right"];
|
||||
break;
|
||||
|
||||
case "left":
|
||||
$length = $h;
|
||||
$r1 = $radius["top-left"];
|
||||
$r2 = $radius["bottom-left"];
|
||||
break;
|
||||
|
||||
case "right":
|
||||
$length = $h;
|
||||
$x += $w;
|
||||
$r1 = $radius["top-right"];
|
||||
$r2 = $radius["bottom-right"];
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
$method = "_border_" . $props["style"];
|
||||
|
||||
// draw rounded corners
|
||||
$this->$method($x, $y, $length, $props["color"], $widths, $side, $corner_style, $r1, $r2);
|
||||
}
|
||||
}
|
||||
|
||||
protected function _render_outline(Frame_Decorator $frame, $border_box = null, $corner_style = "bevel") {
|
||||
$style = $frame->get_style();
|
||||
|
||||
$props = array(
|
||||
"width" => $style->outline_width,
|
||||
"style" => $style->outline_style,
|
||||
"color" => $style->outline_color,
|
||||
);
|
||||
|
||||
if ( !$props["style"] || $props["style"] === "none" || $props["width"] <= 0 )
|
||||
return;
|
||||
|
||||
if ( empty($border_box) ) {
|
||||
$border_box = $frame->get_border_box();
|
||||
}
|
||||
|
||||
$offset = $style->length_in_pt($props["width"]);
|
||||
$pattern = $this->_get_dash_pattern($props["style"], $offset);
|
||||
|
||||
// If the outline style is "solid" we'd better draw a rectangle
|
||||
if ( in_array($props["style"], array("solid", "dashed", "dotted")) ) {
|
||||
$border_box[0] -= $offset / 2;
|
||||
$border_box[1] -= $offset / 2;
|
||||
$border_box[2] += $offset;
|
||||
$border_box[3] += $offset;
|
||||
|
||||
list($x, $y, $w, $h) = $border_box;
|
||||
$this->_canvas->rectangle($x, $y, $w, $h, $props["color"], $offset, $pattern);
|
||||
return;
|
||||
}
|
||||
|
||||
$border_box[0] -= $offset;
|
||||
$border_box[1] -= $offset;
|
||||
$border_box[2] += $offset * 2;
|
||||
$border_box[3] += $offset * 2;
|
||||
|
||||
$method = "_border_" . $props["style"];
|
||||
$widths = array_fill(0, 4, $props["width"]);
|
||||
$sides = array("top", "right", "left", "bottom");
|
||||
$length = 0;
|
||||
|
||||
foreach ($sides as $side) {
|
||||
list($x, $y, $w, $h) = $border_box;
|
||||
|
||||
switch($side) {
|
||||
case "top":
|
||||
$length = $w;
|
||||
break;
|
||||
|
||||
case "bottom":
|
||||
$length = $w;
|
||||
$y += $h;
|
||||
break;
|
||||
|
||||
case "left":
|
||||
$length = $h;
|
||||
break;
|
||||
|
||||
case "right":
|
||||
$length = $h;
|
||||
$x += $w;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
$this->$method($x, $y, $length, $props["color"], $widths, $side, $corner_style);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,164 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* @package dompdf
|
||||
* @link http://dompdf.github.com/
|
||||
* @author Benj Carson <benjcarson@digitaljunkies.ca>
|
||||
* @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License
|
||||
*/
|
||||
|
||||
/**
|
||||
* Caching canvas implementation
|
||||
*
|
||||
* Each rendered page is serialized and stored in the {@link Page_Cache}.
|
||||
* This is useful for static forms/pages that do not need to be re-rendered
|
||||
* all the time.
|
||||
*
|
||||
* This class decorates normal CPDF_Adapters. It is currently completely
|
||||
* experimental.
|
||||
*
|
||||
* @access private
|
||||
* @package dompdf
|
||||
*/
|
||||
class Cached_PDF_Decorator extends CPDF_Adapter implements Canvas {
|
||||
/**
|
||||
* @var CPDF_Adapter
|
||||
*/
|
||||
protected $_pdf;
|
||||
protected $_cache_id;
|
||||
protected $_current_page_id;
|
||||
protected $_fonts; // fonts used in this document
|
||||
|
||||
function __construct($paper = "letter", $orientation = "portrait", DOMPDF $dompdf) {
|
||||
$this->_fonts = array();
|
||||
}
|
||||
|
||||
/**
|
||||
* Must be called after constructor
|
||||
*
|
||||
* @param int $cache_id
|
||||
* @param CPDF_Adapter $pdf
|
||||
*/
|
||||
function init($cache_id, CPDF_Adapter $pdf) {
|
||||
$this->_cache_id = $cache_id;
|
||||
$this->_pdf = $pdf;
|
||||
$this->_current_page_id = $this->_pdf->open_object();
|
||||
}
|
||||
|
||||
//........................................................................
|
||||
|
||||
function get_cpdf() { return $this->_pdf->get_cpdf(); }
|
||||
|
||||
function open_object() { $this->_pdf->open_object(); }
|
||||
function reopen_object($object) { $this->_pdf->reopen_object($object); }
|
||||
|
||||
function close_object() { $this->_pdf->close_object(); }
|
||||
|
||||
function add_object($object, $where = 'all') { $this->_pdf->add_object($object, $where); }
|
||||
|
||||
function serialize_object($id) { $this->_pdf->serialize_object($id); }
|
||||
|
||||
function reopen_serialized_object($obj) { $this->_pdf->reopen_serialized_object($obj); }
|
||||
|
||||
//........................................................................
|
||||
|
||||
function get_width() { return $this->_pdf->get_width(); }
|
||||
function get_height() { return $this->_pdf->get_height(); }
|
||||
function get_page_number() { return $this->_pdf->get_page_number(); }
|
||||
function get_page_count() { return $this->_pdf->get_page_count(); }
|
||||
|
||||
function set_page_number($num) { $this->_pdf->set_page_number($num); }
|
||||
function set_page_count($count) { $this->_pdf->set_page_count($count); }
|
||||
|
||||
function line($x1, $y1, $x2, $y2, $color, $width, $style = array()) {
|
||||
$this->_pdf->line($x1, $y1, $x2, $y2, $color, $width, $style);
|
||||
}
|
||||
|
||||
function rectangle($x1, $y1, $w, $h, $color, $width, $style = array()) {
|
||||
$this->_pdf->rectangle($x1, $y1, $w, $h, $color, $width, $style);
|
||||
}
|
||||
|
||||
function filled_rectangle($x1, $y1, $w, $h, $color) {
|
||||
$this->_pdf->filled_rectangle($x1, $y1, $w, $h, $color);
|
||||
}
|
||||
|
||||
function polygon($points, $color, $width = null, $style = array(), $fill = false) {
|
||||
$this->_pdf->polygon($points, $color, $width, $style, $fill);
|
||||
}
|
||||
|
||||
function circle($x, $y, $r1, $color, $width = null, $style = null, $fill = false) {
|
||||
$this->_pdf->circle($x, $y, $r1, $color, $width, $style, $fill);
|
||||
}
|
||||
|
||||
function image($img_url, $x, $y, $w, $h, $resolution = "normal") {
|
||||
$this->_pdf->image($img_url, $x, $y, $w, $h, $resolution);
|
||||
}
|
||||
|
||||
function text($x, $y, $text, $font, $size, $color = array(0,0,0), $word_space = 0.0, $char_space = 0.0, $angle = 0.0) {
|
||||
$this->_fonts[$font] = true;
|
||||
$this->_pdf->text($x, $y, $text, $font, $size, $color, $word_space, $char_space, $angle);
|
||||
}
|
||||
|
||||
function page_text($x, $y, $text, $font, $size, $color = array(0,0,0), $word_space = 0.0, $char_space = 0.0, $angle = 0.0) {
|
||||
|
||||
// We want to remove this from cached pages since it may not be correct
|
||||
$this->_pdf->close_object();
|
||||
$this->_pdf->page_text($x, $y, $text, $font, $size, $color, $word_space, $char_space, $angle);
|
||||
$this->_pdf->reopen_object($this->_current_page_id);
|
||||
}
|
||||
|
||||
function page_script($script, $type = 'text/php') {
|
||||
|
||||
// We want to remove this from cached pages since it may not be correct
|
||||
$this->_pdf->close_object();
|
||||
$this->_pdf->page_script($script, $type);
|
||||
$this->_pdf->reopen_object($this->_current_page_id);
|
||||
}
|
||||
|
||||
function new_page() {
|
||||
$this->_pdf->close_object();
|
||||
|
||||
// Add the object to the current page
|
||||
$this->_pdf->add_object($this->_current_page_id, "add");
|
||||
$this->_pdf->new_page();
|
||||
|
||||
Page_Cache::store_page($this->_cache_id,
|
||||
$this->_pdf->get_page_number() - 1,
|
||||
$this->_pdf->serialize_object($this->_current_page_id));
|
||||
|
||||
$this->_current_page_id = $this->_pdf->open_object();
|
||||
return $this->_current_page_id;
|
||||
}
|
||||
|
||||
function stream($filename, $options = null) {
|
||||
// Store the last page in the page cache
|
||||
if ( !is_null($this->_current_page_id) ) {
|
||||
$this->_pdf->close_object();
|
||||
$this->_pdf->add_object($this->_current_page_id, "add");
|
||||
Page_Cache::store_page($this->_cache_id,
|
||||
$this->_pdf->get_page_number(),
|
||||
$this->_pdf->serialize_object($this->_current_page_id));
|
||||
Page_Cache::store_fonts($this->_cache_id, $this->_fonts);
|
||||
$this->_current_page_id = null;
|
||||
}
|
||||
|
||||
$this->_pdf->stream($filename);
|
||||
|
||||
}
|
||||
|
||||
function output($options = null) {
|
||||
// Store the last page in the page cache
|
||||
if ( !is_null($this->_current_page_id) ) {
|
||||
$this->_pdf->close_object();
|
||||
$this->_pdf->add_object($this->_current_page_id, "add");
|
||||
Page_Cache::store_page($this->_cache_id,
|
||||
$this->_pdf->get_page_number(),
|
||||
$this->_pdf->serialize_object($this->_current_page_id));
|
||||
$this->_current_page_id = null;
|
||||
}
|
||||
|
||||
return $this->_pdf->output();
|
||||
}
|
||||
|
||||
function get_messages() { return $this->_pdf->get_messages(); }
|
||||
|
||||
}
|
||||
@@ -1,385 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* @package dompdf
|
||||
* @link http://dompdf.github.com/
|
||||
* @author Benj Carson <benjcarson@digitaljunkies.ca>
|
||||
* @author Fabien Ménager <fabien.menager@gmail.com>
|
||||
* @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License
|
||||
*/
|
||||
|
||||
/**
|
||||
* Main rendering interface
|
||||
*
|
||||
* Currently {@link CPDF_Adapter}, {@link PDFLib_Adapter}, {@link TCPDF_Adapter}, and {@link GD_Adapter}
|
||||
* implement this interface.
|
||||
*
|
||||
* Implementations should measure x and y increasing to the left and down,
|
||||
* respectively, with the origin in the top left corner. Implementations
|
||||
* are free to use a unit other than points for length, but I can't
|
||||
* guarantee that the results will look any good.
|
||||
*
|
||||
* @package dompdf
|
||||
*/
|
||||
interface Canvas {
|
||||
function __construct($paper = "letter", $orientation = "portrait", DOMPDF $dompdf);
|
||||
|
||||
/**
|
||||
* @return DOMPDF
|
||||
*/
|
||||
function get_dompdf();
|
||||
|
||||
/**
|
||||
* Returns the current page number
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
function get_page_number();
|
||||
|
||||
/**
|
||||
* Returns the total number of pages
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
function get_page_count();
|
||||
|
||||
/**
|
||||
* Sets the total number of pages
|
||||
*
|
||||
* @param int $count
|
||||
*/
|
||||
function set_page_count($count);
|
||||
|
||||
/**
|
||||
* Draws a line from x1,y1 to x2,y2
|
||||
*
|
||||
* See {@link Style::munge_color()} for the format of the color array.
|
||||
* See {@link Cpdf::setLineStyle()} for a description of the format of the
|
||||
* $style parameter (aka dash).
|
||||
*
|
||||
* @param float $x1
|
||||
* @param float $y1
|
||||
* @param float $x2
|
||||
* @param float $y2
|
||||
* @param array $color
|
||||
* @param float $width
|
||||
* @param array $style
|
||||
*/
|
||||
function line($x1, $y1, $x2, $y2, $color, $width, $style = null);
|
||||
|
||||
/**
|
||||
* Draws a rectangle at x1,y1 with width w and height h
|
||||
*
|
||||
* See {@link Style::munge_color()} for the format of the color array.
|
||||
* See {@link Cpdf::setLineStyle()} for a description of the $style
|
||||
* parameter (aka dash)
|
||||
*
|
||||
* @param float $x1
|
||||
* @param float $y1
|
||||
* @param float $w
|
||||
* @param float $h
|
||||
* @param array $color
|
||||
* @param float $width
|
||||
* @param array $style
|
||||
*/
|
||||
function rectangle($x1, $y1, $w, $h, $color, $width, $style = null);
|
||||
|
||||
/**
|
||||
* Draws a filled rectangle at x1,y1 with width w and height h
|
||||
*
|
||||
* See {@link Style::munge_color()} for the format of the color array.
|
||||
*
|
||||
* @param float $x1
|
||||
* @param float $y1
|
||||
* @param float $w
|
||||
* @param float $h
|
||||
* @param array $color
|
||||
*/
|
||||
function filled_rectangle($x1, $y1, $w, $h, $color);
|
||||
|
||||
/**
|
||||
* Starts a clipping rectangle at x1,y1 with width w and height h
|
||||
*
|
||||
* @param float $x1
|
||||
* @param float $y1
|
||||
* @param float $w
|
||||
* @param float $h
|
||||
*/
|
||||
function clipping_rectangle($x1, $y1, $w, $h);
|
||||
|
||||
/**
|
||||
* Starts a rounded clipping rectangle at x1,y1 with width w and height h
|
||||
*
|
||||
* @param float $x1
|
||||
* @param float $y1
|
||||
* @param float $w
|
||||
* @param float $h
|
||||
* @param float $tl
|
||||
* @param float $tr
|
||||
* @param float $br
|
||||
* @param float $bl
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
function clipping_roundrectangle($x1, $y1, $w, $h, $tl, $tr, $br, $bl);
|
||||
|
||||
/**
|
||||
* Ends the last clipping shape
|
||||
*/
|
||||
function clipping_end();
|
||||
|
||||
/**
|
||||
* Save current state
|
||||
*/
|
||||
function save();
|
||||
|
||||
/**
|
||||
* Restore last state
|
||||
*/
|
||||
function restore();
|
||||
|
||||
/**
|
||||
* Rotate
|
||||
*/
|
||||
function rotate($angle, $x, $y);
|
||||
|
||||
/**
|
||||
* Skew
|
||||
*/
|
||||
function skew($angle_x, $angle_y, $x, $y);
|
||||
|
||||
/**
|
||||
* Scale
|
||||
*/
|
||||
function scale($s_x, $s_y, $x, $y);
|
||||
|
||||
/**
|
||||
* Translate
|
||||
*/
|
||||
function translate($t_x, $t_y);
|
||||
|
||||
/**
|
||||
* Transform
|
||||
*/
|
||||
function transform($a, $b, $c, $d, $e, $f);
|
||||
|
||||
/**
|
||||
* Draws a polygon
|
||||
*
|
||||
* The polygon is formed by joining all the points stored in the $points
|
||||
* array. $points has the following structure:
|
||||
* <code>
|
||||
* array(0 => x1,
|
||||
* 1 => y1,
|
||||
* 2 => x2,
|
||||
* 3 => y2,
|
||||
* ...
|
||||
* );
|
||||
* </code>
|
||||
*
|
||||
* See {@link Style::munge_color()} for the format of the color array.
|
||||
* See {@link Cpdf::setLineStyle()} for a description of the $style
|
||||
* parameter (aka dash)
|
||||
*
|
||||
* @param array $points
|
||||
* @param array $color
|
||||
* @param float $width
|
||||
* @param array $style
|
||||
* @param bool $fill Fills the polygon if true
|
||||
*/
|
||||
function polygon($points, $color, $width = null, $style = null, $fill = false);
|
||||
|
||||
/**
|
||||
* Draws a circle at $x,$y with radius $r
|
||||
*
|
||||
* See {@link Style::munge_color()} for the format of the color array.
|
||||
* See {@link Cpdf::setLineStyle()} for a description of the $style
|
||||
* parameter (aka dash)
|
||||
*
|
||||
* @param float $x
|
||||
* @param float $y
|
||||
* @param float $r
|
||||
* @param array $color
|
||||
* @param float $width
|
||||
* @param array $style
|
||||
* @param bool $fill Fills the circle if true
|
||||
*/
|
||||
function circle($x, $y, $r, $color, $width = null, $style = null, $fill = false);
|
||||
|
||||
/**
|
||||
* Add an image to the pdf.
|
||||
*
|
||||
* The image is placed at the specified x and y coordinates with the
|
||||
* given width and height.
|
||||
*
|
||||
* @param string $img_url the path to the image
|
||||
* @param float $x x position
|
||||
* @param float $y y position
|
||||
* @param int $w width (in pixels)
|
||||
* @param int $h height (in pixels)
|
||||
* @param string $resolution The resolution of the image
|
||||
*/
|
||||
function image($img_url, $x, $y, $w, $h, $resolution = "normal");
|
||||
|
||||
/**
|
||||
* Add an arc to the PDF
|
||||
* See {@link Style::munge_color()} for the format of the color array.
|
||||
*
|
||||
* @param float $x X coordinate of the arc
|
||||
* @param float $y Y coordinate of the arc
|
||||
* @param float $r1 Radius 1
|
||||
* @param float $r2 Radius 2
|
||||
* @param float $astart Start angle in degrees
|
||||
* @param float $aend End angle in degrees
|
||||
* @param array $color Color
|
||||
* @param float $width
|
||||
* @param array $style
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
function arc($x, $y, $r1, $r2, $astart, $aend, $color, $width, $style = array());
|
||||
|
||||
/**
|
||||
* Writes text at the specified x and y coordinates
|
||||
* See {@link Style::munge_color()} for the format of the color array.
|
||||
*
|
||||
* @param float $x
|
||||
* @param float $y
|
||||
* @param string $text the text to write
|
||||
* @param string $font the font file to use
|
||||
* @param float $size the font size, in points
|
||||
* @param array $color
|
||||
* @param float $word_space word spacing adjustment
|
||||
* @param float $char_space char spacing adjustment
|
||||
* @param float $angle angle
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
function text($x, $y, $text, $font, $size, $color = array(0,0,0), $word_space = 0.0, $char_space = 0.0, $angle = 0.0);
|
||||
|
||||
/**
|
||||
* Add a named destination (similar to <a name="foo">...</a> in html)
|
||||
*
|
||||
* @param string $anchorname The name of the named destination
|
||||
*/
|
||||
function add_named_dest($anchorname);
|
||||
|
||||
/**
|
||||
* Add a link to the pdf
|
||||
*
|
||||
* @param string $url The url to link to
|
||||
* @param float $x The x position of the link
|
||||
* @param float $y The y position of the link
|
||||
* @param float $width The width of the link
|
||||
* @param float $height The height of the link
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
function add_link($url, $x, $y, $width, $height);
|
||||
|
||||
/**
|
||||
* Add meta information to the pdf
|
||||
*
|
||||
* @param string $name Label of the value (Creator, Producer, etc.)
|
||||
* @param string $value The text to set
|
||||
*/
|
||||
function add_info($name, $value);
|
||||
|
||||
/**
|
||||
* Calculates text size, in points
|
||||
*
|
||||
* @param string $text the text to be sized
|
||||
* @param string $font the desired font
|
||||
* @param float $size the desired font size
|
||||
* @param float $word_spacing word spacing, if any
|
||||
* @param float $char_spacing
|
||||
*
|
||||
* @return float
|
||||
*/
|
||||
function get_text_width($text, $font, $size, $word_spacing = 0.0, $char_spacing = 0.0);
|
||||
|
||||
/**
|
||||
* Calculates font height, in points
|
||||
*
|
||||
* @param string $font
|
||||
* @param float $size
|
||||
*
|
||||
* @return float
|
||||
*/
|
||||
function get_font_height($font, $size);
|
||||
|
||||
/**
|
||||
* Calculates font baseline, in points
|
||||
*
|
||||
* @param string $font
|
||||
* @param float $size
|
||||
*
|
||||
* @return float
|
||||
*/
|
||||
function get_font_baseline($font, $size);
|
||||
|
||||
/**
|
||||
* Returns the font x-height, in points
|
||||
*
|
||||
* @param string $font
|
||||
* @param float $size
|
||||
*
|
||||
* @return float
|
||||
*/
|
||||
//function get_font_x_height($font, $size);
|
||||
|
||||
/**
|
||||
* Sets the opacity
|
||||
*
|
||||
* @param float $opacity
|
||||
* @param string $mode
|
||||
*/
|
||||
function set_opacity($opacity, $mode = "Normal");
|
||||
|
||||
/**
|
||||
* Sets the default view
|
||||
*
|
||||
* @param string $view
|
||||
* 'XYZ' left, top, zoom
|
||||
* 'Fit'
|
||||
* 'FitH' top
|
||||
* 'FitV' left
|
||||
* 'FitR' left,bottom,right
|
||||
* 'FitB'
|
||||
* 'FitBH' top
|
||||
* 'FitBV' left
|
||||
* @param array $options
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
function set_default_view($view, $options = array());
|
||||
|
||||
/**
|
||||
* @param string $script
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
function javascript($script);
|
||||
|
||||
/**
|
||||
* Starts a new page
|
||||
*
|
||||
* Subsequent drawing operations will appear on the new page.
|
||||
*/
|
||||
function new_page();
|
||||
|
||||
/**
|
||||
* Streams the PDF directly to the browser
|
||||
*
|
||||
* @param string $filename the name of the PDF file
|
||||
* @param array $options associative array, 'Attachment' => 0 or 1, 'compress' => 1 or 0
|
||||
*/
|
||||
function stream($filename, $options = null);
|
||||
|
||||
/**
|
||||
* Returns the PDF as a string
|
||||
*
|
||||
* @param array $options associative array: 'compress' => 1 or 0
|
||||
* @return string
|
||||
*/
|
||||
function output($options = null);
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user