Compare commits
549 Commits
v6.10.0
...
developmen
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9a28c86991 | ||
|
|
38b2ffe82a | ||
|
|
6e547abccb | ||
|
|
676af5e1a4 | ||
|
|
118aacee28 | ||
|
|
564e23ecd7 | ||
|
|
2889012592 | ||
|
|
cd65604073 | ||
|
|
a3cf5f45f9 | ||
|
|
6f3dacdec0 | ||
|
|
2ab1ee90ef | ||
|
|
b8c0aff975 | ||
|
|
c5fed66237 | ||
|
|
157169d3ba | ||
|
|
60fe0e0def | ||
|
|
e473e7899d | ||
|
|
8af71b70a3 | ||
|
|
7d10b4c5af | ||
|
|
c81b602657 | ||
|
|
59cc5f2060 | ||
|
|
e072aaf4d6 | ||
|
|
259f9cebf3 | ||
|
|
bd4f674f0f | ||
|
|
87293bf633 | ||
|
|
be46d6e101 | ||
|
|
433bc3d539 | ||
|
|
4ed645bac3 | ||
|
|
908376c1a5 | ||
|
|
c329e7a2da | ||
|
|
ad7b59e26a | ||
|
|
c43bb0662d | ||
|
|
c4e83f94e9 | ||
|
|
a292abc2c5 | ||
|
|
6c5af91386 | ||
|
|
73fc74a43a | ||
|
|
b89238b922 | ||
|
|
9115fc9557 | ||
|
|
62d9cda3d0 | ||
|
|
dbc72472f9 | ||
|
|
3be3519e45 | ||
|
|
4707427ff4 | ||
|
|
73ac0b68b6 | ||
|
|
a501fa25de | ||
|
|
d4db235e5b | ||
|
|
c70cdf457f | ||
|
|
57aae073d7 | ||
|
|
4bebec2b47 | ||
|
|
991750aa5f | ||
| 426afdc1ff | |||
| ffff65a76d | |||
|
|
c22e68f19a | ||
|
|
074d5bed4c | ||
|
|
93cb7e0cab | ||
|
|
7fbce6529b | ||
|
|
6e086fe7b3 | ||
|
|
0ec19d5b75 | ||
|
|
8134da349f | ||
|
|
8396f7856b | ||
|
|
b18866077e | ||
|
|
a66cc09095 | ||
|
|
1cfdc45107 | ||
|
|
07e46c91ab | ||
|
|
8aee448c59 | ||
|
|
37367db878 | ||
|
|
2d30d1d160 | ||
|
|
531229e8b7 | ||
|
|
d09c20ff9d | ||
|
|
f4ddc5a5fc | ||
|
|
1791ec3908 | ||
|
|
3d13f55c35 | ||
|
|
cf1989819a | ||
|
|
b302fb4053 | ||
|
|
32decdd037 | ||
|
|
46cda40d37 | ||
|
|
e71df90144 | ||
|
|
bbcc642fde | ||
|
|
558694aa6c | ||
|
|
f3bd09529a | ||
|
|
816bb7c9ee | ||
|
|
fc7b705355 | ||
|
|
7b96c1f9ca | ||
|
|
26c6ebcea7 | ||
|
|
32dee1692e | ||
|
|
6291ed88c0 | ||
|
|
5e21ead6fa | ||
|
|
07fbd13213 | ||
|
|
44b825310a | ||
|
|
2c234ccef6 | ||
|
|
b493b3c4fd | ||
|
|
e7dd96b5d9 | ||
|
|
bcde36ac17 | ||
|
|
8bde34ec7d | ||
|
|
a345d71306 | ||
|
|
0ff6294faa | ||
|
|
757d7ae01d | ||
|
|
4e78b21c67 | ||
|
|
d7e6434808 | ||
|
|
443cc2751d | ||
|
|
cf6500b55a | ||
|
|
09c2ec653f | ||
|
|
fc105f9295 | ||
|
|
053ab69330 | ||
|
|
fd079316f5 | ||
|
|
08664e9834 | ||
|
|
e063162161 | ||
|
|
7fbc449a5c | ||
|
|
72912c8c90 | ||
|
|
de2ed8be3d | ||
|
|
9d65f5d7c1 | ||
|
|
fbe827e989 | ||
|
|
c778a4eb81 | ||
|
|
ce1c72a0bc | ||
|
|
10319ef728 | ||
|
|
8d0036eaac | ||
|
|
d1e65c702e | ||
|
|
7248906da7 | ||
|
|
7f9a4dc04f | ||
|
|
10935214eb | ||
|
|
41e116f7d4 | ||
|
|
881c93c343 | ||
|
|
185d044a0b | ||
|
|
cc067cc202 | ||
|
|
37e2e54b2a | ||
|
|
711b3bfe97 | ||
|
|
3bd21c75d8 | ||
|
|
4971f62490 | ||
|
|
1cf4fdf31a | ||
|
|
d16b920966 | ||
|
|
ab52bf59b5 | ||
|
|
a8dd076aac | ||
|
|
c17ca1f847 | ||
|
|
e349613d60 | ||
|
|
e9cfdb4bf0 | ||
|
|
f966209e0a | ||
|
|
c13934de99 | ||
|
|
1e90bb677e | ||
|
|
540269e61f | ||
|
|
e793c3975b | ||
|
|
7d4c9724fe | ||
|
|
d1c4611431 | ||
|
|
8d3882a6fe | ||
|
|
2b0434e36b | ||
|
|
ba11a936db | ||
|
|
df591659cb | ||
|
|
5343034768 | ||
|
|
dec56c9559 | ||
|
|
880f15ac6f | ||
|
|
a46601fe03 | ||
|
|
022c39e791 | ||
|
|
fdefaca301 | ||
|
|
46e44c19bf | ||
|
|
41cb6358f9 | ||
|
|
23142a4549 | ||
|
|
a7742bd5c8 | ||
|
|
50f83b822c | ||
|
|
78591d6ba4 | ||
|
|
e8299a123b | ||
|
|
10c320f60c | ||
|
|
eeca138192 | ||
|
|
65715ea9c3 | ||
|
|
a56cbd8e97 | ||
|
|
fe50a988a0 | ||
|
|
a84ab86e31 | ||
|
|
b044999772 | ||
|
|
98bf3a40cd | ||
|
|
cbd47fb015 | ||
|
|
5f89917abd | ||
|
|
eeaff3042e | ||
|
|
d070c4e461 | ||
|
|
e57c336dba | ||
|
|
075fe967d5 | ||
|
|
0e5f637052 | ||
|
|
2e1b767a85 | ||
|
|
f78c67c378 | ||
|
|
75e69932fc | ||
|
|
7354632479 | ||
|
|
5a21d22c7b | ||
|
|
cee3b5c2d1 | ||
|
|
47e44c15cc | ||
|
|
83738adcb6 | ||
|
|
5454133239 | ||
|
|
87f35f23c3 | ||
|
|
3c4c5d3106 | ||
|
|
b080727ff3 | ||
|
|
ae044bee6f | ||
|
|
529b6a75ba | ||
|
|
8de112ba7e | ||
|
|
ad070ebdf4 | ||
|
|
9edfc2acb6 | ||
|
|
35cc6dbf91 | ||
|
|
cb3d5e1f27 | ||
|
|
0a45300c21 | ||
|
|
54ce378ae2 | ||
|
|
4ac659f7d9 | ||
|
|
497833ca71 | ||
|
|
e5a9b149b1 | ||
|
|
5213805a58 | ||
|
|
a9f1d878f7 | ||
|
|
3845bc7ff5 | ||
|
|
32c192a362 | ||
|
|
2bd68f32ac | ||
|
|
f5964fed02 | ||
|
|
625272198d | ||
|
|
00821bd5ea | ||
|
|
921b9cb3d9 | ||
|
|
720b78b687 | ||
|
|
565014e1e2 | ||
|
|
d9bcb577d7 | ||
|
|
8613e8977b | ||
|
|
0c51a3be87 | ||
|
|
f9cf36524e | ||
|
|
bacb9881ac | ||
|
|
f0fae1f76d | ||
|
|
1653e6b684 | ||
|
|
c8bc0062ad | ||
|
|
5c8a2ef8da | ||
|
|
d8379a10d9 | ||
|
|
30e2f33620 | ||
|
|
a4f16f4ca9 | ||
|
|
6e7b9cd033 | ||
|
|
4bc2ad8fa0 | ||
|
|
0d4e959f39 | ||
|
|
95d567545a | ||
|
|
d89c6d1bde | ||
|
|
337ebb9032 | ||
|
|
9538ebce7b | ||
|
|
1bff19f4b6 | ||
|
|
66dc72ec67 | ||
|
|
f781b5e55f | ||
|
|
934db50b3a | ||
|
|
573588ad3c | ||
|
|
d04addba81 | ||
|
|
a50a38fd40 | ||
|
|
3c5200cd99 | ||
|
|
50a4b88f55 | ||
|
|
e82929f512 | ||
|
|
5fc55c53b8 | ||
|
|
47da4d02ff | ||
|
|
9d131cf6dd | ||
|
|
dfcae20f64 | ||
|
|
61e489ee4c | ||
|
|
29982f90bc | ||
|
|
7cced63c4b | ||
|
|
06c2ea5e0d | ||
|
|
2e9239ec23 | ||
|
|
545279b9fe | ||
|
|
0c89840dba | ||
|
|
db144493f3 | ||
|
|
5cec54d508 | ||
|
|
8e60c992f1 | ||
|
|
1b5437b675 | ||
|
|
ef80cba561 | ||
|
|
2d71e760e8 | ||
|
|
a8d07634ff | ||
|
|
aa2b60973e | ||
|
|
554dd5f73c | ||
|
|
e6f9559fbb | ||
|
|
770d6f30a4 | ||
|
|
f94f6cbe87 | ||
|
|
9b69390fa2 | ||
|
|
0524d8ac1b | ||
|
|
e933022671 | ||
|
|
c549d34e65 | ||
|
|
f4ff31721b | ||
|
|
21ac91d2e6 | ||
|
|
2d98d26d0b | ||
|
|
3fda1bef60 | ||
|
|
4f1104c36e | ||
|
|
db1007ef12 | ||
|
|
13c76efcef | ||
|
|
f59c325b05 | ||
|
|
aac5157173 | ||
|
|
abc2705c64 | ||
|
|
e2fff45b16 | ||
|
|
b6ae3f99d9 | ||
|
|
a377ab4b61 | ||
|
|
ec9275d8d3 | ||
|
|
10ed5b3ea0 | ||
|
|
5f290419c6 | ||
|
|
0152af6e65 | ||
|
|
4adb9fba30 | ||
|
|
672931ee67 | ||
|
|
373a9aff2f | ||
|
|
4e3ceecac8 | ||
|
|
8bf694b2b2 | ||
|
|
caf03421a7 | ||
|
|
facf8adaf7 | ||
|
|
c8158c8224 | ||
|
|
7b9a0043d3 | ||
|
|
6517747fef | ||
|
|
fb7071adc4 | ||
|
|
d96c92f9ef | ||
|
|
d7c0054ea0 | ||
|
|
80d2215f2b | ||
|
|
b18bf937d3 | ||
|
|
4b6c5df74f | ||
|
|
89e3888bf8 | ||
|
|
c46125aef1 | ||
|
|
a8ca5d7a2b | ||
|
|
ae2d6580a2 | ||
|
|
97e1b2b63d | ||
|
|
d632a2599e | ||
|
|
2f81009a97 | ||
|
|
e9799f888b | ||
|
|
94b24b4eae | ||
|
|
a304d29698 | ||
|
|
c4c809be66 | ||
|
|
a3bf38f6cf | ||
|
|
c1b906e701 | ||
|
|
32f8e1440d | ||
|
|
2f8f98642b | ||
|
|
7ab03913ac | ||
|
|
a7853171e0 | ||
|
|
dfdfcf87f2 | ||
|
|
6218e0a6a8 | ||
|
|
a84a745be2 | ||
|
|
312762e92e | ||
|
|
fa4c1f0597 | ||
|
|
438a75af23 | ||
|
|
afd8ff3e31 | ||
|
|
4343af7937 | ||
|
|
d06769c48b | ||
|
|
4c0390f082 | ||
|
|
95bee3dc8c | ||
|
|
65132d8a4a | ||
|
|
b2243cd06d | ||
|
|
8f09b67d86 | ||
|
|
fe459aec80 | ||
|
|
de0ed058ca | ||
|
|
f90bd193d9 | ||
|
|
0e31180868 | ||
|
|
68c9164eaa | ||
|
|
c2389db1c9 | ||
|
|
f9558cd3aa | ||
|
|
ae3011fe22 | ||
|
|
9b9dfeac69 | ||
|
|
33cb05a002 | ||
|
|
ec110499a8 | ||
|
|
09839f3451 | ||
|
|
067e0aed5d | ||
|
|
545de5c4a1 | ||
|
|
2fe37bf92a | ||
|
|
cd81d15d9a | ||
|
|
8a33ee5c15 | ||
|
|
46e1419ef5 | ||
|
|
c441063437 | ||
|
|
5290d5f351 | ||
|
|
2635ccb82b | ||
|
|
4f2ac2ed1b | ||
|
|
5b8e4e4e3e | ||
|
|
53192da571 | ||
|
|
f29e915068 | ||
|
|
46bc5f2da6 | ||
|
|
d70182a84e | ||
|
|
7243f69826 | ||
|
|
1fc144e178 | ||
|
|
c383a7b7b7 | ||
|
|
69077c384c | ||
|
|
cfd49947ad | ||
|
|
6985dc4e9d | ||
|
|
5f2668b011 | ||
|
|
eba1ef9c59 | ||
|
|
8497144053 | ||
|
|
2006798388 | ||
|
|
bf63d850ca | ||
|
|
53e267ce24 | ||
|
|
1754ecf2ee | ||
|
|
3c37899a48 | ||
|
|
0436cfe3da | ||
|
|
3606de1a00 | ||
|
|
3081439eda | ||
|
|
7af0e74b85 | ||
|
|
7748b83a6b | ||
|
|
f83293ff1a | ||
|
|
9c3be2942e | ||
|
|
ee62bd98ee | ||
|
|
02e9610fad | ||
|
|
8a41db4649 | ||
|
|
e27ea3dc9f | ||
|
|
ec4bf54d81 | ||
|
|
ec3ca787fa | ||
|
|
86acbbb85b | ||
|
|
8e0af7a5f7 | ||
|
|
b022662dfc | ||
|
|
3039ebf913 | ||
|
|
e2e080c404 | ||
|
|
4671143d1c | ||
|
|
b492558cca | ||
|
|
64e76530d4 | ||
|
|
0b93f9f146 | ||
|
|
4c6fe1cd6c | ||
|
|
83ba48f598 | ||
|
|
62c6de8244 | ||
|
|
1c2f9f0c2c | ||
|
|
30bb0e8895 | ||
|
|
75c4c98de8 | ||
|
|
f72055909b | ||
|
|
b0a8783276 | ||
|
|
7b5ad92e66 | ||
|
|
250067927a | ||
|
|
7c2cbbaca7 | ||
|
|
ac037eabde | ||
|
|
0250b86b3f | ||
|
|
e45acc412b | ||
|
|
854206bc70 | ||
|
|
b192e98a8a | ||
|
|
c4e2c781c6 | ||
|
|
e80b3b8dfd | ||
|
|
2b079ff836 | ||
|
|
37201799b5 | ||
|
|
b9d8911c7b | ||
|
|
c51ceb926e | ||
|
|
b4b33d6873 | ||
|
|
959240b0fa | ||
|
|
7eace1013e | ||
|
|
be1e55cad7 | ||
|
|
11a8c6440b | ||
|
|
742cbc31df | ||
|
|
28909fdc03 | ||
|
|
c3b29ad0d7 | ||
|
|
6d481657df | ||
|
|
fc57aabf5d | ||
|
|
d56ee68482 | ||
|
|
b89ab09e12 | ||
|
|
e873ade6c0 | ||
|
|
5910b884ac | ||
|
|
e3bd2c1c3b | ||
|
|
90a8c5540f | ||
|
|
ea503fffe9 | ||
|
|
feba79a2e8 | ||
|
|
6bec59e387 | ||
|
|
03fbcaecfb | ||
|
|
283e7de1dc | ||
|
|
d952c5f774 | ||
|
|
cd8351d761 | ||
|
|
b992901072 | ||
|
|
1596654149 | ||
|
|
44f37b7f74 | ||
|
|
829f5c567f | ||
|
|
710a48abcd | ||
|
|
f564c27319 | ||
|
|
00b98e7230 | ||
|
|
7cae3e701a | ||
|
|
da67d1bde3 | ||
|
|
16c3653cee | ||
|
|
47c4c5cb69 | ||
|
|
7b9dc9c8b2 | ||
|
|
6133da9069 | ||
|
|
fa0b102d1a | ||
|
|
0e99700bbe | ||
|
|
2f0b9fb360 | ||
|
|
c7cc3c2938 | ||
|
|
f508b607a6 | ||
|
|
f94b350ba4 | ||
|
|
53eef03387 | ||
|
|
5a81445a28 | ||
|
|
4bbbd653cd | ||
|
|
4c28e6d0ec | ||
|
|
66b7e81463 | ||
|
|
cf58f86802 | ||
|
|
ff644310cd | ||
|
|
58988b9c0f | ||
|
|
fe75f1d724 | ||
|
|
0607cdc3be | ||
|
|
6cb14daf49 | ||
|
|
330582f273 | ||
|
|
b0293b52bd | ||
|
|
00591deb00 | ||
|
|
737f70fac5 | ||
|
|
0328ccd2fe | ||
|
|
eba1e2885f | ||
|
|
53813261fb | ||
|
|
df2ae66942 | ||
|
|
78e1d73cd9 | ||
|
|
620a5878c1 | ||
|
|
5a0b09a916 | ||
|
|
98c6033c75 | ||
|
|
6dcebc9b67 | ||
|
|
c97520e186 | ||
|
|
764ca1f098 | ||
|
|
3d23e5b066 | ||
|
|
90e418ba24 | ||
|
|
b6a0937e0c | ||
|
|
b3f6f8ef18 | ||
|
|
d9d5400498 | ||
|
|
b1be681afb | ||
|
|
8ef309d479 | ||
|
|
6e59b63791 | ||
|
|
9c7b3cea83 | ||
|
|
26af6a07f4 | ||
|
|
b7c6d4b478 | ||
|
|
9936fc04da | ||
|
|
1e0dfa2106 | ||
|
|
3af6f6a8f0 | ||
|
|
1e793c0d16 | ||
|
|
5be34453ce | ||
|
|
7773b78e17 | ||
|
|
2a3798c8c2 | ||
|
|
bc8303fe5f | ||
|
|
ba89b188d9 | ||
|
|
d15618cde4 | ||
|
|
0fd89727e9 | ||
|
|
a8e75d158b | ||
|
|
4b3fbaa309 | ||
|
|
1a6c65df0e | ||
|
|
24f553a17e | ||
|
|
9a3ea2f7db | ||
|
|
bcdb877d90 | ||
|
|
6d0e528c38 | ||
|
|
7e6474195b | ||
|
|
1795d3ba6c | ||
|
|
e1340acf55 | ||
|
|
b5ead3e266 | ||
|
|
f5daaca598 | ||
|
|
6b4f310cd2 | ||
|
|
7b5bddb529 | ||
|
|
0a6fdf1248 | ||
|
|
3220180d58 | ||
|
|
8c8f14ec74 | ||
|
|
643991c3fd | ||
|
|
c81c46d426 | ||
|
|
d97b173ee7 | ||
|
|
b61152f10e | ||
|
|
0c68ebe652 | ||
|
|
31d0cdb8ad | ||
|
|
0f823bd283 | ||
|
|
6385a48824 | ||
|
|
a754d897cf | ||
|
|
4600f8f7bf | ||
|
|
04e4fe46f2 | ||
|
|
c35d3c9324 | ||
|
|
e92a682a8c | ||
|
|
ea07e4b95b | ||
|
|
88178cb08d | ||
|
|
5d98be06be | ||
|
|
183cadb0fd | ||
|
|
2067a6fe1d | ||
|
|
f5b6c639fb | ||
|
|
cde29c0362 | ||
|
|
10234000b7 | ||
|
|
a63a50a412 | ||
|
|
59da10b649 | ||
|
|
b714de498f | ||
|
|
aa11937ab2 | ||
|
|
d64d5f081c | ||
|
|
3085b52714 | ||
|
|
9949a5ef7f | ||
|
|
74ba935e96 | ||
|
|
39a62ed59d |
10
.gitignore
vendored
10
.gitignore
vendored
@@ -0,0 +1,10 @@
|
|||||||
|
.libs
|
||||||
|
node_modules/
|
||||||
|
composer.lock
|
||||||
|
vendor/
|
||||||
|
tools/
|
||||||
|
www/composer.lock
|
||||||
|
www/vendor
|
||||||
|
**/.env
|
||||||
|
**/.target
|
||||||
|
package-lock.json
|
||||||
|
|||||||
@@ -26,6 +26,8 @@
|
|||||||
use Phan\Config;
|
use Phan\Config;
|
||||||
|
|
||||||
return [
|
return [
|
||||||
|
// "target_php_version" => "8.3",
|
||||||
|
"minimum_target_php_version" => "8.3",
|
||||||
// turn color on (-C)
|
// turn color on (-C)
|
||||||
"color_issue_messages_if_supported" => true,
|
"color_issue_messages_if_supported" => true,
|
||||||
// If true, missing properties will be created when
|
// If true, missing properties will be created when
|
||||||
@@ -94,8 +96,6 @@ return [
|
|||||||
"exclude_analysis_directory_list" => [
|
"exclude_analysis_directory_list" => [
|
||||||
'www/vendor',
|
'www/vendor',
|
||||||
'www/tests',
|
'www/tests',
|
||||||
'www/lib/Smarty',
|
|
||||||
'www/lib/smarty-4.1.0',
|
|
||||||
'www/templates_c',
|
'www/templates_c',
|
||||||
'www/log',
|
'www/log',
|
||||||
'www/tmp',
|
'www/tmp',
|
||||||
@@ -116,8 +116,6 @@ return [
|
|||||||
// ignore the old qq tests
|
// ignore the old qq tests
|
||||||
'www/admin/qq_file_upload_front.php',
|
'www/admin/qq_file_upload_front.php',
|
||||||
'www/admin/qq_file_upload_ajax.php',
|
'www/admin/qq_file_upload_ajax.php',
|
||||||
// symlink ignore
|
|
||||||
'www/lib/smarty-4.1.0/libs/Smarty.class.php'
|
|
||||||
],
|
],
|
||||||
|
|
||||||
// what not to show as problem
|
// what not to show as problem
|
||||||
@@ -130,7 +128,12 @@ return [
|
|||||||
'PhanWriteOnlyPublicProperty',
|
'PhanWriteOnlyPublicProperty',
|
||||||
'PhanUnreferencedConstant',
|
'PhanUnreferencedConstant',
|
||||||
'PhanWriteOnlyPublicProperty',
|
'PhanWriteOnlyPublicProperty',
|
||||||
'PhanReadOnlyPublicProperty'
|
'PhanReadOnlyPublicProperty',
|
||||||
|
// start ignore annotations
|
||||||
|
'PhanUnextractableAnnotationElementName',
|
||||||
|
'PhanUnextractableAnnotationSuffix',
|
||||||
|
// enum problems in comments
|
||||||
|
'PhanCommentObjectInClassConstantType'
|
||||||
],
|
],
|
||||||
|
|
||||||
// Override to hardcode existence and types of (non-builtin) globals in the global scope.
|
// Override to hardcode existence and types of (non-builtin) globals in the global scope.
|
||||||
|
|||||||
12
.phive/phars.xml
Normal file
12
.phive/phars.xml
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<phive xmlns="https://phar.io/phive">
|
||||||
|
<phar name="phpunit" version="~9.6" installed="9.6.31" location="./tools/phpunit" copy="false"/>
|
||||||
|
<phar name="phpcbf" version="4" installed="4.0.1" location="./tools/phpcbf" copy="false"/>
|
||||||
|
<phar name="phpcs" version="4" installed="4.0.1" location="./tools/phpcs" copy="false"/>
|
||||||
|
<phar name="phpstan" version="^2.0" installed="2.1.33" location="./tools/phpstan" copy="false"/>
|
||||||
|
<phar name="phan" version="^5.4.3" installed="5.5.2" location="./tools/phan" copy="false"/>
|
||||||
|
<phar name="psalm" version="^5.26.1" installed="5.26.1" location="./tools/psalm" copy="false"/>
|
||||||
|
<phar name="phpdox" version="^0.12.0" installed="0.12.0" location="./tools/phpdox" copy="false"/>
|
||||||
|
<phar name="phpdocumentor" version="^3.4.2" installed="3.9.1" location="./tools/phpDocumentor" copy="false"/>
|
||||||
|
<phar name="php-cs-fixer" version="^3.34.1" installed="3.92.4" location="./tools/php-cs-fixer" copy="false"/>
|
||||||
|
</phive>
|
||||||
2
.shellcheckrc
Normal file
2
.shellcheckrc
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
shell=bash
|
||||||
|
external-sources=true
|
||||||
@@ -1,17 +1,20 @@
|
|||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
base_folder='/var/www/html/developers/clemens/core_data/php_libraries/trunk/www/';
|
BASE_FOLDER=$(dirname "$(readlink -f "$0")")"/";
|
||||||
|
# Assume script is in 4dev/bin
|
||||||
|
base_folder="${BASE_FOLDER}../../www/";
|
||||||
|
|
||||||
# locale gettext po to mo translator master
|
# locale gettext po to mo translator master
|
||||||
for file in $(ls -1 ${base_folder}../4dev/locale/*.po); do
|
for file in "${base_folder}"../4dev/locale/*.po; do
|
||||||
file=$(basename $file .po);
|
[[ -e "$file" ]] || break
|
||||||
echo "Translate language ${file}";
|
file=$(basename "$file" .po);
|
||||||
locale=$(echo "${file}" | cut -d "-" -f 1);
|
locale=$(echo "${file}" | cut -d "-" -f 1);
|
||||||
domain=$(echo "${file}" | cut -d "-" -f 2);
|
domain=$(echo "${file}" | cut -d "-" -f 2);
|
||||||
|
echo "- Translate language file '${file}' for locale '${locale}' and domain '${domain}':";
|
||||||
if [ ! -d "${base_folder}/includes/locale/${locale}/LC_MESSAGES/" ]; then
|
if [ ! -d "${base_folder}/includes/locale/${locale}/LC_MESSAGES/" ]; then
|
||||||
mkdir -p "${base_folder}/includes/locale/${locale}/LC_MESSAGES/";
|
mkdir -p "${base_folder}/includes/locale/${locale}/LC_MESSAGES/";
|
||||||
fi;
|
fi;
|
||||||
msgfmt -o ${base_folder}/includes/locale/${locale}/LC_MESSAGES/${domain}.mo ${base_folder}../4dev/locale/${locale}-${domain}.po;
|
msgfmt -o "${base_folder}/includes/locale/${locale}/LC_MESSAGES/${domain}.mo" "${base_folder}../4dev/locale/${locale}-${domain}.po";
|
||||||
done;
|
done;
|
||||||
|
|
||||||
# __END__
|
# __END__
|
||||||
|
|||||||
176
4dev/bin/mo_to_js.sh
Executable file
176
4dev/bin/mo_to_js.sh
Executable file
@@ -0,0 +1,176 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# read source mo files and writes target js files in object form
|
||||||
|
|
||||||
|
# check for ARG 1 is "no-move"
|
||||||
|
# then do not move the files directly for manual check
|
||||||
|
FILE_MOVE=1;
|
||||||
|
if [ "${1}" = "no-move" ]; then
|
||||||
|
echo "+++ CREATE TEMPORARY FILES +++";
|
||||||
|
FILE_MOVE=0;
|
||||||
|
else
|
||||||
|
echo "*** Direct write ***";
|
||||||
|
fi;
|
||||||
|
|
||||||
|
target='';
|
||||||
|
BASE_FOLDER=$(dirname "$(readlink -f "$0")")"/";
|
||||||
|
# Assume script is in 4dev/bin
|
||||||
|
base_folder="${BASE_FOLDER}../../www/";
|
||||||
|
po_folder='../4dev/locale/'
|
||||||
|
mo_folder='includes/locale/';
|
||||||
|
target_folder='';
|
||||||
|
template_file_stump='##SUFFIX##translate-##LANGUAGE##.TMP.js';
|
||||||
|
# for output file names
|
||||||
|
source_list=(iw);
|
||||||
|
language_list=(en ja);
|
||||||
|
# set target names
|
||||||
|
if [ "${target}" == '' ]; then
|
||||||
|
echo "*** Non smarty ***";
|
||||||
|
TEXTDOMAINDIR=${base_folder}${mo_folder}.
|
||||||
|
# default is admin
|
||||||
|
TEXTDOMAIN="admin";
|
||||||
|
fi;
|
||||||
|
js_folder="${TEXTDOMAIN}/layout/javascript/";
|
||||||
|
|
||||||
|
error=0;
|
||||||
|
# this checks if the TEXTDOMAIN target actually exists
|
||||||
|
if [ ! -d "${base_folder}${js_folder}" ]; then
|
||||||
|
echo "Cannot find target javascript folder ${base_folder}${js_folder}";
|
||||||
|
error=1;
|
||||||
|
else
|
||||||
|
target_folder="${base_folder}${js_folder}";
|
||||||
|
fi;
|
||||||
|
|
||||||
|
if [ ${error} -eq 1 ]; then
|
||||||
|
exit;
|
||||||
|
fi;
|
||||||
|
|
||||||
|
# locale gettext po to mo translator master
|
||||||
|
for file in "${base_folder}"../4dev/locale/*.po; do
|
||||||
|
[[ -e "$file" ]] || break
|
||||||
|
file=$(basename "$file" .po);
|
||||||
|
locale=$(echo "${file}" | cut -d "-" -f 1);
|
||||||
|
domain=$(echo "${file}" | cut -d "-" -f 2);
|
||||||
|
echo "- Translate language file '${file}' for locale '${locale}' and domain '${domain}':";
|
||||||
|
if [ ! -d "${base_folder}/includes/locale/${locale}/LC_MESSAGES/" ]; then
|
||||||
|
mkdir -p "${base_folder}/includes/locale/${locale}/LC_MESSAGES/";
|
||||||
|
fi;
|
||||||
|
msgfmt -o "${base_folder}/includes/locale/${locale}/LC_MESSAGES/${domain}.mo" "${base_folder}${po_folder}${locale}-${domain}.po";
|
||||||
|
done;
|
||||||
|
|
||||||
|
rx_msgid_empty="^msgid \"\"";
|
||||||
|
rx_msgid="^msgid \"";
|
||||||
|
rx_msgstr="^msgstr \""
|
||||||
|
|
||||||
|
# quick copy string at the end
|
||||||
|
quick_copy='';
|
||||||
|
|
||||||
|
for language in "${language_list[@]}"; do
|
||||||
|
# I don't know which one must be set, but I think at least LANGUAGE
|
||||||
|
case ${language} in
|
||||||
|
ja)
|
||||||
|
LANG=ja_JP.UTF-8;
|
||||||
|
ENCODING=UTF-8;
|
||||||
|
LANGUAGE=ja;
|
||||||
|
;;
|
||||||
|
en)
|
||||||
|
# was en_JP.UTF-8
|
||||||
|
LANG=en_US.UTF-8;
|
||||||
|
ENCODING=UTF-8;
|
||||||
|
LANGUAGE=en;
|
||||||
|
;;
|
||||||
|
esac;
|
||||||
|
# write only one for language and then symlink files
|
||||||
|
template_file=$(echo ${template_file_stump} | sed -e "s/##SUFFIX##//" | sed -e "s/##LANGUAGE##/${LANG}/");
|
||||||
|
# original_file=$(echo ${template_file} | sed -e 's/\.TMP//g');
|
||||||
|
original_file=${template_file//.TMP/};
|
||||||
|
if [ "${FILE_MOVE}" -eq 0 ]; then
|
||||||
|
file=${target_folder}${template_file};
|
||||||
|
else
|
||||||
|
file=${target_folder}${original_file};
|
||||||
|
fi;
|
||||||
|
echo "===> Write translation file ${file}";
|
||||||
|
echo ". = normal, : = escape, x = skip";
|
||||||
|
# init line [aka don't touch this file]
|
||||||
|
echo "// AUTO FILL, changes will be overwritten" > "$file";
|
||||||
|
{
|
||||||
|
echo "// source: ${suffix}, language: ${language}";
|
||||||
|
echo "// Translation strings in the format";
|
||||||
|
echo "// \"Original\":\"Translated\""$'\n'
|
||||||
|
echo "var i18n = {"
|
||||||
|
} >> "$file"
|
||||||
|
# translations stuff
|
||||||
|
# read the po file
|
||||||
|
pos=0; # do we add a , for the next line
|
||||||
|
cat "${base_folder}${po_folder}${language}-${TEXTDOMAIN}.po" |
|
||||||
|
while read -r str; do
|
||||||
|
# echo "S: ${str}";
|
||||||
|
# skip empty
|
||||||
|
if [[ "${str}" =~ ${rx_msgid_empty} ]]; then
|
||||||
|
# skip on empty
|
||||||
|
echo -n "x";
|
||||||
|
# msgid is left, msgstr is right
|
||||||
|
elif [[ "${str}" =~ ${rx_msgid} ]]; then
|
||||||
|
echo -n ".";
|
||||||
|
# open left side
|
||||||
|
# TODO: how to handle multi line strings: or don't use them
|
||||||
|
# extract from between ""
|
||||||
|
str_source=$(echo "${str}" | sed -e "s/^msgid \"//" | sed -e "s/\"$//");
|
||||||
|
# close right side, if not last add ,
|
||||||
|
if [ "${pos}" -eq 1 ]; then
|
||||||
|
echo -n "," >> "$file";
|
||||||
|
fi;
|
||||||
|
# all " inside string need to be escaped
|
||||||
|
# str_source=$(echo "${str_source}" | sed -e 's/"/\\"/g');
|
||||||
|
str_source=${str_source//\"/\\\"}
|
||||||
|
# fix with proper layout
|
||||||
|
echo -n "\"$str_source\":\"$(TEXTDOMAINDIR=${TEXTDOMAINDIR} LANGUAGE=${language} LANG=${LANG} gettext "${TEXTDOMAIN}" "${str_source}")\"" >> "$file";
|
||||||
|
pos=1;
|
||||||
|
elif [[ "${str}" =~ ${rx_msgstr} ]]; then
|
||||||
|
# open right side (ignore)
|
||||||
|
echo -n "";
|
||||||
|
else
|
||||||
|
# general ignore (anything between or comments)
|
||||||
|
echo -n "";
|
||||||
|
fi;
|
||||||
|
done;
|
||||||
|
|
||||||
|
echo "" >> "$file";
|
||||||
|
echo "};" >> "$file";
|
||||||
|
echo " [DONE]";
|
||||||
|
|
||||||
|
# on no move
|
||||||
|
if [ "${FILE_MOVE}" -eq 0 ]; then
|
||||||
|
echo "===> Confirm all changes in ${file} and then move data to original";
|
||||||
|
echo "";
|
||||||
|
quick_copy=${quick_copy}"mv ${template_file} ${original_file}"$'\n';
|
||||||
|
fi;
|
||||||
|
|
||||||
|
# symlink to master file
|
||||||
|
for suffix in "${source_list[@]}"; do
|
||||||
|
# symlink with full lang name
|
||||||
|
symlink_file[0]=$(echo ${template_file_stump} | sed -e "s/##SUFFIX##/${suffix}_/" | sed -e "s/##LANGUAGE##/${LANG}/" | sed -e 's/\.TMP//g');
|
||||||
|
# create second one with lang (no country) + encoding
|
||||||
|
symlink_file[1]=$(echo ${template_file_stump} | sed -e "s/##SUFFIX##/${suffix}_/" | sed -e "s/##LANGUAGE##/${LANGUAGE}\.${ENCODING}/" | sed -e 's/\.TMP//g');
|
||||||
|
for template_file in "${symlink_file[@]}"; do
|
||||||
|
# if this is not symlink, create them
|
||||||
|
if [ ! -h "${template_file}" ]; then
|
||||||
|
echo "Create symlink: ${template_file}";
|
||||||
|
# symlik to original
|
||||||
|
cd "${target_folder}" || exit;
|
||||||
|
ln -sf "${original_file}" "${template_file}";
|
||||||
|
cd - >/dev/null || exit;
|
||||||
|
fi;
|
||||||
|
done;
|
||||||
|
done;
|
||||||
|
done;
|
||||||
|
|
||||||
|
if [ "${FILE_MOVE}" -eq 0 ]; then
|
||||||
|
echo "";
|
||||||
|
echo "-- IN FOLDER: ${target_folder}";
|
||||||
|
echo "-- START: copy lines below to copy created over original --";
|
||||||
|
echo "${quick_copy}";
|
||||||
|
echo "-- END ----------------------------------------------------";
|
||||||
|
fi;
|
||||||
|
|
||||||
|
# __END__
|
||||||
@@ -1,3 +1,100 @@
|
|||||||
base="/storage/var/www/html/developers/clemens/core_data/php_libraries/trunk/";
|
#!/bin/env bash
|
||||||
# must be run in ${base}www/
|
|
||||||
phan --progress-bar -C --analyze-twice
|
function error() {
|
||||||
|
if [ -t 1 ]; then echo "[MAK] ERROR: $*" >&2; fi; exit 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
usage() {
|
||||||
|
cat <<EOF
|
||||||
|
Usage: $(basename "${BASH_SOURCE[0]}") [-h | --help] [-p | --php VERSION] [-c | --composer]
|
||||||
|
|
||||||
|
Runs phan static analyzer.
|
||||||
|
|
||||||
|
If -p is not set, the default intalled PHP is used.
|
||||||
|
|
||||||
|
Available options:
|
||||||
|
|
||||||
|
-h, --help Print this help and exit
|
||||||
|
-p, --php VERSION Chose PHP version in the form of "N.N", if not found will exit
|
||||||
|
-c, --composer Use composer version and not the default phives bundle
|
||||||
|
EOF
|
||||||
|
exit
|
||||||
|
}
|
||||||
|
|
||||||
|
BASE_PATH=$(pwd)"/";
|
||||||
|
PHP_BIN_PATH=$(which php);
|
||||||
|
if [ -z "${PHP_BIN_PATH}" ]; then
|
||||||
|
echo "Cannot find php binary";
|
||||||
|
exit;
|
||||||
|
fi;
|
||||||
|
DEFAULT_PHP_VERSION=$(${PHP_BIN_PATH} -r "echo PHP_MAJOR_VERSION.'.'.PHP_MINOR_VERSION;");
|
||||||
|
if [ -z "${DEFAULT_PHP_VERSION}" ]; then
|
||||||
|
echo "Cannot set default PHP version";
|
||||||
|
exit;
|
||||||
|
fi;
|
||||||
|
php_version="";
|
||||||
|
no_php_version=0;
|
||||||
|
use_composer=0;
|
||||||
|
while [ -n "${1-}" ]; do
|
||||||
|
case "${1}" in
|
||||||
|
-p | --php)
|
||||||
|
php_version="${2-}";
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
-c | --composer)
|
||||||
|
use_composer=1;
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
-h | --help)
|
||||||
|
usage
|
||||||
|
;;
|
||||||
|
# invalid option
|
||||||
|
-?*)
|
||||||
|
error "[!] Unknown option: '$1'."
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
shift;
|
||||||
|
done;
|
||||||
|
if [ -z "${php_version}" ]; then
|
||||||
|
php_version="${DEFAULT_PHP_VERSION}";
|
||||||
|
no_php_version=1;
|
||||||
|
fi;
|
||||||
|
php_bin="${PHP_BIN_PATH}${php_version}";
|
||||||
|
echo "Use PHP Version: ${php_version}";
|
||||||
|
if [ "${use_composer}" -eq 1 ]; then
|
||||||
|
echo "Use composer installed";
|
||||||
|
else
|
||||||
|
echo "Use phive installed";
|
||||||
|
fi;
|
||||||
|
|
||||||
|
if [ ! -f "${php_bin}" ]; then
|
||||||
|
echo "Set php ${php_bin} does not exist";
|
||||||
|
exit;
|
||||||
|
fi;
|
||||||
|
|
||||||
|
# must be run in ${base}
|
||||||
|
cd "$BASE_PATH" || exit;
|
||||||
|
export PHAN_DISABLE_XDEBUG_WARN=1;
|
||||||
|
PHAN_CALL=(
|
||||||
|
"${php_bin}"
|
||||||
|
);
|
||||||
|
if [ "${use_composer}" -eq 1 ]; then
|
||||||
|
PHAN_CALL+=("${BASE_PATH}vendor/bin/phan");
|
||||||
|
else
|
||||||
|
PHAN_CALL+=("${BASE_PATH}tools/phan");
|
||||||
|
fi;
|
||||||
|
PHAN_CALL+=(
|
||||||
|
"--progress-bar"
|
||||||
|
"-C"
|
||||||
|
"--analyze-twice"
|
||||||
|
)
|
||||||
|
"${PHAN_CALL[@]}";
|
||||||
|
if [ "${no_php_version}" -eq 0 ]; then
|
||||||
|
echo "*** CALLED WITH PHP ${php_bin} ***";
|
||||||
|
${php_bin} --version;
|
||||||
|
else
|
||||||
|
echo "Default PHP used: $(php --version)";
|
||||||
|
fi;
|
||||||
|
cd ~ || exit;
|
||||||
|
|
||||||
|
# __END__
|
||||||
|
|||||||
@@ -1,3 +1,92 @@
|
|||||||
base="/storage/var/www/html/developers/clemens/core_data/php_libraries/trunk/";
|
#!/bin/env bash
|
||||||
# must be run in ${base}www/
|
|
||||||
phpstan
|
function error() {
|
||||||
|
if [ -t 1 ]; then echo "[MAK] ERROR: $*" >&2; fi; exit 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
usage() {
|
||||||
|
cat <<EOF
|
||||||
|
Usage: $(basename "${BASH_SOURCE[0]}") [-h] [-h | --help] [-p | --php VERSION] [-c | --composer]
|
||||||
|
|
||||||
|
Runs phan static analyzer.
|
||||||
|
|
||||||
|
If -p is not set, the default intalled PHP is used.
|
||||||
|
|
||||||
|
Available options:
|
||||||
|
|
||||||
|
-h, --help Print this help and exit
|
||||||
|
-p, --php VERSION Chose PHP version in the form of "N.N", if not found will exit
|
||||||
|
-c, --composer Use composer version and not the default phives bundle
|
||||||
|
EOF
|
||||||
|
exit
|
||||||
|
}
|
||||||
|
|
||||||
|
BASE_PATH=$(pwd)"/";
|
||||||
|
PHP_BIN_PATH=$(which php);
|
||||||
|
if [ -z "${PHP_BIN_PATH}" ]; then
|
||||||
|
echo "Cannot find php binary";
|
||||||
|
exit;
|
||||||
|
fi;
|
||||||
|
DEFAULT_PHP_VERSION=$(${PHP_BIN_PATH} -r "echo PHP_MAJOR_VERSION.'.'.PHP_MINOR_VERSION;");
|
||||||
|
if [ -z "${DEFAULT_PHP_VERSION}" ]; then
|
||||||
|
echo "Cannot set default PHP version";
|
||||||
|
exit;
|
||||||
|
fi;
|
||||||
|
php_version="";
|
||||||
|
no_php_version=0;
|
||||||
|
use_composer=0;
|
||||||
|
while [ -n "${1-}" ]; do
|
||||||
|
case "${1}" in
|
||||||
|
-p | --php)
|
||||||
|
php_version="${2-}";
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
-c | --composer)
|
||||||
|
use_composer=1;
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
-h | --help)
|
||||||
|
usage
|
||||||
|
;;
|
||||||
|
# invalid option
|
||||||
|
-?*)
|
||||||
|
error "[!] Unknown option: '$1'."
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
shift;
|
||||||
|
done;
|
||||||
|
if [ -z "${php_version}" ]; then
|
||||||
|
php_version="${DEFAULT_PHP_VERSION}";
|
||||||
|
no_php_version=1;
|
||||||
|
fi;
|
||||||
|
php_bin="${PHP_BIN_PATH}${php_version}";
|
||||||
|
echo "Use PHP Version: ${php_version}";
|
||||||
|
if [ "${use_composer}" -eq 1 ]; then
|
||||||
|
echo "Use composer installed";
|
||||||
|
else
|
||||||
|
echo "Use phive installed";
|
||||||
|
fi;
|
||||||
|
|
||||||
|
if [ ! -f "${php_bin}" ]; then
|
||||||
|
echo "Set php ${php_bin} does not exist";
|
||||||
|
exit;
|
||||||
|
fi;
|
||||||
|
|
||||||
|
BASE_PATH=$(pwd)"/";
|
||||||
|
cd "$BASE_PATH" || exit;
|
||||||
|
PHPSTAN_CALL=(
|
||||||
|
"${php_bin}"
|
||||||
|
);
|
||||||
|
if [ "${use_composer}" -eq 1 ]; then
|
||||||
|
PHPSTAN_CALL+=("${BASE_PATH}vendor/bin/phpstan");
|
||||||
|
else
|
||||||
|
PHPSTAN_CALL+=("${BASE_PATH}tools/phpstan");
|
||||||
|
fi;
|
||||||
|
"${PHPSTAN_CALL[@]}";
|
||||||
|
if [ "${no_php_version}" -eq 0 ]; then
|
||||||
|
echo "*** CALLED WITH PHP ${php_bin} ***";
|
||||||
|
${php_bin} --version;
|
||||||
|
else
|
||||||
|
echo "Default PHP used: $(php --version)";
|
||||||
|
fi;
|
||||||
|
cd ~ || exit;
|
||||||
|
|||||||
@@ -1,42 +1,119 @@
|
|||||||
base="/storage/var/www/html/developers/clemens/core_data/php_libraries/trunk/";
|
#!/bin/env bash
|
||||||
|
|
||||||
|
function error() {
|
||||||
|
if [ -t 1 ]; then echo "[MAK] ERROR: $*" >&2; fi; exit 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
usage() {
|
||||||
|
cat <<EOF
|
||||||
|
Usage: $(basename "${BASH_SOURCE[0]}") [-h | --help] [-p | --php VERSION] [-c | --composer] [-t | --testdox] [-v | --verbose]
|
||||||
|
|
||||||
|
Runs all the PHP unit tests.
|
||||||
|
|
||||||
|
If -p is not set, the default intalled PHP is used.
|
||||||
|
|
||||||
|
Available options:
|
||||||
|
|
||||||
|
-h, --help Print this help and exit
|
||||||
|
-t, --testdox Enable testdox output for PHPunit
|
||||||
|
-v, --verbose Enable verbose output for PHPunit
|
||||||
|
-c, --composer Use composer version and not the default phives bundle
|
||||||
|
-p, --php VERSION Chose PHP version in the form of "N.N", if not found will exit
|
||||||
|
EOF
|
||||||
|
exit
|
||||||
|
}
|
||||||
|
|
||||||
|
# set base variables
|
||||||
|
BASE_PATH=$(pwd)"/";
|
||||||
|
PHPUNIT_CONFIG="${BASE_PATH}phpunit.xml";
|
||||||
|
PHP_BIN_PATH=$(which php);
|
||||||
|
if [ -z "${PHP_BIN_PATH}" ]; then
|
||||||
|
echo "Cannot find php binary";
|
||||||
|
exit;
|
||||||
|
fi;
|
||||||
|
DEFAULT_PHP_VERSION=$(${PHP_BIN_PATH} -r "echo PHP_MAJOR_VERSION.'.'.PHP_MINOR_VERSION;");
|
||||||
|
if [ -z "${DEFAULT_PHP_VERSION}" ]; then
|
||||||
|
echo "Cannot set default PHP version";
|
||||||
|
exit;
|
||||||
|
fi;
|
||||||
# -c phpunit.xml
|
# -c phpunit.xml
|
||||||
# --testdox
|
# --testdox
|
||||||
# call with "t" to give verbose testdox output
|
# call with "-tt" to give verbose testdox output
|
||||||
# SUPPORTED: https://www.php.net/supported-versions.php
|
# SUPPORTED: https://www.php.net/supported-versions.php
|
||||||
# call with 7.3, 7.4, 8.0, 8.1 to force a certain php version
|
# call with -p <php version number> to force a certain php version
|
||||||
|
|
||||||
opt_testdox="";
|
opt_testdox="";
|
||||||
if [ "${1}" = "t" ] || [ "${2}" = "t" ]; then
|
opt_verbose="";
|
||||||
opt_testdox="--testdox";
|
php_version="";
|
||||||
fi;
|
no_php_version=0;
|
||||||
php_bin="";
|
use_composer=0;
|
||||||
if [ ! -z "${1}" ]; then
|
while [ -n "${1-}" ]; do
|
||||||
case "${1}" in
|
case "${1}" in
|
||||||
# "7.3") php_bin="/usr/bin/php7.3 "; ;;
|
-t | --testdox)
|
||||||
"7.4") php_bin="/usr/bin/php7.4 "; ;;
|
opt_testdox="--testdox";
|
||||||
"8.0") php_bin="/usr/bin/php8.0 "; ;;
|
;;
|
||||||
"8.1") php_bin="/usr/bin/php8.1 "; ;;
|
-v | --verbose)
|
||||||
*) echo "Not support PHP: ${1}"; exit; ;;
|
opt_verbose="--verbose";
|
||||||
esac;
|
;;
|
||||||
|
-c | --composer)
|
||||||
|
use_composer=1;
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
-p | --php)
|
||||||
|
php_version="${2-}";
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
-h | --help)
|
||||||
|
usage
|
||||||
|
;;
|
||||||
|
# invalid option
|
||||||
|
-?*)
|
||||||
|
error "[!] Unknown option: '$1'."
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
shift;
|
||||||
|
done;
|
||||||
|
|
||||||
|
if [ -z "${php_version}" ]; then
|
||||||
|
php_version="${DEFAULT_PHP_VERSION}";
|
||||||
|
no_php_version=1;
|
||||||
fi;
|
fi;
|
||||||
if [ ! -z "${2}" ] && [ -z "${php_bin}" ]; then
|
php_bin="${PHP_BIN_PATH}${php_version}";
|
||||||
case "${2}" in
|
echo "Use PHP Version: ${php_version}";
|
||||||
# "7.3") php_bin="/usr/bin/php7.3 "; ;;
|
if [ "${use_composer}" -eq 1 ]; then
|
||||||
"7.4") php_bin="/usr/bin/php7.4 "; ;;
|
echo "Use composer installed";
|
||||||
"8.0") php_bin="/usr/bin/php8.0 "; ;;
|
|
||||||
"8.1") php_bin="/usr/bin/php8.1 "; ;;
|
|
||||||
*) echo "Not support PHP: ${1}"; exit; ;;
|
|
||||||
esac;
|
|
||||||
fi;
|
|
||||||
|
|
||||||
phpunit_call="${php_bin}${base}www/vendor/bin/phpunit ${opt_testdox} -c ${base}phpunit.xml ${base}4dev/tests/";
|
|
||||||
|
|
||||||
${phpunit_call};
|
|
||||||
|
|
||||||
if [ ! -z "${php_bin}" ]; then
|
|
||||||
echo "CALLED WITH PHP: ${php_bin}"$(${php_bin} --version);
|
|
||||||
else
|
else
|
||||||
echo "Default PHP used: "$(php --version);
|
echo "Use phive installed";
|
||||||
|
fi;
|
||||||
|
|
||||||
|
if [ ! -f "${php_bin}" ]; then
|
||||||
|
echo "Set php ${php_bin} does not exist";
|
||||||
|
exit;
|
||||||
|
fi;
|
||||||
|
|
||||||
|
# Note 4dev/tests/bootstrap.php has to be set as bootstrap file in phpunit.xml
|
||||||
|
PHPUNIT_CALL=(
|
||||||
|
"${php_bin}"
|
||||||
|
);
|
||||||
|
if [ "${use_composer}" -eq 1 ]; then
|
||||||
|
PHPUNIT_CALL+=("${BASE_PATH}vendor/bin/phpunit");
|
||||||
|
else
|
||||||
|
PHPUNIT_CALL+=("${BASE_PATH}tools/phpunit");
|
||||||
|
fi;
|
||||||
|
PHPUNIT_CALL+=(
|
||||||
|
"${opt_testdox}"
|
||||||
|
"${opt_verbose}"
|
||||||
|
"-c" "${PHPUNIT_CONFIG}"
|
||||||
|
"${BASE_PATH}4dev/tests/"
|
||||||
|
);
|
||||||
|
"${PHPUNIT_CALL[@]}" || exit;
|
||||||
|
|
||||||
|
echo -e "\nPHPUnit Config: ${PHPUNIT_CONFIG}";
|
||||||
|
if [ "${no_php_version}" -eq 0 ]; then
|
||||||
|
echo "*** CALLED WITH PHP ${php_bin} ***";
|
||||||
|
${php_bin} --version;
|
||||||
|
else
|
||||||
|
echo "Default PHP used: $(php --version)";
|
||||||
fi;
|
fi;
|
||||||
|
|
||||||
# __END__
|
# __END__
|
||||||
|
|||||||
22
4dev/composer/sync-to-composer-all-folder.sh
Executable file
22
4dev/composer/sync-to-composer-all-folder.sh
Executable file
@@ -0,0 +1,22 @@
|
|||||||
|
#!/bin/env bash
|
||||||
|
|
||||||
|
# syncs
|
||||||
|
# 4dev/tests/
|
||||||
|
# www/lib/CoreLibs/
|
||||||
|
#
|
||||||
|
# to the composer corelibs all repo
|
||||||
|
|
||||||
|
GO="${1}";
|
||||||
|
DRY_RUN="";
|
||||||
|
if [ "${GO}" != "go" ]; then
|
||||||
|
DRY_RUN="-n ";
|
||||||
|
fi;
|
||||||
|
|
||||||
|
BASE="/storage/var/www/html/developers/clemens/core_data/";
|
||||||
|
SOURCE="${BASE}php_libraries/master/"
|
||||||
|
TARGET="${BASE}composer-packages/CoreLibs-Composer-All/"
|
||||||
|
|
||||||
|
rsync ${DRY_RUN}-Plzvrupt --stats --delete ${SOURCE}4dev/tests/ ${TARGET}test/phpunit/
|
||||||
|
rsync ${DRY_RUN}-Plzvrupt --stats --delete ${SOURCE}www/lib/CoreLibs/ ${TARGET}src/
|
||||||
|
|
||||||
|
# __END__
|
||||||
@@ -1,10 +1,11 @@
|
|||||||
|
# this list only holds edit_* related table data
|
||||||
# functions
|
# functions
|
||||||
function/set_uid.sql
|
|
||||||
function/set_generic.sql
|
|
||||||
function/random_string.sql
|
function/random_string.sql
|
||||||
function/set_edit_generic.sql
|
function/set_edit_generic.sql
|
||||||
function/edit_set_access_uid.sql
|
function/edit_access_set_uid.sql
|
||||||
|
function/edit_group_set_uid.sql
|
||||||
function/edit_log_partition_insert.sql
|
function/edit_log_partition_insert.sql
|
||||||
|
function/edit_user_set_login_user_id_set_date.sql
|
||||||
# generic tables
|
# generic tables
|
||||||
table/edit_temp_files.sql
|
table/edit_temp_files.sql
|
||||||
table/edit_generic.sql
|
table/edit_generic.sql
|
||||||
|
|||||||
@@ -6,20 +6,25 @@
|
|||||||
#exit;
|
#exit;
|
||||||
|
|
||||||
# if flagged 'y' then it will ask after each import to continue
|
# if flagged 'y' then it will ask after each import to continue
|
||||||
development='y';
|
development='n';
|
||||||
|
# do not import anything, just order flow output
|
||||||
test='n';
|
test='n';
|
||||||
input='';
|
# write to file do not write to DB directly
|
||||||
|
write='y';
|
||||||
# database connection info
|
# database connection info
|
||||||
db='<db name>';
|
db='<db name>';
|
||||||
host='<db host>';
|
host='<db host>';
|
||||||
user='<db user>';
|
user='<db user>';
|
||||||
schema="public";
|
schemas='public';
|
||||||
export PGPASSWORD='';
|
export PGPASSWORD='';
|
||||||
|
|
||||||
# log files
|
# log files
|
||||||
error_file="log/error";
|
error_file='log/error';
|
||||||
output_file="log/output";
|
output_file='log/output';
|
||||||
|
data_file='database_create_data.sql';
|
||||||
|
|
||||||
|
if [ "$write" = 'y' ]; then
|
||||||
|
rm -f "${data_file}";
|
||||||
|
fi;
|
||||||
if [ ! -f ORDER ]; then
|
if [ ! -f ORDER ]; then
|
||||||
echo "Could not find ORDER file";
|
echo "Could not find ORDER file";
|
||||||
exit;
|
exit;
|
||||||
@@ -40,26 +45,37 @@ while read file <&3; do
|
|||||||
if [ -f "$file" ]; then
|
if [ -f "$file" ]; then
|
||||||
for path in "$schemas"; do
|
for path in "$schemas"; do
|
||||||
echo "[+] WORK ON '${file}' @ '${path}'";
|
echo "[+] WORK ON '${file}' @ '${path}'";
|
||||||
|
# skip all on test
|
||||||
if [ "$test" = 'n' ]; then
|
if [ "$test" = 'n' ]; then
|
||||||
echo "=== START [$file] ===>" >> ${error_file};
|
# write to file
|
||||||
psql -U ${user} -h ${host} -f "${file}" ${db} 1>> ${output_file} 2>> ${error_file}
|
if [ "$write" = 'y' ]; then
|
||||||
echo "=== END [$file] ===>" >> ${error_file};
|
echo "-- START: ${file}" >> ${data_file};
|
||||||
fi;
|
cat "${file}" >> ${data_file};
|
||||||
if [ "$development" = "y" ]; then
|
echo "-- END: ${file}" >> ${data_file};
|
||||||
echo "Press 'y' to move to next. Press 'r' to reload last file. ^c to abort";
|
else
|
||||||
fi;
|
# write to DB
|
||||||
while [ "$development" = "y" ] && [ "$input" != "y" ]; do
|
echo "=== START [$file] ===>" >> ${error_file};
|
||||||
read -ep "Continue (y|r|^c): " input;
|
psql -U ${user} -h ${host} -f "${file}" ${db} 1>> ${output_file} 2>> ${error_file}
|
||||||
if [ "$input" = "r" ]; then
|
echo "=== END [$file] ===>" >> ${error_file};
|
||||||
echo "Reload File '${file}' ...";
|
# next wait for dev
|
||||||
if [ "$test" = 'n' ]; then
|
if [ "$development" = "y" ]; then
|
||||||
echo "=== START RELOAD [$file] ===>" >> ${error_file};
|
echo "Press 'y' to move to next. Press 'r' to reload last file. ^c to abort";
|
||||||
psql -U ${user} -h ${host} -f "${file}" ${db} 1>> ${output_file} 2>> ${error_file}
|
|
||||||
echo "=== END RELOAD [$file] ===>" >> ${error_file};
|
|
||||||
fi;
|
fi;
|
||||||
|
# loop run for reload on failed
|
||||||
|
while [ "$development" = "y" ] && [ "$input" != "y" ]; do
|
||||||
|
read -ep "Continue (y|r|^c): " input;
|
||||||
|
if [ "$input" = "r" ]; then
|
||||||
|
echo "Reload File '${file}' ...";
|
||||||
|
if [ "$test" = 'n' ]; then
|
||||||
|
echo "=== START RELOAD [$file] ===>" >> ${error_file};
|
||||||
|
psql -U ${user} -h ${host} -f "${file}" ${db} 1>> ${output_file} 2>> ${error_file}
|
||||||
|
echo "=== END RELOAD [$file] ===>" >> ${error_file};
|
||||||
|
fi;
|
||||||
|
fi;
|
||||||
|
done;
|
||||||
|
input='';
|
||||||
fi;
|
fi;
|
||||||
done;
|
fi;
|
||||||
input='';
|
|
||||||
done;
|
done;
|
||||||
elif [[ ${file::1} != "#" ]]; then
|
elif [[ ${file::1} != "#" ]]; then
|
||||||
echo "[!] COULD NOT FIND FILE: '${file}'";
|
echo "[!] COULD NOT FIND FILE: '${file}'";
|
||||||
|
|||||||
@@ -68,10 +68,11 @@ INSERT INTO edit_scheme (name, header_color, enabled) VALUES ('Visitor', 'B0C4B3
|
|||||||
INSERT INTO edit_scheme (name, header_color, enabled) VALUES ('User', '1E789E', 1);
|
INSERT INTO edit_scheme (name, header_color, enabled) VALUES ('User', '1E789E', 1);
|
||||||
|
|
||||||
-- edit language
|
-- edit language
|
||||||
|
-- short_name = locale without encoding
|
||||||
-- iso_name = encoding
|
-- iso_name = encoding
|
||||||
DELETE FROM edit_language;
|
DELETE FROM edit_language;
|
||||||
INSERT INTO edit_language (long_name, short_name, iso_name, order_number, enabled, lang_default) VALUES ('English', 'en_US', 'UTF-8', 1, 1, 1);
|
INSERT INTO edit_language (long_name, short_name, iso_name, order_number, enabled, lang_default) VALUES ('English', 'en_US', 'UTF-8', 1, 1, 1);
|
||||||
INSERT INTO edit_language (long_name, short_name, long_name, iso_name, order_number, enabled, lang_default) VALUES ('Japanese', 'ja_JP', 'UTF-8', 2, 1, 0);
|
INSERT INTO edit_language (long_name, short_name, iso_name, order_number, enabled, lang_default) VALUES ('Japanese', 'ja_JP', 'UTF-8', 2, 1, 0);
|
||||||
|
|
||||||
-- edit group
|
-- edit group
|
||||||
DELETE FROM edit_group;
|
DELETE FROM edit_group;
|
||||||
@@ -130,7 +131,7 @@ INSERT INTO edit_page_access (enabled, edit_group_id, edit_page_id, edit_access_
|
|||||||
-- inserts admin user so basic users can be created
|
-- inserts admin user so basic users can be created
|
||||||
DELETE FROM edit_user;
|
DELETE FROM edit_user;
|
||||||
INSERT INTO edit_user (username, password, enabled, debug, db_debug, email, protected, admin, edit_language_id, edit_group_id, edit_scheme_id, edit_access_right_id) VALUES ('admin', 'admin', 1, 1, 1, '', 1, 1,
|
INSERT INTO edit_user (username, password, enabled, debug, db_debug, email, protected, admin, edit_language_id, edit_group_id, edit_scheme_id, edit_access_right_id) VALUES ('admin', 'admin', 1, 1, 1, '', 1, 1,
|
||||||
(SELECT edit_language_id FROM edit_language WHERE short_name = 'en'),
|
(SELECT edit_language_id FROM edit_language WHERE short_name = 'en_US'),
|
||||||
(SELECT edit_group_id FROM edit_group WHERE name = 'Admin'),
|
(SELECT edit_group_id FROM edit_group WHERE name = 'Admin'),
|
||||||
(SELECT edit_scheme_id FROM edit_scheme WHERE name = 'Admin'),
|
(SELECT edit_scheme_id FROM edit_scheme WHERE name = 'Admin'),
|
||||||
(SELECT edit_access_right_id FROM edit_access_right WHERE type = 'admin')
|
(SELECT edit_access_right_id FROM edit_access_right WHERE type = 'admin')
|
||||||
|
|||||||
1031
4dev/database/database_create_data.sql
Normal file
1031
4dev/database/database_create_data.sql
Normal file
File diff suppressed because it is too large
Load Diff
28
4dev/database/function/edit_access_set_uid.sql
Normal file
28
4dev/database/function/edit_access_set_uid.sql
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
-- add uid add for edit_access table
|
||||||
|
|
||||||
|
CREATE OR REPLACE FUNCTION set_edit_access_uid() RETURNS TRIGGER AS
|
||||||
|
$$
|
||||||
|
DECLARE
|
||||||
|
myrec RECORD;
|
||||||
|
v_uid VARCHAR;
|
||||||
|
BEGIN
|
||||||
|
-- skip if NEW.name is not set
|
||||||
|
IF NEW.name IS NOT NULL AND NEW.name <> '' THEN
|
||||||
|
-- use NEW.name as base, remove all spaces
|
||||||
|
-- name data is already unique, so we do not need to worry about this here
|
||||||
|
v_uid := REPLACE(NEW.name, ' ', '');
|
||||||
|
IF TG_OP = 'INSERT' THEN
|
||||||
|
-- always set
|
||||||
|
NEW.uid := v_uid;
|
||||||
|
ELSIF TG_OP = 'UPDATE' THEN
|
||||||
|
-- check if not set, then set
|
||||||
|
SELECT INTO myrec t.* FROM edit_access t WHERE edit_access_id = NEW.edit_access_id;
|
||||||
|
IF FOUND THEN
|
||||||
|
NEW.uid := v_uid;
|
||||||
|
END IF;
|
||||||
|
END IF;
|
||||||
|
END IF;
|
||||||
|
RETURN NEW;
|
||||||
|
END;
|
||||||
|
$$
|
||||||
|
LANGUAGE 'plpgsql';
|
||||||
28
4dev/database/function/edit_group_set_uid.sql
Executable file
28
4dev/database/function/edit_group_set_uid.sql
Executable file
@@ -0,0 +1,28 @@
|
|||||||
|
-- add uid add for edit_group table
|
||||||
|
|
||||||
|
CREATE OR REPLACE FUNCTION set_edit_group_uid() RETURNS TRIGGER AS
|
||||||
|
$$
|
||||||
|
DECLARE
|
||||||
|
myrec RECORD;
|
||||||
|
v_uid VARCHAR;
|
||||||
|
BEGIN
|
||||||
|
-- skip if NEW.name is not set
|
||||||
|
IF NEW.name IS NOT NULL AND NEW.name <> '' THEN
|
||||||
|
-- use NEW.name as base, remove all spaces
|
||||||
|
-- name data is already unique, so we do not need to worry about this here
|
||||||
|
v_uid := REPLACE(NEW.name, ' ', '');
|
||||||
|
IF TG_OP = 'INSERT' THEN
|
||||||
|
-- always set
|
||||||
|
NEW.uid := v_uid;
|
||||||
|
ELSIF TG_OP = 'UPDATE' THEN
|
||||||
|
-- check if not set, then set
|
||||||
|
SELECT INTO myrec t.* FROM edit_group t WHERE edit_group_id = NEW.edit_group_id;
|
||||||
|
IF FOUND THEN
|
||||||
|
NEW.uid := v_uid;
|
||||||
|
END IF;
|
||||||
|
END IF;
|
||||||
|
END IF;
|
||||||
|
RETURN NEW;
|
||||||
|
END;
|
||||||
|
$$
|
||||||
|
LANGUAGE 'plpgsql';
|
||||||
@@ -9,142 +9,142 @@ CREATE OR REPLACE FUNCTION edit_log_insert_trigger ()
|
|||||||
RETURNS TRIGGER AS
|
RETURNS TRIGGER AS
|
||||||
$$
|
$$
|
||||||
DECLARE
|
DECLARE
|
||||||
start_date DATE := '2010-01-01';
|
start_date DATE := '2010-01-01';
|
||||||
end_date DATE;
|
end_date DATE;
|
||||||
timeformat TEXT := 'YYYY';
|
timeformat TEXT := 'YYYY';
|
||||||
selector TEXT := 'year';
|
selector TEXT := 'year';
|
||||||
base_table TEXT := 'edit_log';
|
base_table TEXT := 'edit_log';
|
||||||
_interval INTERVAL := '1 ' || selector;
|
_interval INTERVAL := '1 ' || selector;
|
||||||
_interval_next INTERVAL := '2 ' || selector;
|
_interval_next INTERVAL := '2 ' || selector;
|
||||||
table_name TEXT;
|
table_name TEXT;
|
||||||
-- compare date column
|
-- compare date column
|
||||||
compare_date DATE := NEW.event_date;
|
compare_date DATE := NEW.event_date;
|
||||||
compare_date_name TEXT := 'event_date';
|
compare_date_name TEXT := 'event_date';
|
||||||
-- the create commands
|
-- the create commands
|
||||||
command_create_table TEXT := 'CREATE TABLE IF NOT EXISTS {TABLE_NAME} (CHECK({COMPARE_DATE_NAME} >= {START_DATE} AND {COMPARE_DATE_NAME} < {END_DATE})) INHERITS ({BASE_NAME})';
|
command_create_table TEXT := 'CREATE TABLE IF NOT EXISTS {TABLE_NAME} (CHECK({COMPARE_DATE_NAME} >= {START_DATE} AND {COMPARE_DATE_NAME} < {END_DATE})) INHERITS ({BASE_NAME})';
|
||||||
command_create_primary_key TEXT := 'ALTER TABLE {TABLE_NAME} ADD PRIMARY KEY ({BASE_TABLE}_id)';
|
command_create_primary_key TEXT := 'ALTER TABLE {TABLE_NAME} ADD PRIMARY KEY ({BASE_TABLE}_id)';
|
||||||
command_create_foreign_key_1 TEXT := 'ALTER TABLE {TABLE_NAME} ADD CONSTRAINT {TABLE_NAME}_euid_fkey FOREIGN KEY (euid) REFERENCES edit_user (edit_user_id) MATCH FULL ON UPDATE CASCADE ON DELETE SET NULL';
|
command_create_foreign_key_1 TEXT := 'ALTER TABLE {TABLE_NAME} ADD CONSTRAINT {TABLE_NAME}_euid_fkey FOREIGN KEY (euid) REFERENCES edit_user (edit_user_id) MATCH FULL ON UPDATE CASCADE ON DELETE SET NULL';
|
||||||
command_create_trigger_1 TEXT = 'CREATE TRIGGER trg_{TABLE_NAME} BEFORE INSERT OR UPDATE ON {TABLE_NAME} FOR EACH ROW EXECUTE PROCEDURE set_edit_generic()';
|
command_create_trigger_1 TEXT = 'CREATE TRIGGER trg_{TABLE_NAME} BEFORE INSERT OR UPDATE ON {TABLE_NAME} FOR EACH ROW EXECUTE PROCEDURE set_edit_generic()';
|
||||||
BEGIN
|
BEGIN
|
||||||
-- we are in valid start time area
|
-- we are in valid start time area
|
||||||
IF (NEW.event_date >= start_date) THEN
|
IF (NEW.event_date >= start_date) THEN
|
||||||
-- current table name
|
-- current table name
|
||||||
table_name := base_table || '_' || to_char(NEW.event_date, timeformat);
|
table_name := base_table || '_' || to_char(NEW.event_date, timeformat);
|
||||||
BEGIN
|
BEGIN
|
||||||
EXECUTE 'INSERT INTO ' || quote_ident(table_name) || ' SELECT ($1).*' USING NEW;
|
EXECUTE 'INSERT INTO ' || quote_ident(table_name) || ' SELECT ($1).*' USING NEW;
|
||||||
-- if insert failed because of missing table, create new below
|
-- if insert failed because of missing table, create new below
|
||||||
EXCEPTION
|
EXCEPTION
|
||||||
WHEN undefined_table THEN
|
WHEN undefined_table THEN
|
||||||
-- another block, so in case the creation fails here too
|
-- another block, so in case the creation fails here too
|
||||||
BEGIN
|
BEGIN
|
||||||
-- create new table here + all indexes
|
-- create new table here + all indexes
|
||||||
start_date := date_trunc(selector, NEW.event_date);
|
start_date := date_trunc(selector, NEW.event_date);
|
||||||
end_date := date_trunc(selector, NEW.event_date + _interval);
|
end_date := date_trunc(selector, NEW.event_date + _interval);
|
||||||
-- creat table
|
-- creat table
|
||||||
EXECUTE format(REPLACE( -- end date
|
EXECUTE format(REPLACE( -- end date
|
||||||
REPLACE( -- start date
|
REPLACE( -- start date
|
||||||
REPLACE( -- compare date name
|
REPLACE( -- compare date name
|
||||||
REPLACE( -- base name (inherit)
|
REPLACE( -- base name (inherit)
|
||||||
REPLACE( -- table name
|
REPLACE( -- table name
|
||||||
command_create_table,
|
command_create_table,
|
||||||
'{TABLE_NAME}',
|
'{TABLE_NAME}',
|
||||||
table_name
|
table_name
|
||||||
),
|
),
|
||||||
'{BASE_NAME}',
|
'{BASE_NAME}',
|
||||||
base_table
|
base_table
|
||||||
),
|
),
|
||||||
'{COMPARE_DATE_NAME}',
|
'{COMPARE_DATE_NAME}',
|
||||||
compare_date_name
|
compare_date_name
|
||||||
),
|
),
|
||||||
'{START_DATE}',
|
'{START_DATE}',
|
||||||
quote_literal(start_date)
|
quote_literal(start_date)
|
||||||
),
|
),
|
||||||
'{END_DATE}',
|
'{END_DATE}',
|
||||||
quote_literal(end_date)
|
quote_literal(end_date)
|
||||||
));
|
));
|
||||||
-- create all indexes and triggers
|
-- create all indexes and triggers
|
||||||
EXECUTE format(REPLACE(
|
EXECUTE format(REPLACE(
|
||||||
REPLACE(
|
REPLACE(
|
||||||
command_create_primary_key,
|
command_create_primary_key,
|
||||||
'{TABLE_NAME}',
|
'{TABLE_NAME}',
|
||||||
table_name
|
table_name
|
||||||
),
|
),
|
||||||
'{BASE_TABLE}',
|
'{BASE_TABLE}',
|
||||||
base_table
|
base_table
|
||||||
));
|
));
|
||||||
-- FK constraints
|
-- FK constraints
|
||||||
EXECUTE format(REPLACE(command_create_foreign_key_1, '{TABLE_NAME}', table_name));
|
EXECUTE format(REPLACE(command_create_foreign_key_1, '{TABLE_NAME}', table_name));
|
||||||
-- generic trigger
|
-- generic trigger
|
||||||
EXECUTE format(REPLACE(command_create_trigger_1, '{TABLE_NAME}', table_name));
|
EXECUTE format(REPLACE(command_create_trigger_1, '{TABLE_NAME}', table_name));
|
||||||
|
|
||||||
-- insert try again
|
-- insert try again
|
||||||
EXECUTE 'INSERT INTO ' || quote_ident(table_name) || ' SELECT ($1).*' USING NEW;
|
EXECUTE 'INSERT INTO ' || quote_ident(table_name) || ' SELECT ($1).*' USING NEW;
|
||||||
EXCEPTION
|
EXCEPTION
|
||||||
WHEN OTHERS THEN
|
WHEN OTHERS THEN
|
||||||
-- if this faled, throw it into the overflow table (so we don't loose anything)
|
-- if this faled, throw it into the overflow table (so we don't loose anything)
|
||||||
INSERT INTO edit_log_overflow VALUES (NEW.*);
|
INSERT INTO edit_log_overflow VALUES (NEW.*);
|
||||||
END;
|
END;
|
||||||
-- other errors, insert into overlow
|
-- other errors, insert into overlow
|
||||||
WHEN OTHERS THEN
|
WHEN OTHERS THEN
|
||||||
-- if this faled, throw it into the overflow table (so we don't loose anything)
|
-- if this faled, throw it into the overflow table (so we don't loose anything)
|
||||||
INSERT INTO edit_log_overflow VALUES (NEW.*);
|
INSERT INTO edit_log_overflow VALUES (NEW.*);
|
||||||
END;
|
END;
|
||||||
-- main insert run done, check if we have to create next months table
|
-- main insert run done, check if we have to create next months table
|
||||||
BEGIN
|
BEGIN
|
||||||
-- check if next month table exists
|
-- check if next month table exists
|
||||||
table_name := base_table || '_' || to_char((SELECT NEW.event_date + _interval)::DATE, timeformat);
|
table_name := base_table || '_' || to_char((SELECT NEW.event_date + _interval)::DATE, timeformat);
|
||||||
-- RAISE NOTICE 'SEARCH NEXT: %', table_name;
|
-- RAISE NOTICE 'SEARCH NEXT: %', table_name;
|
||||||
IF (SELECT to_regclass(table_name)) IS NULL THEN
|
IF (SELECT to_regclass(table_name)) IS NULL THEN
|
||||||
-- move inner interval same
|
-- move inner interval same
|
||||||
start_date := date_trunc(selector, NEW.event_date + _interval);
|
start_date := date_trunc(selector, NEW.event_date + _interval);
|
||||||
end_date := date_trunc(selector, NEW.event_date + _interval_next);
|
end_date := date_trunc(selector, NEW.event_date + _interval_next);
|
||||||
-- RAISE NOTICE 'CREATE NEXT: %', table_name;
|
-- RAISE NOTICE 'CREATE NEXT: %', table_name;
|
||||||
-- create table
|
-- create table
|
||||||
EXECUTE format(REPLACE( -- end date
|
EXECUTE format(REPLACE( -- end date
|
||||||
REPLACE( -- start date
|
REPLACE( -- start date
|
||||||
REPLACE( -- compare date name
|
REPLACE( -- compare date name
|
||||||
REPLACE( -- base name (inherit)
|
REPLACE( -- base name (inherit)
|
||||||
REPLACE( -- table name
|
REPLACE( -- table name
|
||||||
command_create_table,
|
command_create_table,
|
||||||
'{TABLE_NAME}',
|
'{TABLE_NAME}',
|
||||||
table_name
|
table_name
|
||||||
),
|
),
|
||||||
'{BASE_NAME}',
|
'{BASE_NAME}',
|
||||||
base_table
|
base_table
|
||||||
),
|
),
|
||||||
'{COMPARE_DATE_NAME}',
|
'{COMPARE_DATE_NAME}',
|
||||||
compare_date_name
|
compare_date_name
|
||||||
),
|
),
|
||||||
'{START_DATE}',
|
'{START_DATE}',
|
||||||
quote_literal(start_date)
|
quote_literal(start_date)
|
||||||
),
|
),
|
||||||
'{END_DATE}',
|
'{END_DATE}',
|
||||||
quote_literal(end_date)
|
quote_literal(end_date)
|
||||||
));
|
));
|
||||||
-- create all indexes and triggers
|
-- create all indexes and triggers
|
||||||
EXECUTE format(REPLACE(
|
EXECUTE format(REPLACE(
|
||||||
REPLACE(
|
REPLACE(
|
||||||
command_create_primary_key,
|
command_create_primary_key,
|
||||||
'{TABLE_NAME}',
|
'{TABLE_NAME}',
|
||||||
table_name
|
table_name
|
||||||
),
|
),
|
||||||
'{BASE_TABLE}',
|
'{BASE_TABLE}',
|
||||||
base_table
|
base_table
|
||||||
));
|
));
|
||||||
-- FK constraints
|
-- FK constraints
|
||||||
EXECUTE format(REPLACE(command_create_foreign_key_1, '{TABLE_NAME}', table_name));
|
EXECUTE format(REPLACE(command_create_foreign_key_1, '{TABLE_NAME}', table_name));
|
||||||
-- generic trigger
|
-- generic trigger
|
||||||
EXECUTE format(REPLACE(command_create_trigger_1, '{TABLE_NAME}', table_name));
|
EXECUTE format(REPLACE(command_create_trigger_1, '{TABLE_NAME}', table_name));
|
||||||
END IF;
|
END IF;
|
||||||
EXCEPTION
|
EXCEPTION
|
||||||
WHEN OTHERS THEN
|
WHEN OTHERS THEN
|
||||||
RAISE NOTICE 'Failed to create next table: %', table_name;
|
RAISE NOTICE 'Failed to create next table: %', table_name;
|
||||||
END;
|
END;
|
||||||
ELSE
|
ELSE
|
||||||
-- if outside valid date, insert into overflow
|
-- if outside valid date, insert into overflow
|
||||||
INSERT INTO edit_log_overflow VALUES (NEW.*);
|
INSERT INTO edit_log_overflow VALUES (NEW.*);
|
||||||
END IF;
|
END IF;
|
||||||
RETURN NULL;
|
RETURN NULL;
|
||||||
END
|
END
|
||||||
$$
|
$$
|
||||||
LANGUAGE 'plpgsql';
|
LANGUAGE 'plpgsql';
|
||||||
|
|||||||
@@ -1,28 +0,0 @@
|
|||||||
-- add uid add for edit_access table
|
|
||||||
|
|
||||||
CREATE OR REPLACE FUNCTION set_edit_access_uid() RETURNS TRIGGER AS
|
|
||||||
$$
|
|
||||||
DECLARE
|
|
||||||
myrec RECORD;
|
|
||||||
v_uid VARCHAR;
|
|
||||||
BEGIN
|
|
||||||
-- skip if NEW.name is not set
|
|
||||||
IF NEW.name IS NOT NULL AND NEW.name <> '' THEN
|
|
||||||
-- use NEW.name as base, remove all spaces
|
|
||||||
-- name data is already unique, so we do not need to worry about this here
|
|
||||||
v_uid := REPLACE(NEW.name, ' ', '');
|
|
||||||
IF TG_OP = 'INSERT' THEN
|
|
||||||
-- always set
|
|
||||||
NEW.uid := v_uid;
|
|
||||||
ELSIF TG_OP = 'UPDATE' THEN
|
|
||||||
-- check if not set, then set
|
|
||||||
SELECT INTO myrec t.* FROM edit_access t WHERE edit_access_id = NEW.edit_access_id;
|
|
||||||
IF FOUND THEN
|
|
||||||
NEW.uid := v_uid;
|
|
||||||
END IF;
|
|
||||||
END IF;
|
|
||||||
END IF;
|
|
||||||
RETURN NEW;
|
|
||||||
END;
|
|
||||||
$$
|
|
||||||
LANGUAGE 'plpgsql';
|
|
||||||
@@ -1,28 +0,0 @@
|
|||||||
-- add uid add for edit_group table
|
|
||||||
|
|
||||||
CREATE OR REPLACE FUNCTION set_edit_group_uid() RETURNS TRIGGER AS
|
|
||||||
$$
|
|
||||||
DECLARE
|
|
||||||
myrec RECORD;
|
|
||||||
v_uid VARCHAR;
|
|
||||||
BEGIN
|
|
||||||
-- skip if NEW.name is not set
|
|
||||||
IF NEW.name IS NOT NULL AND NEW.name <> '' THEN
|
|
||||||
-- use NEW.name as base, remove all spaces
|
|
||||||
-- name data is already unique, so we do not need to worry about this here
|
|
||||||
v_uid := REPLACE(NEW.name, ' ', '');
|
|
||||||
IF TG_OP = 'INSERT' THEN
|
|
||||||
-- always set
|
|
||||||
NEW.uid := v_uid;
|
|
||||||
ELSIF TG_OP = 'UPDATE' THEN
|
|
||||||
-- check if not set, then set
|
|
||||||
SELECT INTO myrec t.* FROM edit_group t WHERE edit_group_id = NEW.edit_group_id;
|
|
||||||
IF FOUND THEN
|
|
||||||
NEW.uid := v_uid;
|
|
||||||
END IF;
|
|
||||||
END IF;
|
|
||||||
END IF;
|
|
||||||
RETURN NEW;
|
|
||||||
END;
|
|
||||||
$$
|
|
||||||
LANGUAGE 'plpgsql';
|
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
-- set edit user login_user_id_set_date if login_user_id is set
|
||||||
|
-- NOW() if not empty
|
||||||
|
|
||||||
|
CREATE OR REPLACE FUNCTION set_login_user_id_set_date()
|
||||||
|
RETURNS TRIGGER AS
|
||||||
|
$$
|
||||||
|
BEGIN
|
||||||
|
-- if new is not null/empty
|
||||||
|
-- and old one is null or old one different new one
|
||||||
|
-- set NOW()
|
||||||
|
-- if new one is NULL
|
||||||
|
-- set NULL
|
||||||
|
IF
|
||||||
|
NEW.login_user_id IS NOT NULL AND NEW.login_user_id <> '' AND
|
||||||
|
(OLD.login_user_id IS NULL OR NEW.login_user_id <> OLD.login_user_id)
|
||||||
|
THEN
|
||||||
|
NEW.login_user_id_set_date = NOW();
|
||||||
|
NEW.login_user_id_last_revalidate = NOW();
|
||||||
|
ELSIF NEW.login_user_id IS NULL OR NEW.login_user_id = '' THEN
|
||||||
|
NEW.login_user_id_set_date = NULL;
|
||||||
|
NEW.login_user_id_last_revalidate = NULL;
|
||||||
|
END IF;
|
||||||
|
RETURN NEW;
|
||||||
|
END;
|
||||||
|
$$
|
||||||
|
LANGUAGE 'plpgsql';
|
||||||
@@ -1,18 +1,20 @@
|
|||||||
-- create random string with length X
|
-- create random string with length X
|
||||||
|
|
||||||
CREATE FUNCTION random_string(randomLength int)
|
CREATE FUNCTION random_string(randomLength int)
|
||||||
RETURNS text AS $$
|
RETURNS text AS
|
||||||
|
$$
|
||||||
SELECT array_to_string(
|
SELECT array_to_string(
|
||||||
ARRAY(
|
ARRAY(
|
||||||
SELECT substring(
|
SELECT substring(
|
||||||
'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789',
|
'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789',
|
||||||
trunc(random() * 62)::int + 1,
|
trunc(random() * 62)::int + 1,
|
||||||
1
|
1
|
||||||
)
|
)
|
||||||
FROM generate_series(1, randomLength) AS gs(x)
|
FROM generate_series(1, randomLength) AS gs(x)
|
||||||
),
|
),
|
||||||
''
|
''
|
||||||
)
|
)
|
||||||
$$ LANGUAGE SQL
|
$$
|
||||||
|
LANGUAGE SQL
|
||||||
RETURNS NULL ON NULL INPUT
|
RETURNS NULL ON NULL INPUT
|
||||||
VOLATILE; -- LEAKPROOF;
|
VOLATILE; -- LEAKPROOF;
|
||||||
|
|||||||
15
4dev/database/function/set_date.sql
Normal file
15
4dev/database/function/set_date.sql
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
-- adds the created or updated date tags
|
||||||
|
|
||||||
|
CREATE OR REPLACE FUNCTION set_date()
|
||||||
|
RETURNS TRIGGER AS
|
||||||
|
$$
|
||||||
|
BEGIN
|
||||||
|
IF TG_OP = 'INSERT' THEN
|
||||||
|
NEW.date_created := clock_timestamp();
|
||||||
|
ELSIF TG_OP = 'UPDATE' THEN
|
||||||
|
NEW.date_updated := clock_timestamp();
|
||||||
|
END IF;
|
||||||
|
RETURN NEW;
|
||||||
|
END;
|
||||||
|
$$
|
||||||
|
LANGUAGE 'plpgsql';
|
||||||
@@ -1,15 +1,19 @@
|
|||||||
-- adds the created or updated date tags
|
-- adds the created or updated date tags
|
||||||
|
|
||||||
CREATE OR REPLACE FUNCTION set_edit_generic() RETURNS TRIGGER AS '
|
CREATE OR REPLACE FUNCTION set_edit_generic()
|
||||||
DECLARE
|
RETURNS TRIGGER AS
|
||||||
random_length INT = 12; -- that should be long enough
|
$$
|
||||||
BEGIN
|
DECLARE
|
||||||
IF TG_OP = ''INSERT'' THEN
|
random_length INT = 25; -- that should be long enough
|
||||||
NEW.date_created := ''now'';
|
BEGIN
|
||||||
NEW.cuid := random_string(random_length);
|
IF TG_OP = 'INSERT' THEN
|
||||||
ELSIF TG_OP = ''UPDATE'' THEN
|
NEW.date_created := clock_timestamp();
|
||||||
NEW.date_updated := ''now'';
|
NEW.cuid := random_string(random_length);
|
||||||
END IF;
|
NEW.cuuid := gen_random_uuid();
|
||||||
RETURN NEW;
|
ELSIF TG_OP = 'UPDATE' THEN
|
||||||
END;
|
NEW.date_updated := clock_timestamp();
|
||||||
' LANGUAGE 'plpgsql';
|
END IF;
|
||||||
|
RETURN NEW;
|
||||||
|
END;
|
||||||
|
$$
|
||||||
|
LANGUAGE 'plpgsql';
|
||||||
|
|||||||
@@ -1,12 +0,0 @@
|
|||||||
-- adds the created or updated date tags
|
|
||||||
|
|
||||||
CREATE OR REPLACE FUNCTION set_generic() RETURNS TRIGGER AS '
|
|
||||||
BEGIN
|
|
||||||
IF TG_OP = ''INSERT'' THEN
|
|
||||||
NEW.date_created := ''now'';
|
|
||||||
ELSIF TG_OP = ''UPDATE'' THEN
|
|
||||||
NEW.date_updated := ''now'';
|
|
||||||
END IF;
|
|
||||||
RETURN NEW;
|
|
||||||
END;
|
|
||||||
' LANGUAGE 'plpgsql';
|
|
||||||
21
4dev/database/function/set_generic_uid.sql
Normal file
21
4dev/database/function/set_generic_uid.sql
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
-- set generic with date and uid combined
|
||||||
|
-- don't use with set_generic/set_uid together
|
||||||
|
|
||||||
|
CREATE OR REPLACE FUNCTION set_generic()
|
||||||
|
RETURNS TRIGGER AS
|
||||||
|
$$
|
||||||
|
DECLARE
|
||||||
|
random_length INT = 32; -- long for massive data
|
||||||
|
BEGIN
|
||||||
|
IF TG_OP = 'INSERT' THEN
|
||||||
|
NEW.date_created := clock_timestamp();
|
||||||
|
IF NEW.uid IS NULL THEN
|
||||||
|
NEW.uid := random_string(random_length);
|
||||||
|
END IF;
|
||||||
|
ELSIF TG_OP = 'UPDATE' THEN
|
||||||
|
NEW.date_updated := clock_timestamp();
|
||||||
|
END IF;
|
||||||
|
RETURN NEW;
|
||||||
|
END;
|
||||||
|
$$
|
||||||
|
LANGUAGE 'plpgsql';
|
||||||
@@ -1,12 +1,15 @@
|
|||||||
-- adds the created or updated date tags
|
-- adds the created or updated date tags
|
||||||
|
|
||||||
CREATE OR REPLACE FUNCTION set_uid() RETURNS TRIGGER AS '
|
CREATE OR REPLACE FUNCTION set_uid()
|
||||||
DECLARE
|
RETURNS TRIGGER AS
|
||||||
random_length INT = 32; -- that should be long enough
|
$$
|
||||||
BEGIN
|
DECLARE
|
||||||
IF TG_OP = ''INSERT'' THEN
|
random_length INT = 32; -- that should be long enough
|
||||||
NEW.uid := random_string(random_length);
|
BEGIN
|
||||||
END IF;
|
IF TG_OP = 'INSERT' THEN
|
||||||
RETURN NEW;
|
NEW.uid := random_string(random_length);
|
||||||
END;
|
END IF;
|
||||||
' LANGUAGE 'plpgsql';
|
RETURN NEW;
|
||||||
|
END;
|
||||||
|
$$
|
||||||
|
LANGUAGE 'plpgsql';
|
||||||
|
|||||||
@@ -1,16 +0,0 @@
|
|||||||
-- adds the created or updated date tags
|
|
||||||
|
|
||||||
-- OLD, DEPRECATED, use set_generic.sql
|
|
||||||
|
|
||||||
-- CREATE OR REPLACE FUNCTION set_generic() RETURNS TRIGGER AS '
|
|
||||||
-- BEGIN
|
|
||||||
-- IF TG_OP = ''INSERT'' THEN
|
|
||||||
-- NEW.date_created := clock_timestamp();
|
|
||||||
-- NEW.user_created := current_user;
|
|
||||||
-- ELSIF TG_OP = ''UPDATE'' THEN
|
|
||||||
-- NEW.date_updated := clock_timestamp();
|
|
||||||
-- NEW.user_updated := current_user;
|
|
||||||
-- END IF;
|
|
||||||
-- RETURN NEW;
|
|
||||||
-- END;
|
|
||||||
-- ' LANGUAGE 'plpgsql';
|
|
||||||
110
4dev/database/function/upgrade_serial_to_identity.sql
Normal file
110
4dev/database/function/upgrade_serial_to_identity.sql
Normal file
@@ -0,0 +1,110 @@
|
|||||||
|
-- Upgrade serial to identity type
|
||||||
|
--
|
||||||
|
-- Original: https://www.enterprisedb.com/blog/postgresql-10-identity-columns-explained#section-6
|
||||||
|
--
|
||||||
|
-- @param reclass tbl The table where the column is located, prefix with 'schema.' if different schema
|
||||||
|
-- @param name col The column to be changed
|
||||||
|
-- @param varchar identity_type [default=a] Allowed a, d, assigned, default
|
||||||
|
-- @param varchar col_type [default=''] Allowed smallint, int, bigint, int2, int4, int8
|
||||||
|
-- @returns varchar status tring
|
||||||
|
-- @raises EXCEPTON on column not found, no linked sequence, more than one linked sequence found, invalid col type
|
||||||
|
--
|
||||||
|
CREATE OR REPLACE FUNCTION upgrade_serial_to_identity(
|
||||||
|
tbl regclass,
|
||||||
|
col name,
|
||||||
|
identity_type varchar = 'a',
|
||||||
|
col_type varchar = ''
|
||||||
|
)
|
||||||
|
RETURNS varchar
|
||||||
|
LANGUAGE plpgsql
|
||||||
|
AS $$
|
||||||
|
DECLARE
|
||||||
|
colnum SMALLINT;
|
||||||
|
seqid OID;
|
||||||
|
count INT;
|
||||||
|
col_type_oid INT;
|
||||||
|
col_type_len INT;
|
||||||
|
current_col_atttypid OID;
|
||||||
|
current_col_attlen INT;
|
||||||
|
status_string VARCHAR;
|
||||||
|
BEGIN
|
||||||
|
-- switch between always (default) or default identiy type
|
||||||
|
IF identity_type NOT IN ('a', 'd', 'assigned', 'default') THEN
|
||||||
|
identity_type := 'a';
|
||||||
|
ELSE
|
||||||
|
IF identity_type = 'default' THEN
|
||||||
|
identity_type := 'd';
|
||||||
|
ELSIF identity_type = 'assigned' THEN
|
||||||
|
identity_type := 'a';
|
||||||
|
END IF;
|
||||||
|
END IF;
|
||||||
|
-- find column number, attribute oid and attribute len
|
||||||
|
SELECT attnum, atttypid, attlen
|
||||||
|
INTO colnum, current_col_atttypid, current_col_attlen
|
||||||
|
FROM pg_attribute
|
||||||
|
WHERE attrelid = tbl AND attname = col;
|
||||||
|
IF NOT FOUND THEN
|
||||||
|
RAISE EXCEPTION 'column does not exist';
|
||||||
|
END IF;
|
||||||
|
|
||||||
|
-- find sequence
|
||||||
|
SELECT INTO seqid objid
|
||||||
|
FROM pg_depend
|
||||||
|
WHERE (refclassid, refobjid, refobjsubid) = ('pg_class'::regclass, tbl, colnum)
|
||||||
|
AND classid = 'pg_class'::regclass AND objsubid = 0
|
||||||
|
AND deptype = 'a';
|
||||||
|
|
||||||
|
GET DIAGNOSTICS count = ROW_COUNT;
|
||||||
|
IF count < 1 THEN
|
||||||
|
RAISE EXCEPTION 'no linked sequence found';
|
||||||
|
ELSIF count > 1 THEN
|
||||||
|
RAISE EXCEPTION 'more than one linked sequence found';
|
||||||
|
END IF;
|
||||||
|
|
||||||
|
IF col_type <> '' AND col_type NOT IN ('smallint', 'int', 'bigint', 'int2', 'int4', 'int8') THEN
|
||||||
|
RAISE EXCEPTION 'Invalid col type: %', col_type;
|
||||||
|
END IF;
|
||||||
|
|
||||||
|
-- drop the default
|
||||||
|
EXECUTE 'ALTER TABLE ' || tbl || ' ALTER COLUMN ' || quote_ident(col) || ' DROP DEFAULT';
|
||||||
|
|
||||||
|
-- change the dependency between column and sequence to internal
|
||||||
|
UPDATE pg_depend
|
||||||
|
SET deptype = 'i'
|
||||||
|
WHERE (classid, objid, objsubid) = ('pg_class'::regclass, seqid, 0)
|
||||||
|
AND deptype = 'a';
|
||||||
|
|
||||||
|
-- mark the column as identity column
|
||||||
|
UPDATE pg_attribute
|
||||||
|
-- set to 'd' for default
|
||||||
|
SET attidentity = identity_type
|
||||||
|
WHERE attrelid = tbl
|
||||||
|
AND attname = col;
|
||||||
|
status_string := 'Updated to identity for table "' || tbl || '" and columen "' || col || '" with type "' || identity_type || '"';
|
||||||
|
|
||||||
|
-- set type if requested and not empty
|
||||||
|
IF col_type <> '' THEN
|
||||||
|
-- rewrite smallint, int, bigint
|
||||||
|
IF col_type = 'smallint' THEN
|
||||||
|
col_type := 'int2';
|
||||||
|
ELSIF col_type = 'int' THEN
|
||||||
|
col_type := 'int4';
|
||||||
|
ELSIF col_type = 'bigint' THEN
|
||||||
|
col_type := 'int8';
|
||||||
|
END IF;
|
||||||
|
-- get the length and oid for selected
|
||||||
|
SELECT oid, typlen INTO col_type_oid, col_type_len FROM pg_type WHERE typname = col_type;
|
||||||
|
-- set only if diff or hight
|
||||||
|
IF current_col_atttypid <> col_type_oid AND col_type_len > current_col_attlen THEN
|
||||||
|
status_string := status_string || '. Change col type: ' || col_type;
|
||||||
|
-- update type
|
||||||
|
UPDATE pg_attribute
|
||||||
|
SET
|
||||||
|
atttypid = col_type_oid, attlen = col_type_len
|
||||||
|
WHERE attrelid = tbl
|
||||||
|
AND attname = col;
|
||||||
|
END IF;
|
||||||
|
END IF;
|
||||||
|
RETURN status_string;
|
||||||
|
END;
|
||||||
|
$$;
|
||||||
@@ -7,13 +7,13 @@
|
|||||||
|
|
||||||
-- DROP TABLE edit_access;
|
-- DROP TABLE edit_access;
|
||||||
CREATE TABLE edit_access (
|
CREATE TABLE edit_access (
|
||||||
edit_access_id SERIAL PRIMARY KEY,
|
edit_access_id INT GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
|
||||||
enabled SMALLINT NOT NULL DEFAULT 0,
|
enabled SMALLINT NOT NULL DEFAULT 0,
|
||||||
protected SMALLINT DEFAULT 0,
|
protected SMALLINT DEFAULT 0,
|
||||||
deleted SMALLINT DEFAULT 0,
|
deleted SMALLINT DEFAULT 0,
|
||||||
uid VARCHAR,
|
uid VARCHAR,
|
||||||
name VARCHAR UNIQUE,
|
name VARCHAR UNIQUE,
|
||||||
description VARCHAR,
|
description VARCHAR,
|
||||||
color VARCHAR,
|
color VARCHAR,
|
||||||
additional_acl JSONB
|
additional_acl JSONB
|
||||||
) INHERITS (edit_generic) WITHOUT OIDS;
|
) INHERITS (edit_generic) WITHOUT OIDS;
|
||||||
|
|||||||
@@ -7,12 +7,12 @@
|
|||||||
|
|
||||||
-- DROP TABLE edit_access_data;
|
-- DROP TABLE edit_access_data;
|
||||||
CREATE TABLE edit_access_data (
|
CREATE TABLE edit_access_data (
|
||||||
edit_access_data_id SERIAL PRIMARY KEY,
|
edit_access_data_id INT GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
|
||||||
edit_access_id INT NOT NULL,
|
edit_access_id INT NOT NULL,
|
||||||
FOREIGN KEY (edit_access_id) REFERENCES edit_access (edit_access_id) MATCH FULL ON DELETE CASCADE ON UPDATE CASCADE,
|
FOREIGN KEY (edit_access_id) REFERENCES edit_access (edit_access_id) MATCH FULL ON DELETE CASCADE ON UPDATE CASCADE,
|
||||||
enabled SMALLINT NOT NULL DEFAULT 0,
|
enabled SMALLINT NOT NULL DEFAULT 0,
|
||||||
name VARCHAR,
|
name VARCHAR,
|
||||||
value VARCHAR
|
value VARCHAR
|
||||||
) INHERITS (edit_generic) WITHOUT OIDS;
|
) INHERITS (edit_generic) WITHOUT OIDS;
|
||||||
|
|
||||||
-- create a unique index for each attached data block for each edit access can
|
-- create a unique index for each attached data block for each edit access can
|
||||||
|
|||||||
@@ -8,9 +8,9 @@
|
|||||||
|
|
||||||
-- DROP TABLE edit_access_right;
|
-- DROP TABLE edit_access_right;
|
||||||
CREATE TABLE edit_access_right (
|
CREATE TABLE edit_access_right (
|
||||||
edit_access_right_id SERIAL PRIMARY KEY,
|
edit_access_right_id INT GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
|
||||||
name VARCHAR,
|
name VARCHAR,
|
||||||
level SMALLINT,
|
level SMALLINT,
|
||||||
type VARCHAR,
|
type VARCHAR,
|
||||||
UNIQUE (level,type)
|
UNIQUE (level,type)
|
||||||
) INHERITS (edit_generic) WITHOUT OIDS;
|
) INHERITS (edit_generic) WITHOUT OIDS;
|
||||||
|
|||||||
@@ -7,13 +7,13 @@
|
|||||||
|
|
||||||
-- DROP TABLE edit_access_user;
|
-- DROP TABLE edit_access_user;
|
||||||
CREATE TABLE edit_access_user (
|
CREATE TABLE edit_access_user (
|
||||||
edit_access_user_id SERIAL PRIMARY KEY,
|
edit_access_user_id INT GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
|
||||||
edit_access_id INT NOT NULL,
|
edit_access_id INT NOT NULL,
|
||||||
FOREIGN KEY (edit_access_id) REFERENCES edit_access (edit_access_id) MATCH FULL ON DELETE CASCADE ON UPDATE CASCADE,
|
FOREIGN KEY (edit_access_id) REFERENCES edit_access (edit_access_id) MATCH FULL ON DELETE CASCADE ON UPDATE CASCADE,
|
||||||
edit_user_id INT NOT NULL,
|
edit_user_id INT NOT NULL,
|
||||||
FOREIGN KEY (edit_user_id) REFERENCES edit_user (edit_user_id) MATCH FULL ON DELETE CASCADE ON UPDATE CASCADE,
|
FOREIGN KEY (edit_user_id) REFERENCES edit_user (edit_user_id) MATCH FULL ON DELETE CASCADE ON UPDATE CASCADE,
|
||||||
edit_access_right_id INT NOT NULL,
|
edit_access_right_id INT NOT NULL,
|
||||||
FOREIGN KEY (edit_access_right_id) REFERENCES edit_access_right (edit_access_right_id) MATCH FULL ON DELETE CASCADE ON UPDATE CASCADE,
|
FOREIGN KEY (edit_access_right_id) REFERENCES edit_access_right (edit_access_right_id) MATCH FULL ON DELETE CASCADE ON UPDATE CASCADE,
|
||||||
edit_default SMALLINT DEFAULT 0,
|
edit_default SMALLINT DEFAULT 0,
|
||||||
enabled SMALLINT NOT NULL DEFAULT 0
|
enabled SMALLINT NOT NULL DEFAULT 0
|
||||||
) INHERITS (edit_generic) WITHOUT OIDS;
|
) INHERITS (edit_generic) WITHOUT OIDS;
|
||||||
|
|||||||
@@ -7,7 +7,8 @@
|
|||||||
|
|
||||||
-- DROP TABLE edit_generic;
|
-- DROP TABLE edit_generic;
|
||||||
CREATE TABLE edit_generic (
|
CREATE TABLE edit_generic (
|
||||||
cuid VARCHAR,
|
cuid VARCHAR,
|
||||||
date_created TIMESTAMP WITHOUT TIME ZONE DEFAULT clock_timestamp(),
|
cuuid UUID DEFAULT gen_random_uuid(),
|
||||||
date_updated TIMESTAMP WITHOUT TIME ZONE
|
date_created TIMESTAMP WITHOUT TIME ZONE DEFAULT clock_timestamp(),
|
||||||
|
date_updated TIMESTAMP WITHOUT TIME ZONE
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -7,14 +7,14 @@
|
|||||||
|
|
||||||
-- DROP TABLE edit_group;
|
-- DROP TABLE edit_group;
|
||||||
CREATE TABLE edit_group (
|
CREATE TABLE edit_group (
|
||||||
edit_group_id SERIAL PRIMARY KEY,
|
edit_group_id INT GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
|
||||||
edit_scheme_id INT,
|
edit_scheme_id INT,
|
||||||
FOREIGN KEY (edit_scheme_id) REFERENCES edit_scheme (edit_scheme_id) MATCH FULL ON DELETE CASCADE ON UPDATE CASCADE,
|
FOREIGN KEY (edit_scheme_id) REFERENCES edit_scheme (edit_scheme_id) MATCH FULL ON DELETE CASCADE ON UPDATE CASCADE,
|
||||||
edit_access_right_id INT NOT NULL,
|
edit_access_right_id INT NOT NULL,
|
||||||
FOREIGN KEY (edit_access_right_id) REFERENCES edit_access_right (edit_access_right_id) MATCH FULL ON DELETE CASCADE ON UPDATE CASCADE,
|
FOREIGN KEY (edit_access_right_id) REFERENCES edit_access_right (edit_access_right_id) MATCH FULL ON DELETE CASCADE ON UPDATE CASCADE,
|
||||||
enabled SMALLINT NOT NULL DEFAULT 0,
|
enabled SMALLINT NOT NULL DEFAULT 0,
|
||||||
deleted SMALLINT DEFAULT 0,
|
deleted SMALLINT DEFAULT 0,
|
||||||
uid VARCHAR,
|
uid VARCHAR,
|
||||||
name VARCHAR,
|
name VARCHAR,
|
||||||
additional_acl JSONB
|
additional_acl JSONB
|
||||||
) INHERITS (edit_generic) WITHOUT OIDS;
|
) INHERITS (edit_generic) WITHOUT OIDS;
|
||||||
|
|||||||
@@ -8,11 +8,11 @@
|
|||||||
|
|
||||||
-- DROP TABLE edit_language;
|
-- DROP TABLE edit_language;
|
||||||
CREATE TABLE edit_language (
|
CREATE TABLE edit_language (
|
||||||
edit_language_id SERIAL PRIMARY KEY,
|
edit_language_id INT GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
|
||||||
enabled SMALLINT NOT NULL DEFAULT 0,
|
enabled SMALLINT NOT NULL DEFAULT 0,
|
||||||
lang_default SMALLINT NOT NULL DEFAULT 0,
|
lang_default SMALLINT NOT NULL DEFAULT 0,
|
||||||
long_name VARCHAR,
|
long_name VARCHAR,
|
||||||
short_name VARCHAR, -- en_US, en or en_US@latin without encoding
|
short_name VARCHAR, -- en_US, en or en_US@latin without encoding
|
||||||
iso_name VARCHAR, -- should actually be encoding
|
iso_name VARCHAR, -- should actually be encoding
|
||||||
order_number INT
|
order_number INT
|
||||||
) INHERITS (edit_generic) WITHOUT OIDS;
|
) INHERITS (edit_generic) WITHOUT OIDS;
|
||||||
|
|||||||
@@ -7,35 +7,54 @@
|
|||||||
|
|
||||||
-- DROP TABLE edit_log;
|
-- DROP TABLE edit_log;
|
||||||
CREATE TABLE edit_log (
|
CREATE TABLE edit_log (
|
||||||
edit_log_id SERIAL PRIMARY KEY,
|
edit_log_id INT GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
|
||||||
euid INT, -- this is a foreign key, but I don't nedd to reference to it
|
euid INT, -- this is a foreign key, but I don't nedd to reference to it
|
||||||
FOREIGN KEY (euid) REFERENCES edit_user (edit_user_id) MATCH FULL ON UPDATE CASCADE ON DELETE SET NULL,
|
FOREIGN KEY (euid) REFERENCES edit_user (edit_user_id) MATCH FULL ON UPDATE CASCADE ON DELETE SET NULL,
|
||||||
username VARCHAR,
|
eucuid VARCHAR,
|
||||||
password VARCHAR,
|
eucuuid UUID, -- this is the one we want to use, full UUIDv4 from the edit user table
|
||||||
event_date TIMESTAMP WITHOUT TIME ZONE DEFAULT CURRENT_TIMESTAMP,
|
-- date_created equal, but can be overridden
|
||||||
ip VARCHAR,
|
event_date TIMESTAMP WITHOUT TIME ZONE DEFAULT CURRENT_TIMESTAMP,
|
||||||
error TEXT,
|
-- session ID if set
|
||||||
event TEXT,
|
session_id VARCHAR,
|
||||||
data_binary BYTEA,
|
-- username
|
||||||
data TEXT,
|
username VARCHAR,
|
||||||
page VARCHAR,
|
-- DEPRECATED [password]
|
||||||
action VARCHAR,
|
password VARCHAR,
|
||||||
action_id VARCHAR,
|
ip_address JSONB, -- REMOTE_IP and all other IPs (X_FORWARD, etc) as JSON block
|
||||||
action_yes VARCHAR,
|
-- DEPRECATED [ip]
|
||||||
action_flag VARCHAR,
|
ip VARCHAR, -- just the REMOTE_IP, full set see ip_address
|
||||||
action_menu VARCHAR,
|
-- string blocks, general
|
||||||
action_loaded VARCHAR,
|
error TEXT,
|
||||||
action_value VARCHAR,
|
event TEXT,
|
||||||
action_type VARCHAR,
|
-- bytea or string type storage of any data
|
||||||
action_error VARCHAR,
|
data_binary BYTEA,
|
||||||
user_agent VARCHAR,
|
data TEXT,
|
||||||
referer VARCHAR,
|
-- set page name only
|
||||||
script_name VARCHAR,
|
page VARCHAR,
|
||||||
query_string VARCHAR,
|
-- various info data sets
|
||||||
server_name VARCHAR,
|
user_agent VARCHAR,
|
||||||
http_host VARCHAR,
|
referer VARCHAR,
|
||||||
http_accept VARCHAR,
|
script_name VARCHAR,
|
||||||
http_accept_charset VARCHAR,
|
query_string VARCHAR,
|
||||||
http_accept_encoding VARCHAR,
|
request_scheme VARCHAR, -- http or https
|
||||||
session_id VARCHAR
|
server_name VARCHAR,
|
||||||
|
http_host VARCHAR,
|
||||||
|
http_data JSONB,
|
||||||
|
-- DEPRECATED [http*]
|
||||||
|
http_accept VARCHAR, -- in http_data
|
||||||
|
http_accept_charset VARCHAR, -- in http_data
|
||||||
|
http_accept_encoding VARCHAR, -- in http_data
|
||||||
|
-- any action var, -> same set in action_data as JSON
|
||||||
|
action_data JSONB,
|
||||||
|
-- DEPRECATED [action*]
|
||||||
|
action VARCHAR, -- in action_data
|
||||||
|
action_id VARCHAR, -- in action_data
|
||||||
|
action_sub_id VARCHAR, -- in action_data
|
||||||
|
action_yes VARCHAR, -- in action_data
|
||||||
|
action_flag VARCHAR, -- in action_data
|
||||||
|
action_menu VARCHAR, -- in action_data
|
||||||
|
action_loaded VARCHAR, -- in action_data
|
||||||
|
action_value VARCHAR, -- in action_data
|
||||||
|
action_type VARCHAR, -- in action_data
|
||||||
|
action_error VARCHAR -- in action_data
|
||||||
) INHERITS (edit_generic) WITHOUT OIDS;
|
) INHERITS (edit_generic) WITHOUT OIDS;
|
||||||
|
|||||||
@@ -7,10 +7,8 @@
|
|||||||
|
|
||||||
-- DROP TABLE edit_menu_group;
|
-- DROP TABLE edit_menu_group;
|
||||||
CREATE TABLE edit_menu_group (
|
CREATE TABLE edit_menu_group (
|
||||||
edit_menu_group_id SERIAL PRIMARY KEY,
|
edit_menu_group_id INT GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
|
||||||
name VARCHAR,
|
name VARCHAR,
|
||||||
flag VARCHAR,
|
flag VARCHAR,
|
||||||
order_number INT NOT NULL
|
order_number INT NOT NULL
|
||||||
) INHERITS (edit_generic) WITHOUT OIDS;
|
) INHERITS (edit_generic) WITHOUT OIDS;
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -7,16 +7,16 @@
|
|||||||
|
|
||||||
-- DROP TABLE edit_page;
|
-- DROP TABLE edit_page;
|
||||||
CREATE TABLE edit_page (
|
CREATE TABLE edit_page (
|
||||||
edit_page_id SERIAL PRIMARY KEY,
|
edit_page_id INT GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
|
||||||
content_alias_edit_page_id INT, -- alias for page content, if the page content is defined on a different page, ege for ajax backend pages
|
content_alias_edit_page_id INT, -- alias for page content, if the page content is defined on a different page, ege for ajax backend pages
|
||||||
FOREIGN KEY (content_alias_edit_page_id) REFERENCES edit_page (edit_page_id) MATCH FULL ON DELETE RESTRICT ON UPDATE CASCADE,
|
FOREIGN KEY (content_alias_edit_page_id) REFERENCES edit_page (edit_page_id) MATCH FULL ON DELETE RESTRICT ON UPDATE CASCADE,
|
||||||
filename VARCHAR,
|
filename VARCHAR,
|
||||||
name VARCHAR UNIQUE,
|
name VARCHAR UNIQUE,
|
||||||
order_number INT NOT NULL,
|
order_number INT NOT NULL,
|
||||||
online SMALLINT NOT NULL DEFAULT 0,
|
online SMALLINT NOT NULL DEFAULT 0,
|
||||||
menu SMALLINT NOT NULL DEFAULT 0,
|
menu SMALLINT NOT NULL DEFAULT 0,
|
||||||
popup SMALLINT NOT NULL DEFAULT 0,
|
popup SMALLINT NOT NULL DEFAULT 0,
|
||||||
popup_x SMALLINT,
|
popup_x SMALLINT,
|
||||||
popup_y SMALLINT,
|
popup_y SMALLINT,
|
||||||
hostname VARCHAR
|
hostname VARCHAR
|
||||||
) INHERITS (edit_generic) WITHOUT OIDS;
|
) INHERITS (edit_generic) WITHOUT OIDS;
|
||||||
|
|||||||
@@ -7,14 +7,12 @@
|
|||||||
|
|
||||||
-- DROP TABLE edit_page_access;
|
-- DROP TABLE edit_page_access;
|
||||||
CREATE TABLE edit_page_access (
|
CREATE TABLE edit_page_access (
|
||||||
edit_page_access_id SERIAL PRIMARY KEY,
|
edit_page_access_id INT GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
|
||||||
edit_group_id INT NOT NULL,
|
edit_group_id INT NOT NULL,
|
||||||
FOREIGN KEY (edit_group_id) REFERENCES edit_group (edit_group_id) MATCH FULL ON DELETE CASCADE ON UPDATE CASCADE,
|
FOREIGN KEY (edit_group_id) REFERENCES edit_group (edit_group_id) MATCH FULL ON DELETE CASCADE ON UPDATE CASCADE,
|
||||||
edit_page_id INT NOT NULL,
|
edit_page_id INT NOT NULL,
|
||||||
FOREIGN KEY (edit_page_id) REFERENCES edit_page (edit_page_id) MATCH FULL ON DELETE CASCADE ON UPDATE CASCADE,
|
FOREIGN KEY (edit_page_id) REFERENCES edit_page (edit_page_id) MATCH FULL ON DELETE CASCADE ON UPDATE CASCADE,
|
||||||
edit_access_right_id INT NOT NULL,
|
edit_access_right_id INT NOT NULL,
|
||||||
FOREIGN KEY (edit_access_right_id) REFERENCES edit_access_right (edit_access_right_id) MATCH FULL ON DELETE CASCADE ON UPDATE CASCADE,
|
FOREIGN KEY (edit_access_right_id) REFERENCES edit_access_right (edit_access_right_id) MATCH FULL ON DELETE CASCADE ON UPDATE CASCADE,
|
||||||
enabled SMALLINT NOT NULL DEFAULT 0
|
enabled SMALLINT NOT NULL DEFAULT 0
|
||||||
) INHERITS (edit_generic) WITHOUT OIDS;
|
) INHERITS (edit_generic) WITHOUT OIDS;
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -8,13 +8,13 @@
|
|||||||
|
|
||||||
-- DROP TABLE edit_page_content;
|
-- DROP TABLE edit_page_content;
|
||||||
CREATE TABLE edit_page_content (
|
CREATE TABLE edit_page_content (
|
||||||
edit_page_content_id SERIAL PRIMARY KEY,
|
edit_page_content_id INT GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
|
||||||
edit_page_id INT NOT NULL,
|
edit_page_id INT NOT NULL,
|
||||||
FOREIGN KEY (edit_page_id) REFERENCES edit_page (edit_page_id) MATCH FULL ON DELETE CASCADE ON UPDATE CASCADE,
|
FOREIGN KEY (edit_page_id) REFERENCES edit_page (edit_page_id) MATCH FULL ON DELETE CASCADE ON UPDATE CASCADE,
|
||||||
edit_access_right_id INT NOT NULL,
|
edit_access_right_id INT NOT NULL,
|
||||||
FOREIGN KEY (edit_access_right_id) REFERENCES edit_access_right (edit_access_right_id) MATCH FULL ON DELETE CASCADE ON UPDATE CASCADE,
|
FOREIGN KEY (edit_access_right_id) REFERENCES edit_access_right (edit_access_right_id) MATCH FULL ON DELETE CASCADE ON UPDATE CASCADE,
|
||||||
uid VARCHAR UNIQUE,
|
uid VARCHAR UNIQUE,
|
||||||
name VARCHAR,
|
name VARCHAR,
|
||||||
order_number INT NOT NULL,
|
order_number INT NOT NULL,
|
||||||
online SMALLINT NOT NULL DEFAULT 0
|
online SMALLINT NOT NULL DEFAULT 0
|
||||||
) INHERITS (edit_generic) WITHOUT OIDS;
|
) INHERITS (edit_generic) WITHOUT OIDS;
|
||||||
|
|||||||
@@ -7,8 +7,8 @@
|
|||||||
|
|
||||||
-- DROP TABLE edit_page_menu_group;
|
-- DROP TABLE edit_page_menu_group;
|
||||||
CREATE TABLE edit_page_menu_group (
|
CREATE TABLE edit_page_menu_group (
|
||||||
edit_page_id INT NOT NULL,
|
edit_page_id INT NOT NULL,
|
||||||
FOREIGN KEY (edit_page_id) REFERENCES edit_page (edit_page_id) MATCH FULL ON DELETE CASCADE ON UPDATE CASCADE,
|
FOREIGN KEY (edit_page_id) REFERENCES edit_page (edit_page_id) MATCH FULL ON DELETE CASCADE ON UPDATE CASCADE,
|
||||||
edit_menu_group_id INT NOT NULL,
|
edit_menu_group_id INT NOT NULL,
|
||||||
FOREIGN KEY (edit_menu_group_id) REFERENCES edit_menu_group (edit_menu_group_id) MATCH FULL ON DELETE CASCADE ON UPDATE CASCADE
|
FOREIGN KEY (edit_menu_group_id) REFERENCES edit_menu_group (edit_menu_group_id) MATCH FULL ON DELETE CASCADE ON UPDATE CASCADE
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -7,8 +7,8 @@
|
|||||||
|
|
||||||
-- DROP TABLE edit_page_visible_group;
|
-- DROP TABLE edit_page_visible_group;
|
||||||
CREATE TABLE edit_page_visible_group (
|
CREATE TABLE edit_page_visible_group (
|
||||||
edit_page_id INT NOT NULL,
|
edit_page_id INT NOT NULL,
|
||||||
FOREIGN KEY (edit_page_id) REFERENCES edit_page (edit_page_id) MATCH FULL ON DELETE CASCADE ON UPDATE CASCADE,
|
FOREIGN KEY (edit_page_id) REFERENCES edit_page (edit_page_id) MATCH FULL ON DELETE CASCADE ON UPDATE CASCADE,
|
||||||
edit_visible_group_id INT NOT NULL,
|
edit_visible_group_id INT NOT NULL,
|
||||||
FOREIGN KEY (edit_visible_group_id) REFERENCES edit_visible_group (edit_visible_group_id) MATCH FULL ON DELETE CASCADE ON UPDATE CASCADE
|
FOREIGN KEY (edit_visible_group_id) REFERENCES edit_visible_group (edit_visible_group_id) MATCH FULL ON DELETE CASCADE ON UPDATE CASCADE
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -7,11 +7,11 @@
|
|||||||
|
|
||||||
-- DROP TABLE edit_query_string;
|
-- DROP TABLE edit_query_string;
|
||||||
CREATE TABLE edit_query_string (
|
CREATE TABLE edit_query_string (
|
||||||
edit_query_string_id SERIAL PRIMARY KEY,
|
edit_query_string_id SERIAINT GENERATED ALWAYS AS IDENTITYL PRIMARY KEY,
|
||||||
edit_page_id INT NOT NULL,
|
edit_page_id INT NOT NULL,
|
||||||
FOREIGN KEY (edit_page_id) REFERENCES edit_page (edit_page_id) MATCH FULL ON DELETE CASCADE ON UPDATE CASCADE,
|
FOREIGN KEY (edit_page_id) REFERENCES edit_page (edit_page_id) MATCH FULL ON DELETE CASCADE ON UPDATE CASCADE,
|
||||||
enabled SMALLINT NOT NULL DEFAULT 0,
|
enabled SMALLINT NOT NULL DEFAULT 0,
|
||||||
name VARCHAR,
|
name VARCHAR,
|
||||||
value VARCHAR,
|
value VARCHAR,
|
||||||
dynamic SMALLINT NOT NULL DEFAULT 0
|
dynamic SMALLINT NOT NULL DEFAULT 0
|
||||||
) INHERITS (edit_generic) WITHOUT OIDS;
|
) INHERITS (edit_generic) WITHOUT OIDS;
|
||||||
|
|||||||
@@ -7,10 +7,10 @@
|
|||||||
|
|
||||||
-- DROP TABLE edit_scheme;
|
-- DROP TABLE edit_scheme;
|
||||||
CREATE TABLE edit_scheme (
|
CREATE TABLE edit_scheme (
|
||||||
edit_scheme_id SERIAL PRIMARY KEY,
|
edit_scheme_id INT GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
|
||||||
enabled SMALLINT NOT NULL DEFAULT 0,
|
enabled SMALLINT NOT NULL DEFAULT 0,
|
||||||
name VARCHAR,
|
name VARCHAR,
|
||||||
header_color VARCHAR,
|
header_color VARCHAR,
|
||||||
css_file VARCHAR,
|
css_file VARCHAR,
|
||||||
template VARCHAR
|
template VARCHAR
|
||||||
) INHERITS (edit_generic) WITHOUT OIDS;
|
) INHERITS (edit_generic) WITHOUT OIDS;
|
||||||
|
|||||||
@@ -7,6 +7,6 @@
|
|||||||
|
|
||||||
-- DROP TABLE temp_files;
|
-- DROP TABLE temp_files;
|
||||||
CREATE TABLE temp_files (
|
CREATE TABLE temp_files (
|
||||||
filename VARCHAR,
|
filename VARCHAR,
|
||||||
folder VARCHAR
|
folder VARCHAR
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -7,42 +7,91 @@
|
|||||||
|
|
||||||
-- DROP TABLE edit_user;
|
-- DROP TABLE edit_user;
|
||||||
CREATE TABLE edit_user (
|
CREATE TABLE edit_user (
|
||||||
edit_user_id SERIAL PRIMARY KEY,
|
edit_user_id INT GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
|
||||||
connect_edit_user_id INT, -- possible reference to other user
|
connect_edit_user_id INT, -- possible reference to other user
|
||||||
FOREIGN KEY (connect_edit_user_id) REFERENCES edit_user (edit_user_id) MATCH FULL ON DELETE CASCADE ON UPDATE CASCADE,
|
FOREIGN KEY (connect_edit_user_id) REFERENCES edit_user (edit_user_id) MATCH FULL ON DELETE CASCADE ON UPDATE CASCADE,
|
||||||
edit_language_id INT NOT NULL,
|
edit_language_id INT NOT NULL,
|
||||||
FOREIGN KEY (edit_language_id) REFERENCES edit_language (edit_language_id) MATCH FULL ON DELETE CASCADE ON UPDATE CASCADE,
|
FOREIGN KEY (edit_language_id) REFERENCES edit_language (edit_language_id) MATCH FULL ON DELETE CASCADE ON UPDATE CASCADE,
|
||||||
edit_group_id INT NOT NULL,
|
edit_group_id INT NOT NULL,
|
||||||
FOREIGN KEY (edit_group_id) REFERENCES edit_group (edit_group_id) MATCH FULL ON DELETE CASCADE ON UPDATE CASCADE,
|
FOREIGN KEY (edit_group_id) REFERENCES edit_group (edit_group_id) MATCH FULL ON DELETE CASCADE ON UPDATE CASCADE,
|
||||||
edit_scheme_id INT,
|
edit_scheme_id INT,
|
||||||
FOREIGN KEY (edit_scheme_id) REFERENCES edit_scheme (edit_scheme_id) MATCH FULL ON DELETE CASCADE ON UPDATE CASCADE,
|
FOREIGN KEY (edit_scheme_id) REFERENCES edit_scheme (edit_scheme_id) MATCH FULL ON DELETE CASCADE ON UPDATE CASCADE,
|
||||||
edit_access_right_id INT NOT NULL,
|
edit_access_right_id INT NOT NULL,
|
||||||
FOREIGN KEY (edit_access_right_id) REFERENCES edit_access_right (edit_access_right_id) MATCH FULL ON DELETE CASCADE ON UPDATE CASCADE,
|
FOREIGN KEY (edit_access_right_id) REFERENCES edit_access_right (edit_access_right_id) MATCH FULL ON DELETE CASCADE ON UPDATE CASCADE,
|
||||||
enabled SMALLINT NOT NULL DEFAULT 0,
|
-- username/password
|
||||||
deleted SMALLINT NOT NULL DEFAULT 0,
|
username VARCHAR UNIQUE,
|
||||||
username VARCHAR UNIQUE,
|
password VARCHAR,
|
||||||
password VARCHAR,
|
-- name block
|
||||||
first_name VARCHAR,
|
first_name VARCHAR,
|
||||||
last_name VARCHAR,
|
last_name VARCHAR,
|
||||||
first_name_furigana VARCHAR,
|
first_name_furigana VARCHAR,
|
||||||
last_name_furigana VARCHAR,
|
last_name_furigana VARCHAR,
|
||||||
debug SMALLINT NOT NULL DEFAULT 0,
|
-- email
|
||||||
db_debug SMALLINT NOT NULL DEFAULT 0,
|
email VARCHAR,
|
||||||
email VARCHAR,
|
-- eanbled/deleted flag
|
||||||
protected SMALLINT NOT NULL DEFAULT 0,
|
enabled SMALLINT NOT NULL DEFAULT 0,
|
||||||
admin SMALLINT NOT NULL DEFAULT 0,
|
deleted SMALLINT NOT NULL DEFAULT 0,
|
||||||
last_login TIMESTAMP WITHOUT TIME ZONE,
|
-- general flags
|
||||||
login_error_count INT DEFAULT 0,
|
strict SMALLINT DEFAULT 0,
|
||||||
login_error_date_last TIMESTAMP WITHOUT TIME ZONE,
|
locked SMALLINT DEFAULT 0,
|
||||||
login_error_date_first TIMESTAMP WITHOUT TIME ZONE,
|
protected SMALLINT NOT NULL DEFAULT 0,
|
||||||
strict SMALLINT DEFAULT 0,
|
-- is admin user
|
||||||
locked SMALLINT DEFAULT 0,
|
admin SMALLINT NOT NULL DEFAULT 0,
|
||||||
password_change_date TIMESTAMP WITHOUT TIME ZONE, -- only when password is first set or changed
|
-- force lgout counter
|
||||||
password_change_interval INTERVAL, -- null if no change is needed, or d/m/y time interval
|
force_logout INT DEFAULT 0,
|
||||||
password_reset_time TIMESTAMP WITHOUT TIME ZONE, -- when the password reset was requested
|
-- last login log
|
||||||
password_reset_uid VARCHAR, -- the uid to access the password reset page
|
last_login TIMESTAMP WITHOUT TIME ZONE,
|
||||||
additional_acl JSONB -- additional ACL as JSON string (can be set by other pages)
|
-- login error
|
||||||
|
login_error_count INT DEFAULT 0,
|
||||||
|
login_error_date_last TIMESTAMP WITHOUT TIME ZONE,
|
||||||
|
login_error_date_first TIMESTAMP WITHOUT TIME ZONE,
|
||||||
|
-- time locked
|
||||||
|
lock_until TIMESTAMP WITHOUT TIME ZONE,
|
||||||
|
lock_after TIMESTAMP WITHOUT TIME ZONE,
|
||||||
|
-- password change
|
||||||
|
password_change_date TIMESTAMP WITHOUT TIME ZONE, -- only when password is first set or changed
|
||||||
|
password_change_interval INTERVAL, -- null if no change is needed, or d/m/y time interval
|
||||||
|
password_reset_time TIMESTAMP WITHOUT TIME ZONE, -- when the password reset was requested
|
||||||
|
password_reset_uid VARCHAR, -- the uid to access the password reset page
|
||||||
|
-- _GET login id for direct login
|
||||||
|
login_user_id VARCHAR UNIQUE, -- the loginUserId, at least 32 chars
|
||||||
|
login_user_id_set_date TIMESTAMP WITHOUT TIME ZONE, -- when above uid was set
|
||||||
|
login_user_id_last_revalidate TIMESTAMP WITHOUT TIME ZONE, -- when the last login was done with user name and password
|
||||||
|
login_user_id_valid_from TIMESTAMP WITHOUT TIME ZONE, -- if set, from when the above uid is valid
|
||||||
|
login_user_id_valid_until TIMESTAMP WITHOUT TIME ZONE, -- if set, until when the above uid is valid
|
||||||
|
login_user_id_revalidate_after INTERVAL, -- user must login to revalidated loginUserId after set days, 0 for forever
|
||||||
|
login_user_id_locked SMALLINT DEFAULT 0, -- lock for loginUserId, but still allow normal login
|
||||||
|
-- additional ACL json block
|
||||||
|
additional_acl JSONB -- additional ACL as JSON string (can be set by other pages)
|
||||||
) INHERITS (edit_generic) WITHOUT OIDS;
|
) INHERITS (edit_generic) WITHOUT OIDS;
|
||||||
|
|
||||||
|
-- create unique index
|
||||||
|
-- CREATE UNIQUE INDEX edit_user_login_user_id_key ON edit_user (login_user_id) WHERE login_user_id IS NOT NULL;
|
||||||
|
|
||||||
|
COMMENT ON COLUMN edit_user.username IS 'Login username, must set';
|
||||||
|
COMMENT ON COLUMN edit_user.password IS 'Login password, must set';
|
||||||
|
COMMENT ON COLUMN edit_user.enabled IS 'Login is enabled (master switch)';
|
||||||
|
COMMENT ON COLUMN edit_user.deleted IS 'Login is deleted (master switch), overrides all other';
|
||||||
|
COMMENT ON COLUMN edit_user.strict IS 'If too many failed logins user will be locked, default off';
|
||||||
|
COMMENT ON COLUMN edit_user.locked IS 'Locked from too many wrong password logins';
|
||||||
|
COMMENT ON COLUMN edit_user.protected IS 'User can only be chnaged by admin user';
|
||||||
|
COMMENT ON COLUMN edit_user.admin IS 'If set, this user is SUPER admin';
|
||||||
|
COMMENT ON COLUMN edit_user.force_logout IS 'Counter for forced log out, if this one is higher than the session set one the session gets terminated';
|
||||||
|
COMMENT ON COLUMN edit_user.last_login IS 'Last succesfull login tiemstamp';
|
||||||
|
COMMENT ON COLUMN edit_user.login_error_count IS 'Number of failed logins, reset on successful login';
|
||||||
|
COMMENT ON COLUMN edit_user.login_error_date_last IS 'Last login error date';
|
||||||
|
COMMENT ON COLUMN edit_user.login_error_date_first IS 'First login error date, reset on successfull login';
|
||||||
|
COMMENT ON COLUMN edit_user.lock_until IS 'Account is locked until this date, <';
|
||||||
|
COMMENT ON COLUMN edit_user.lock_after IS 'Account is locked after this date, >';
|
||||||
|
COMMENT ON COLUMN edit_user.password_change_date IS 'Password was changed on';
|
||||||
|
COMMENT ON COLUMN edit_user.password_change_interval IS 'After how many days the password has to be changed';
|
||||||
COMMENT ON COLUMN edit_user.password_reset_time IS 'When the password reset was requested. For reset page uid valid check';
|
COMMENT ON COLUMN edit_user.password_reset_time IS 'When the password reset was requested. For reset page uid valid check';
|
||||||
COMMENT ON COLUMN edit_user.password_reset_uid IS 'Password reset page uid';
|
COMMENT ON COLUMN edit_user.password_reset_uid IS 'Password reset page uid, one time, invalid after reset successful or time out';
|
||||||
|
COMMENT ON COLUMN edit_user.login_user_id IS 'Min 32 character UID to be used to login without password. Via GET/POST parameter';
|
||||||
|
COMMENT ON COLUMN edit_user.login_user_id_set_date IS 'loginUserId was set at what date';
|
||||||
|
COMMENT ON COLUMN edit_user.login_user_id_last_revalidate IS 'set when username/password login is done and loginUserId is set';
|
||||||
|
COMMENT ON COLUMN edit_user.login_user_id_valid_from IS 'loginUserId is valid from this date, >=';
|
||||||
|
COMMENT ON COLUMN edit_user.login_user_id_valid_until IS 'loginUserId is valid until this date, <=';
|
||||||
|
COMMENT ON COLUMN edit_user.login_user_id_revalidate_after IS 'If set to a number greater 0 then user must login after given amount of days to revalidate the loginUserId, set to 0 for valid forver';
|
||||||
|
COMMENT ON COLUMN edit_user.login_user_id_locked IS 'A separte lock flag for loginUserId, user can still login normal';
|
||||||
|
COMMENT ON COLUMN edit_user.additional_acl IS 'Additional Access Control List stored in JSON format';
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
|
|
||||||
-- DROP TABLE edit_visible_group;
|
-- DROP TABLE edit_visible_group;
|
||||||
CREATE TABLE edit_visible_group (
|
CREATE TABLE edit_visible_group (
|
||||||
edit_visible_group_id SERIAL PRIMARY KEY,
|
edit_visible_group_id INT GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
|
||||||
name VARCHAR,
|
name VARCHAR,
|
||||||
flag VARCHAR
|
flag VARCHAR
|
||||||
) INHERITS (edit_generic) WITHOUT OIDS;
|
) INHERITS (edit_generic) WITHOUT OIDS;
|
||||||
|
|||||||
@@ -1,12 +1,14 @@
|
|||||||
-- AUTHOR: Clemens Schwaighofer
|
-- AUTHOR: Clemens Schwaighofer
|
||||||
-- DATE: 2005/07/05
|
-- DATE: 2005/07/05
|
||||||
-- DESCRIPTION:
|
-- DESCRIPTION:
|
||||||
-- cms tables; generic basic table
|
-- generic basic table with date and uid column
|
||||||
-- TABLE: generic
|
-- TABLE: generic
|
||||||
-- HISTORY:
|
-- HISTORY:
|
||||||
|
|
||||||
-- DROP TABLE edit_generic;
|
-- DROP TABLE generic;
|
||||||
CREATE TABLE generic (
|
CREATE TABLE generic (
|
||||||
date_created TIMESTAMP WITHOUT TIME ZONE DEFAULT clock_timestamp(),
|
date_created TIMESTAMP WITHOUT TIME ZONE DEFAULT clock_timestamp(),
|
||||||
date_updated TIMESTAMP WITHOUT TIME ZONE
|
date_updated TIMESTAMP WITHOUT TIME ZONE,
|
||||||
|
uuid UUID DEFAULT gen_random_uuid(),
|
||||||
|
uid VARCHAR
|
||||||
);
|
);
|
||||||
|
|||||||
81
4dev/database/tests/20220622-01.edit_user-table-updates.sql
Normal file
81
4dev/database/tests/20220622-01.edit_user-table-updates.sql
Normal file
@@ -0,0 +1,81 @@
|
|||||||
|
--
|
||||||
|
SELECT
|
||||||
|
eu.cuid, eu.username,
|
||||||
|
eu.lock_until, eu.lock_after,
|
||||||
|
CASE WHEN (
|
||||||
|
(eu.lock_until IS NULL
|
||||||
|
OR (eu.lock_until IS NOT NULL AND NOW() >= eu.lock_until))
|
||||||
|
AND (eu.lock_after IS NULL
|
||||||
|
OR (eu.lock_after IS NOT NULL AND NOW() <= eu.lock_after))
|
||||||
|
) THEN 0::INT ELSE 1::INT END locked_period
|
||||||
|
FROM edit_user eu
|
||||||
|
WHERE eu.username = 'empty';
|
||||||
|
|
||||||
|
UPDATE edit_user SET
|
||||||
|
lock_until = NOW() + '1 day'::interval
|
||||||
|
WHERE username = 'empty';
|
||||||
|
UPDATE edit_user SET
|
||||||
|
lock_after = NOW() - '1 day'::interval
|
||||||
|
WHERE username = 'empty';
|
||||||
|
|
||||||
|
|
||||||
|
UPDATE edit_user SET
|
||||||
|
lock_until = NOW() - '1 day'::interval
|
||||||
|
WHERE username = 'empty';
|
||||||
|
UPDATE edit_user SET
|
||||||
|
lock_after = NOW() + '1 day'::interval
|
||||||
|
WHERE username = 'empty';
|
||||||
|
|
||||||
|
UPDATE edit_user SET lock_until = NULL, lock_after = NULL WHERE username = 'empty';
|
||||||
|
|
||||||
|
--
|
||||||
|
SELECT
|
||||||
|
eu.cuid, eu.username,
|
||||||
|
eu.login_user_id, login_user_id_set_date, eu.login_user_id_last_revalidate,
|
||||||
|
(eu.login_user_id_last_revalidate + eu.login_user_id_revalidate_after)::DATE AS reval_date, NOW()::DATE,
|
||||||
|
eu.login_user_id_valid_from, eu.login_user_id_valid_until,
|
||||||
|
eu.login_user_id_revalidate_after,
|
||||||
|
CASE WHEN (
|
||||||
|
(eu.login_user_id_valid_from IS NULL
|
||||||
|
OR (eu.login_user_id_valid_from IS NOT NULL AND NOW() >= eu.login_user_id_valid_from))
|
||||||
|
AND (eu.login_user_id_valid_until IS NULL
|
||||||
|
OR (eu.login_user_id_valid_until IS NOT NULL AND NOW() <= eu.login_user_id_valid_until))
|
||||||
|
) THEN 1::INT ELSE 0::INT END AS login_user_id_valid_date,
|
||||||
|
CASE WHEN eu.login_user_id_revalidate_after IS NOT NULL
|
||||||
|
AND eu.login_user_id_revalidate_after > '0 days'::INTERVAL
|
||||||
|
AND (eu.login_user_id_last_revalidate + eu.login_user_id_revalidate_after)::DATE <= NOW()::DATE
|
||||||
|
THEN 1::INT ELSE 0::INT END AS login_user_id_revalidate
|
||||||
|
FROM edit_user eu
|
||||||
|
WHERE eu.username = 'empty';
|
||||||
|
|
||||||
|
-- init
|
||||||
|
UPDATE edit_user SET login_user_id = random_string(5) WHERE username = 'empty';
|
||||||
|
|
||||||
|
-- outside valid
|
||||||
|
UPDATE edit_user SET
|
||||||
|
login_user_id_valid_from = NOW() - '1 day'::interval
|
||||||
|
WHERE username = 'empty';
|
||||||
|
UPDATE edit_user SET
|
||||||
|
login_user_id_valid_until = NOW() + '1 day'::interval
|
||||||
|
WHERE username = 'empty';
|
||||||
|
-- inside valid
|
||||||
|
UPDATE edit_user SET
|
||||||
|
login_user_id_valid_from = NOW() + '1 day'::interval
|
||||||
|
WHERE username = 'empty';
|
||||||
|
UPDATE edit_user SET
|
||||||
|
login_user_id_valid_until = NOW() - '1 day'::interval
|
||||||
|
WHERE username = 'empty';
|
||||||
|
|
||||||
|
-- revalidate must
|
||||||
|
UPDATE edit_user SET
|
||||||
|
login_user_id_last_revalidate = NOW() - '1 day'::interval,
|
||||||
|
login_user_id_revalidate_after = '1 day'::interval
|
||||||
|
WHERE username = 'empty';
|
||||||
|
-- revalidate not yet
|
||||||
|
UPDATE edit_user SET
|
||||||
|
login_user_id_last_revalidate = NOW(),
|
||||||
|
login_user_id_revalidate_after = '6 day'::interval
|
||||||
|
WHERE username = 'empty';
|
||||||
|
|
||||||
|
|
||||||
|
UPDATE edit_user SET login_user_id_set_date = NULL, login_user_id_last_revalidate = NULL, login_user_id_valid_from = NULL, login_user_id_valid_until = NULL, login_user_id_revalidate_after = NULL WHERE username = 'empty';
|
||||||
@@ -1,9 +1,9 @@
|
|||||||
DROP TRIGGER IF EXISTS trg_edit_access ON edit_access;
|
-- DROP TRIGGER IF EXISTS trg_edit_access ON edit_access;
|
||||||
CREATE TRIGGER trg_edit_access
|
CREATE TRIGGER trg_edit_access
|
||||||
BEFORE INSERT OR UPDATE ON edit_access
|
BEFORE INSERT OR UPDATE ON edit_access
|
||||||
FOR EACH ROW EXECUTE PROCEDURE set_edit_generic();
|
FOR EACH ROW EXECUTE PROCEDURE set_edit_generic();
|
||||||
|
|
||||||
DROP TRIGGER IF EXISTS trg_set_edit_access_uid ON edit_access;
|
-- DROP TRIGGER IF EXISTS trg_set_edit_access_uid ON edit_access;
|
||||||
CREATE TRIGGER trg_set_edit_access_uid
|
CREATE TRIGGER trg_set_edit_access_uid
|
||||||
BEFORE INSERT OR UPDATE ON edit_access
|
BEFORE INSERT OR UPDATE ON edit_access
|
||||||
FOR EACH ROW EXECUTE PROCEDURE set_edit_access_uid();
|
FOR EACH ROW EXECUTE PROCEDURE set_edit_access_uid();
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
DROP TRIGGER IF EXISTS trg_edit_access_data ON edit_access_data;
|
-- DROP TRIGGER IF EXISTS trg_edit_access_data ON edit_access_data;
|
||||||
CREATE TRIGGER trg_edit_access_data
|
CREATE TRIGGER trg_edit_access_data
|
||||||
BEFORE INSERT OR UPDATE ON edit_access_data
|
BEFORE INSERT OR UPDATE ON edit_access_data
|
||||||
FOR EACH ROW EXECUTE PROCEDURE set_edit_generic();
|
FOR EACH ROW EXECUTE PROCEDURE set_edit_generic();
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
DROP TRIGGER IF EXISTS trg_edit_access_right ON edit_access_right;
|
-- DROP TRIGGER IF EXISTS trg_edit_access_right ON edit_access_right;
|
||||||
CREATE TRIGGER trg_edit_access_right
|
CREATE TRIGGER trg_edit_access_right
|
||||||
BEFORE INSERT OR UPDATE ON edit_access_right
|
BEFORE INSERT OR UPDATE ON edit_access_right
|
||||||
FOR EACH ROW EXECUTE PROCEDURE set_edit_generic();
|
FOR EACH ROW EXECUTE PROCEDURE set_edit_generic();
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
DROP TRIGGER IF EXISTS trg_edit_access_user ON edit_access_user;
|
-- DROP TRIGGER IF EXISTS trg_edit_access_user ON edit_access_user;
|
||||||
CREATE TRIGGER trg_edit_access_user
|
CREATE TRIGGER trg_edit_access_user
|
||||||
BEFORE INSERT OR UPDATE ON edit_access_user
|
BEFORE INSERT OR UPDATE ON edit_access_user
|
||||||
FOR EACH ROW EXECUTE PROCEDURE set_edit_generic();
|
FOR EACH ROW EXECUTE PROCEDURE set_edit_generic();
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
DROP TRIGGER IF EXISTS trg_edit_group ON edit_group;
|
-- DROP TRIGGER IF EXISTS trg_edit_group ON edit_group;
|
||||||
CREATE TRIGGER trg_edit_group
|
CREATE TRIGGER trg_edit_group
|
||||||
BEFORE INSERT OR UPDATE ON edit_group
|
BEFORE INSERT OR UPDATE ON edit_group
|
||||||
FOR EACH ROW EXECUTE PROCEDURE set_edit_generic();
|
FOR EACH ROW EXECUTE PROCEDURE set_edit_generic();
|
||||||
|
|
||||||
DROP TRIGGER IF EXISTS trg_set_edit_group_uid ON edit_group;
|
-- DROP TRIGGER IF EXISTS trg_set_edit_group_uid ON edit_group;
|
||||||
CREATE TRIGGER trg_set_edit_group_uid
|
CREATE TRIGGER trg_set_edit_group_uid
|
||||||
BEFORE INSERT OR UPDATE ON edit_group
|
BEFORE INSERT OR UPDATE ON edit_group
|
||||||
FOR EACH ROW EXECUTE PROCEDURE set_edit_group_uid();
|
FOR EACH ROW EXECUTE PROCEDURE set_edit_group_uid();
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
DROP TRIGGER IF EXISTS trg_edit_language ON edit_language;
|
-- DROP TRIGGER IF EXISTS trg_edit_language ON edit_language;
|
||||||
CREATE TRIGGER trg_edit_language
|
CREATE TRIGGER trg_edit_language
|
||||||
BEFORE INSERT OR UPDATE ON edit_language
|
BEFORE INSERT OR UPDATE ON edit_language
|
||||||
FOR EACH ROW EXECUTE PROCEDURE set_edit_generic();
|
FOR EACH ROW EXECUTE PROCEDURE set_edit_generic();
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
DROP TRIGGER IF EXISTS trg_edit_log ON edit_log;
|
-- DROP TRIGGER IF EXISTS trg_edit_log ON edit_log;
|
||||||
CREATE TRIGGER trg_edit_log
|
CREATE TRIGGER trg_edit_log
|
||||||
BEFORE INSERT OR UPDATE ON edit_log
|
BEFORE INSERT OR UPDATE ON edit_log
|
||||||
FOR EACH ROW EXECUTE PROCEDURE set_edit_generic();
|
FOR EACH ROW EXECUTE PROCEDURE set_edit_generic();
|
||||||
|
|
||||||
DROP TRIGGER IF EXISTS trg_edit_log_insert_partition ON edit_log;
|
-- DROP TRIGGER IF EXISTS trg_edit_log_insert_partition ON edit_log;
|
||||||
CREATE TRIGGER trg_edit_log_insert_partition
|
CREATE TRIGGER trg_edit_log_insert_partition
|
||||||
BEFORE INSERT OR UPDATE ON edit_log
|
BEFORE INSERT OR UPDATE ON edit_log
|
||||||
FOR EACH ROW EXECUTE PROCEDURE edit_log_insert_trigger();
|
FOR EACH ROW EXECUTE PROCEDURE edit_log_insert_trigger();
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
DROP TRIGGER IF EXISTS trg_edit_log_overflow ON edit_log_overflow;
|
-- DROP TRIGGER IF EXISTS trg_edit_log_overflow ON edit_log_overflow;
|
||||||
CREATE TRIGGER trg_edit_log_overflow
|
CREATE TRIGGER trg_edit_log_overflow
|
||||||
BEFORE INSERT OR UPDATE ON edit_log_overflow
|
BEFORE INSERT OR UPDATE ON edit_log_overflow
|
||||||
FOR EACH ROW EXECUTE PROCEDURE set_edit_generic();
|
FOR EACH ROW EXECUTE PROCEDURE set_edit_generic();
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
DROP TRIGGER IF EXISTS trg_edit_menu_group ON edit_menu_group;
|
-- DROP TRIGGER IF EXISTS trg_edit_menu_group ON edit_menu_group;
|
||||||
CREATE TRIGGER trg_edit_menu_group
|
CREATE TRIGGER trg_edit_menu_group
|
||||||
BEFORE INSERT OR UPDATE ON edit_menu_group
|
BEFORE INSERT OR UPDATE ON edit_menu_group
|
||||||
FOR EACH ROW EXECUTE PROCEDURE set_edit_generic();
|
FOR EACH ROW EXECUTE PROCEDURE set_edit_generic();
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
DROP TRIGGER IF EXISTS trg_edit_page ON edit_page;
|
-- DROP TRIGGER IF EXISTS trg_edit_page ON edit_page;
|
||||||
CREATE TRIGGER trg_edit_page
|
CREATE TRIGGER trg_edit_page
|
||||||
BEFORE INSERT OR UPDATE ON edit_page
|
BEFORE INSERT OR UPDATE ON edit_page
|
||||||
FOR EACH ROW EXECUTE PROCEDURE set_edit_generic();
|
FOR EACH ROW EXECUTE PROCEDURE set_edit_generic();
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
DROP TRIGGER IF EXISTS trg_edit_page_access ON edit_page_access;
|
-- DROP TRIGGER IF EXISTS trg_edit_page_access ON edit_page_access;
|
||||||
CREATE TRIGGER trg_edit_page_access
|
CREATE TRIGGER trg_edit_page_access
|
||||||
BEFORE INSERT OR UPDATE ON edit_page_access
|
BEFORE INSERT OR UPDATE ON edit_page_access
|
||||||
FOR EACH ROW EXECUTE PROCEDURE set_edit_generic();
|
FOR EACH ROW EXECUTE PROCEDURE set_edit_generic();
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
DROP TRIGGER IF EXISTS trg_edit_page_content ON edit_page_content;
|
-- DROP TRIGGER IF EXISTS trg_edit_page_content ON edit_page_content;
|
||||||
CREATE TRIGGER trg_edit_page_content
|
CREATE TRIGGER trg_edit_page_content
|
||||||
BEFORE INSERT OR UPDATE ON edit_page_content
|
BEFORE INSERT OR UPDATE ON edit_page_content
|
||||||
FOR EACH ROW EXECUTE PROCEDURE set_edit_generic();
|
FOR EACH ROW EXECUTE PROCEDURE set_edit_generic();
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
DROP TRIGGER IF EXISTS trg_edit_query_string ON edit_query_string;
|
-- DROP TRIGGER IF EXISTS trg_edit_query_string ON edit_query_string;
|
||||||
CREATE TRIGGER trg_edit_query_string
|
CREATE TRIGGER trg_edit_query_string
|
||||||
BEFORE INSERT OR UPDATE ON edit_query_string
|
BEFORE INSERT OR UPDATE ON edit_query_string
|
||||||
FOR EACH ROW EXECUTE PROCEDURE set_edit_generic();
|
FOR EACH ROW EXECUTE PROCEDURE set_edit_generic();
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
DROP TRIGGER IF EXISTS trg_edit_scheme ON edit_scheme;
|
-- DROP TRIGGER IF EXISTS trg_edit_scheme ON edit_scheme;
|
||||||
CREATE TRIGGER trg_edit_scheme
|
CREATE TRIGGER trg_edit_scheme
|
||||||
BEFORE INSERT OR UPDATE ON edit_scheme
|
BEFORE INSERT OR UPDATE ON edit_scheme
|
||||||
FOR EACH ROW EXECUTE PROCEDURE set_edit_generic();
|
FOR EACH ROW EXECUTE PROCEDURE set_edit_generic();
|
||||||
|
|||||||
@@ -1,4 +1,9 @@
|
|||||||
DROP TRIGGER IF EXISTS trg_edit_user ON edit_user;
|
-- DROP TRIGGER IF EXISTS trg_edit_user ON edit_user;
|
||||||
CREATE TRIGGER trg_edit_user
|
CREATE TRIGGER trg_edit_user
|
||||||
BEFORE INSERT OR UPDATE ON edit_user
|
BEFORE INSERT OR UPDATE ON edit_user
|
||||||
FOR EACH ROW EXECUTE PROCEDURE set_edit_generic();
|
FOR EACH ROW EXECUTE PROCEDURE set_edit_generic();
|
||||||
|
|
||||||
|
-- DROP TRIGGER IF EXISTS trg_edit_user_set_login_user_id_set_date ON edit_user;
|
||||||
|
CREATE TRIGGER trg_edit_user_set_login_user_id_set_date
|
||||||
|
BEFORE INSERT OR UPDATE ON edit_user
|
||||||
|
FOR EACH ROW EXECUTE PROCEDURE set_login_user_id_set_date();
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
DROP TRIGGER IF EXISTS trg_edit_visible_group ON edit_visible_group;
|
-- DROP TRIGGER IF EXISTS trg_edit_visible_group ON edit_visible_group;
|
||||||
CREATE TRIGGER trg_edit_visible_group
|
CREATE TRIGGER trg_edit_visible_group
|
||||||
BEFORE INSERT OR UPDATE ON edit_visible_group
|
BEFORE INSERT OR UPDATE ON edit_visible_group
|
||||||
FOR EACH ROW EXECUTE PROCEDURE set_edit_generic();
|
FOR EACH ROW EXECUTE PROCEDURE set_edit_generic();
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ declare(strict_types=1);
|
|||||||
* 1 for file loadable, but no data inside
|
* 1 for file loadable, but no data inside
|
||||||
* 2 for file not readable
|
* 2 for file not readable
|
||||||
* 3 for file not found
|
* 3 for file not found
|
||||||
* @deprecated V6 Use \CoreLibs\Get\ReadEnvFile::readEnvFile()
|
* @deprecated V6 Use \CoreLibs\Get\DotEnv::readEnvFile()
|
||||||
*/
|
*/
|
||||||
function readEnvFile(string $path = __DIR__, string $env_file = '.env'): int
|
function readEnvFile(string $path = __DIR__, string $env_file = '.env'): int
|
||||||
{
|
{
|
||||||
31
4dev/documentation/DB_Query_Params.md
Normal file
31
4dev/documentation/DB_Query_Params.md
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
# DB Query Params ? and : to $
|
||||||
|
|
||||||
|
dbReturn*
|
||||||
|
dbExec
|
||||||
|
|
||||||
|
keep
|
||||||
|
->query
|
||||||
|
->params
|
||||||
|
for reference
|
||||||
|
|
||||||
|
## : named params
|
||||||
|
|
||||||
|
in order for each named found replace with order number:
|
||||||
|
|
||||||
|
```txt
|
||||||
|
:name, :foo, :bar, :name =>
|
||||||
|
$1, $2, $3, $1
|
||||||
|
```
|
||||||
|
|
||||||
|
```php
|
||||||
|
$query = str_replace(
|
||||||
|
[':name', ':foo', ':bar'],
|
||||||
|
['$1', '$2', '$3'],
|
||||||
|
$query
|
||||||
|
);
|
||||||
|
```
|
||||||
|
|
||||||
|
## ? Params
|
||||||
|
|
||||||
|
Foreach ? set $1 to $n and store that in new params array
|
||||||
|
in QUERY for each ? replace with matching $n
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
#!/bin/bash
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
# create path
|
# create path
|
||||||
path=$(pwd)"/"$0;
|
path=$(pwd)"/"$0;
|
||||||
@@ -10,6 +10,11 @@ TARGET_HOST_WEB="<user>@<host>";
|
|||||||
TMP_DIR=$LOCAL_BASE_DIR"/4dev/tmp/";
|
TMP_DIR=$LOCAL_BASE_DIR"/4dev/tmp/";
|
||||||
tmpf_web=$TMP_DIR"sync.exclude.tmp";
|
tmpf_web=$TMP_DIR"sync.exclude.tmp";
|
||||||
|
|
||||||
|
if [ ! -d "$LOCAL_BASE_DIR" ]; then
|
||||||
|
echo "Folder: $LOCAL_BASE_DIR not found";
|
||||||
|
exit;
|
||||||
|
fi;
|
||||||
|
|
||||||
# if vendor be sure group folder is +x
|
# if vendor be sure group folder is +x
|
||||||
chmod -R ug+rX ${LOCAL_DIR}/vender/
|
chmod -R ug+rX ${LOCAL_DIR}/vender/
|
||||||
|
|
||||||
@@ -18,6 +23,7 @@ rm -f $tmpf_web;
|
|||||||
echo ".*.swp" >> $tmpf_web;
|
echo ".*.swp" >> $tmpf_web;
|
||||||
echo "._*" >> $tmpf_web;
|
echo "._*" >> $tmpf_web;
|
||||||
echo ".DS_Store" >> $tmpf_web;
|
echo ".DS_Store" >> $tmpf_web;
|
||||||
|
echo ".user.ini" >> $tmpf_web;
|
||||||
echo ".svn" >> $tmpf_web;
|
echo ".svn" >> $tmpf_web;
|
||||||
echo ".svnignore" >> $tmpf_web;
|
echo ".svnignore" >> $tmpf_web;
|
||||||
echo ".git" >> $tmpf_web;
|
echo ".git" >> $tmpf_web;
|
||||||
|
|||||||
40
4dev/tests/AAASetupData/CoreLibsAAASetupDataTest.php
Normal file
40
4dev/tests/AAASetupData/CoreLibsAAASetupDataTest.php
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace tests;
|
||||||
|
|
||||||
|
use PHPUnit\Framework\TestCase;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test base setup
|
||||||
|
* @testdox AAASetupData\AAASetupDataTest just setup BASE
|
||||||
|
*/
|
||||||
|
final class CoreLibsAAASetupDataTest extends TestCase
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Covers nothing
|
||||||
|
*
|
||||||
|
* @testdox Just setup BASE
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function testSetupData(): void
|
||||||
|
{
|
||||||
|
if (!defined('BASE')) {
|
||||||
|
define(
|
||||||
|
'BASE',
|
||||||
|
str_replace('/configs', '', __DIR__)
|
||||||
|
. DIRECTORY_SEPARATOR
|
||||||
|
);
|
||||||
|
}
|
||||||
|
$this->assertEquals(
|
||||||
|
str_replace('/configs', '', __DIR__)
|
||||||
|
. DIRECTORY_SEPARATOR,
|
||||||
|
BASE,
|
||||||
|
'BASE Path set check'
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// __END__
|
||||||
1
4dev/tests/AAASetupData/includes
Symbolic link
1
4dev/tests/AAASetupData/includes
Symbolic link
@@ -0,0 +1 @@
|
|||||||
|
../Language/includes/
|
||||||
1
4dev/tests/AAASetupData/log
Symbolic link
1
4dev/tests/AAASetupData/log
Symbolic link
@@ -0,0 +1 @@
|
|||||||
|
../Debug/log/
|
||||||
65
4dev/tests/AAASetupData/requests/http_requests.php
Normal file
65
4dev/tests/AAASetupData/requests/http_requests.php
Normal file
@@ -0,0 +1,65 @@
|
|||||||
|
<?php // phpcs:ignore PSR1.Files.SideEffects
|
||||||
|
|
||||||
|
/**
|
||||||
|
* AUTHOR: Clemens Schwaighofer
|
||||||
|
* CREATED: Ymd
|
||||||
|
* DESCRIPTION:
|
||||||
|
* DescriptionHere
|
||||||
|
*/
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* build return json
|
||||||
|
*
|
||||||
|
* @param array<string,mixed> $http_headers
|
||||||
|
* @param ?string $body
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
function buildContent(array $http_headers, ?string $body): string
|
||||||
|
{
|
||||||
|
if (is_string($body) && !empty($body)) {
|
||||||
|
$_body = json_decode($body, true);
|
||||||
|
if (!is_array($_body)) {
|
||||||
|
$body = [$body];
|
||||||
|
} else {
|
||||||
|
$body = $_body;
|
||||||
|
}
|
||||||
|
} elseif (is_string($body)) {
|
||||||
|
$body = [];
|
||||||
|
}
|
||||||
|
return json_encode([
|
||||||
|
'HEADERS' => $http_headers,
|
||||||
|
"REQUEST_TYPE" => $_SERVER['REQUEST_METHOD'],
|
||||||
|
"PARAMS" => $_GET,
|
||||||
|
"BODY" => $body,
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
$http_headers = array_filter($_SERVER, function ($value, $key) {
|
||||||
|
if (str_starts_with($key, 'HTTP_')) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}, ARRAY_FILTER_USE_BOTH);
|
||||||
|
|
||||||
|
header("Content-Type: application/json; charset=UTF-8");
|
||||||
|
|
||||||
|
// if the header has Authorization and RunAuthTest then exit with 401
|
||||||
|
if (!empty($http_headers['HTTP_AUTHORIZATION']) && !empty($http_headers['HTTP_RUNAUTHTEST'])) {
|
||||||
|
header("HTTP/1.1 401 Unauthorized");
|
||||||
|
print buildContent($http_headers, '{"code": 401, "content": {"Error": "Not Authorized"}}');
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// if server request type is get set file_get to null -> no body
|
||||||
|
if ($_SERVER['REQUEST_METHOD'] == "GET") {
|
||||||
|
$file_get = null;
|
||||||
|
} elseif (($file_get = file_get_contents('php://input')) === false) {
|
||||||
|
header("HTTP/1.1 404 Not Found");
|
||||||
|
print buildContent($http_headers, '{"code": 404, "content": {"Error": "file_get_contents failed"}}');
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
print buildContent($http_headers, $file_get);
|
||||||
|
|
||||||
|
// __END__
|
||||||
2260
4dev/tests/ACL/CoreLibsACLLoginTest.php
Normal file
2260
4dev/tests/ACL/CoreLibsACLLoginTest.php
Normal file
File diff suppressed because it is too large
Load Diff
52
4dev/tests/ACL/CoreLibsACLLogin_database_prepare.sh
Executable file
52
4dev/tests/ACL/CoreLibsACLLogin_database_prepare.sh
Executable file
@@ -0,0 +1,52 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
# note: there is currently no port selection, standard 5432 port is assumed
|
||||||
|
# note: we use the default in path postgresql commands and connect to whatever default DB is set
|
||||||
|
|
||||||
|
# PARAMETER 1: database data file to load
|
||||||
|
# PARAMETER 2: db user WHO MUST BE ABLE TO CREATE A DATABASE
|
||||||
|
# PARAMETER 3: db name
|
||||||
|
# PARAMETER 4: db host
|
||||||
|
# PARAMETER 5: print out for testing
|
||||||
|
|
||||||
|
load_sql="${1}";
|
||||||
|
# abort with 1 if we cannot find the file
|
||||||
|
if [ ! -f "${load_sql}" ]; then
|
||||||
|
echo 1;
|
||||||
|
exit 1;
|
||||||
|
fi;
|
||||||
|
db_user="${2}";
|
||||||
|
db_name="${3}";
|
||||||
|
db_host="${4}";
|
||||||
|
# empty db name or db user -> exit with 2
|
||||||
|
if [ -z "${db_user}" ] || [ -z "${db_name}" ] || [ -z "${db_host}" ]; then
|
||||||
|
echo 2;
|
||||||
|
exit 2;
|
||||||
|
fi;
|
||||||
|
# drop database, on error exit with 3
|
||||||
|
dropdb -U ${db_user} -h ${db_host} ${db_name} 2>&1;
|
||||||
|
if [ $? -ne 0 ]; then
|
||||||
|
echo 3;
|
||||||
|
exit 3;
|
||||||
|
fi;
|
||||||
|
# create database, on error exit with 4
|
||||||
|
createdb -U ${db_user} -O ${db_user} -h ${db_host} -E utf8 ${db_name} 2>&1;
|
||||||
|
if [ $? -ne 0 ]; then
|
||||||
|
echo 4;
|
||||||
|
exit 4;
|
||||||
|
fi;
|
||||||
|
# if error 5 thrown, test with enabled below
|
||||||
|
if [ ! -z "${5}" ]; then
|
||||||
|
psql -U ${db_user} -h ${db_host} -f ${load_sql} ${db_name};
|
||||||
|
else
|
||||||
|
# load data (redirect ALL error to null), on error exit with 5
|
||||||
|
psql -U ${db_user} -h ${db_host} -f ${load_sql} ${db_name} 2>&1 1>/dev/null 2>/dev/null;
|
||||||
|
fi;
|
||||||
|
if [ $? -ne 0 ]; then
|
||||||
|
echo 5;
|
||||||
|
exit 5;
|
||||||
|
fi;
|
||||||
|
echo 0;
|
||||||
|
exit 0;
|
||||||
|
|
||||||
|
# __END__
|
||||||
1049
4dev/tests/ACL/database/CoreLibsACLLogin_database_create_data.sql
Normal file
1049
4dev/tests/ACL/database/CoreLibsACLLogin_database_create_data.sql
Normal file
File diff suppressed because it is too large
Load Diff
1
4dev/tests/ACL/includes
Symbolic link
1
4dev/tests/ACL/includes
Symbolic link
@@ -0,0 +1 @@
|
|||||||
|
../AAASetupData/includes
|
||||||
47
4dev/tests/Admin/CoreLibsAdminEditPageTest.php
Normal file
47
4dev/tests/Admin/CoreLibsAdminEditPageTest.php
Normal file
@@ -0,0 +1,47 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace tests;
|
||||||
|
|
||||||
|
use PHPUnit\Framework\TestCase;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test class for Admin\EditPage
|
||||||
|
* @coversDefaultClass \CoreLibs\Admin\EditPage
|
||||||
|
* @testdox \CoreLibs\Admin\EditPage method tests
|
||||||
|
*/
|
||||||
|
final class CoreLibsAdminEditPageTest extends TestCase
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Undocumented function
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
protected function setUp(): void
|
||||||
|
{
|
||||||
|
if (!extension_loaded('pgsql')) {
|
||||||
|
$this->markTestSkipped(
|
||||||
|
'The PgSQL extension is not available.'
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Undocumented function
|
||||||
|
*
|
||||||
|
* @testdox Admin\EditPage Class tests
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function testAdminEditPage()
|
||||||
|
{
|
||||||
|
/* $this->assertTrue(true, 'ACL Login Tests not implemented');
|
||||||
|
$this->markTestIncomplete(
|
||||||
|
'ACL\Login Tests have not yet been implemented'
|
||||||
|
); */
|
||||||
|
$this->markTestSkipped('No implementation for Admin\EditPage at the moment');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// __END__
|
||||||
334
4dev/tests/Check/CoreLibsCheckColorsTest.php
Normal file
334
4dev/tests/Check/CoreLibsCheckColorsTest.php
Normal file
@@ -0,0 +1,334 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace tests;
|
||||||
|
|
||||||
|
use PHPUnit\Framework\TestCase;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test class for Check\Colors
|
||||||
|
* @coversDefaultClass \CoreLibs\Check\Colors
|
||||||
|
* @testdox \CoreLibs\Check\Colors method tests
|
||||||
|
*/
|
||||||
|
final class CoreLibsCheckColorsTest extends TestCase
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Undocumented function
|
||||||
|
*
|
||||||
|
* @return array<mixed>
|
||||||
|
*/
|
||||||
|
public function validateColorProvider(): array
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
0: input color string
|
||||||
|
1: flag (or flags to set)
|
||||||
|
2: expected result (bool)
|
||||||
|
*/
|
||||||
|
return [
|
||||||
|
// * hex
|
||||||
|
'valid hex rgb, flag ALL (default)' => [
|
||||||
|
'#ab12cd',
|
||||||
|
null,
|
||||||
|
true,
|
||||||
|
],
|
||||||
|
'valid hex rgb, flag ALL' => [
|
||||||
|
'#ab12cd',
|
||||||
|
\CoreLibs\Check\Colors::ALL,
|
||||||
|
true,
|
||||||
|
],
|
||||||
|
'valid hex rgb, flag HEX_RGB' => [
|
||||||
|
'#ab12cd',
|
||||||
|
\CoreLibs\Check\Colors::HEX_RGB,
|
||||||
|
true,
|
||||||
|
],
|
||||||
|
'valid hex rgb, wrong flag' => [
|
||||||
|
'#ab12cd',
|
||||||
|
\CoreLibs\Check\Colors::RGB,
|
||||||
|
false,
|
||||||
|
],
|
||||||
|
// error
|
||||||
|
'invalid hex rgb A' => [
|
||||||
|
'#ab12zz',
|
||||||
|
null,
|
||||||
|
false,
|
||||||
|
],
|
||||||
|
'invalid hex rgb B' => [
|
||||||
|
'#ZyQfo',
|
||||||
|
null,
|
||||||
|
false,
|
||||||
|
],
|
||||||
|
// other valid hex checks
|
||||||
|
'valid hex rgb, alt A' => [
|
||||||
|
'#AB12cd',
|
||||||
|
null,
|
||||||
|
true,
|
||||||
|
],
|
||||||
|
// * hax alpha
|
||||||
|
'valid hex rgb alpha, flag ALL (default)' => [
|
||||||
|
'#ab12cd12',
|
||||||
|
null,
|
||||||
|
true,
|
||||||
|
],
|
||||||
|
'valid hex rgb alpha, flag ALL' => [
|
||||||
|
'#ab12cd12',
|
||||||
|
\CoreLibs\Check\Colors::ALL,
|
||||||
|
true,
|
||||||
|
],
|
||||||
|
'valid hex rgb alpha, flag HEX_RGBA' => [
|
||||||
|
'#ab12cd12',
|
||||||
|
\CoreLibs\Check\Colors::HEX_RGBA,
|
||||||
|
true,
|
||||||
|
],
|
||||||
|
'valid hex rgb alpha, wrong flag' => [
|
||||||
|
'#ab12cd12',
|
||||||
|
\CoreLibs\Check\Colors::RGB,
|
||||||
|
false,
|
||||||
|
],
|
||||||
|
// error
|
||||||
|
'invalid hex rgb alpha A' => [
|
||||||
|
'#ab12dd1',
|
||||||
|
null,
|
||||||
|
false,
|
||||||
|
],
|
||||||
|
'invalid hex rgb alpha B' => [
|
||||||
|
'#ab12ddzz',
|
||||||
|
null,
|
||||||
|
false,
|
||||||
|
],
|
||||||
|
'valid hex rgb alpha, alt A' => [
|
||||||
|
'#ab12cdEE',
|
||||||
|
null,
|
||||||
|
true,
|
||||||
|
],
|
||||||
|
// * rgb
|
||||||
|
'valid rgb, flag ALL (default)' => [
|
||||||
|
'rgb(255, 10, 20)',
|
||||||
|
null,
|
||||||
|
true,
|
||||||
|
],
|
||||||
|
'valid rgb, flag ALL' => [
|
||||||
|
'rgb(255, 10, 20)',
|
||||||
|
\CoreLibs\Check\Colors::ALL,
|
||||||
|
true,
|
||||||
|
],
|
||||||
|
'valid rgb, flag RGB' => [
|
||||||
|
'rgb(255, 10, 20)',
|
||||||
|
\CoreLibs\Check\Colors::RGB,
|
||||||
|
true,
|
||||||
|
],
|
||||||
|
'valid rgb, wrong flag' => [
|
||||||
|
'rgb(255, 10, 20)',
|
||||||
|
\CoreLibs\Check\Colors::HEX_RGB,
|
||||||
|
false,
|
||||||
|
],
|
||||||
|
// error
|
||||||
|
'invalid rgb A' => [
|
||||||
|
'rgb(356, 10, 20)',
|
||||||
|
null,
|
||||||
|
false,
|
||||||
|
],
|
||||||
|
// other valid rgb conbinations
|
||||||
|
'valid rgb, alt A (percent)' => [
|
||||||
|
'rgb(100%, 10%, 20%)',
|
||||||
|
null,
|
||||||
|
true,
|
||||||
|
],
|
||||||
|
// TODO check all % and non percent combinations
|
||||||
|
'valid rgb, alt B (percent, mix)' => [
|
||||||
|
'rgb(100%, 10, 40)',
|
||||||
|
null,
|
||||||
|
true,
|
||||||
|
],
|
||||||
|
// * rgb alpha
|
||||||
|
'valid rgba, flag ALL (default)' => [
|
||||||
|
'rgba(255, 10, 20, 0.5)',
|
||||||
|
null,
|
||||||
|
true,
|
||||||
|
],
|
||||||
|
'valid rgba, flag ALL' => [
|
||||||
|
'rgba(255, 10, 20, 0.5)',
|
||||||
|
\CoreLibs\Check\Colors::ALL,
|
||||||
|
true,
|
||||||
|
],
|
||||||
|
'valid rgba, flag RGB' => [
|
||||||
|
'rgba(255, 10, 20, 0.5)',
|
||||||
|
\CoreLibs\Check\Colors::RGBA,
|
||||||
|
true,
|
||||||
|
],
|
||||||
|
'valid rgba, wrong flag' => [
|
||||||
|
'rgba(255, 10, 20, 0.5)',
|
||||||
|
\CoreLibs\Check\Colors::HEX_RGB,
|
||||||
|
false,
|
||||||
|
],
|
||||||
|
// error
|
||||||
|
'invalid rgba A' => [
|
||||||
|
'rgba(356, 10, 20, 0.5)',
|
||||||
|
null,
|
||||||
|
false,
|
||||||
|
],
|
||||||
|
// other valid rgba combinations
|
||||||
|
'valid rgba, alt A (percent)' => [
|
||||||
|
'rgba(100%, 10%, 20%, 0.5)',
|
||||||
|
null,
|
||||||
|
true,
|
||||||
|
],
|
||||||
|
// TODO check all % and non percent combinations
|
||||||
|
'valid rgba, alt B (percent, mix)' => [
|
||||||
|
'rgba(100%, 10, 40, 0.5)',
|
||||||
|
null,
|
||||||
|
true,
|
||||||
|
],
|
||||||
|
// TODO check all % and non percent combinations with percent transparent
|
||||||
|
'valid rgba, alt C (percent transparent)' => [
|
||||||
|
'rgba(100%, 10%, 20%, 50%)',
|
||||||
|
null,
|
||||||
|
true,
|
||||||
|
],
|
||||||
|
/*
|
||||||
|
// hsl
|
||||||
|
'hsl(100, 50%, 60%)',
|
||||||
|
'hsl(100, 50.5%, 60.5%)',
|
||||||
|
'hsla(100, 50%, 60%)',
|
||||||
|
'hsla(100, 50.5%, 60.5%)',
|
||||||
|
'hsla(100, 50%, 60%, 0.5)',
|
||||||
|
'hsla(100, 50.5%, 60.5%, 0.5)',
|
||||||
|
'hsla(100, 50%, 60%, 50%)',
|
||||||
|
'hsla(100, 50.5%, 60.5%, 50%)',
|
||||||
|
*/
|
||||||
|
// * hsl
|
||||||
|
'valid hsl, flag ALL (default)' => [
|
||||||
|
'hsl(100, 50%, 60%)',
|
||||||
|
null,
|
||||||
|
true,
|
||||||
|
],
|
||||||
|
'valid hsl, flag ALL' => [
|
||||||
|
'hsl(100, 50%, 60%)',
|
||||||
|
\CoreLibs\Check\Colors::ALL,
|
||||||
|
true,
|
||||||
|
],
|
||||||
|
'valid hsl, flag RGB' => [
|
||||||
|
'hsl(100, 50%, 60%)',
|
||||||
|
\CoreLibs\Check\Colors::HSL,
|
||||||
|
true,
|
||||||
|
],
|
||||||
|
'valid hsl, wrong flag' => [
|
||||||
|
'hsl(100, 50%, 60%)',
|
||||||
|
\CoreLibs\Check\Colors::HEX_RGB,
|
||||||
|
false,
|
||||||
|
],
|
||||||
|
'invalid hsl A' => [
|
||||||
|
'hsl(500, 50%, 60%)',
|
||||||
|
null,
|
||||||
|
false,
|
||||||
|
],
|
||||||
|
'valid hsl, alt A' => [
|
||||||
|
'hsl(100, 50.5%, 60.5%)',
|
||||||
|
null,
|
||||||
|
true,
|
||||||
|
],
|
||||||
|
// * hsl alpha
|
||||||
|
'valid hsla, flag ALL (default)' => [
|
||||||
|
'hsla(100, 50%, 60%, 0.5)',
|
||||||
|
null,
|
||||||
|
true,
|
||||||
|
],
|
||||||
|
'valid hsla, flag ALL' => [
|
||||||
|
'hsla(100, 50%, 60%, 0.5)',
|
||||||
|
\CoreLibs\Check\Colors::ALL,
|
||||||
|
true,
|
||||||
|
],
|
||||||
|
'valid hsla, flag RGB' => [
|
||||||
|
'hsla(100, 50%, 60%, 0.5)',
|
||||||
|
\CoreLibs\Check\Colors::HSLA,
|
||||||
|
true,
|
||||||
|
],
|
||||||
|
'valid hsla, wrong flag' => [
|
||||||
|
'hsla(100, 50%, 60%, 0.5)',
|
||||||
|
\CoreLibs\Check\Colors::HEX_RGB,
|
||||||
|
false,
|
||||||
|
],
|
||||||
|
'invalid hsla A' => [
|
||||||
|
'hsla(500, 50%, 60%, 0.5)',
|
||||||
|
null,
|
||||||
|
false,
|
||||||
|
],
|
||||||
|
'valid hsla, alt A (percent alpha' => [
|
||||||
|
'hsla(100, 50%, 60%, 50%)',
|
||||||
|
null,
|
||||||
|
true,
|
||||||
|
],
|
||||||
|
'valid hsla, alt A (percent alpha' => [
|
||||||
|
'hsla(100, 50.5%, 60.5%, 50%)',
|
||||||
|
null,
|
||||||
|
true,
|
||||||
|
],
|
||||||
|
// * combined flag checks
|
||||||
|
'valid rgb, flag RGB|RGBA' => [
|
||||||
|
'rgb(100%, 10%, 20%)',
|
||||||
|
\CoreLibs\Check\Colors::RGB | \CoreLibs\Check\Colors::RGBA,
|
||||||
|
true,
|
||||||
|
],
|
||||||
|
// TODO other combined flag checks all combinations
|
||||||
|
// * invalid string
|
||||||
|
'invalid string A' => [
|
||||||
|
'invalid string',
|
||||||
|
null,
|
||||||
|
false,
|
||||||
|
],
|
||||||
|
'invalid string B' => [
|
||||||
|
'(hsla(100, 100, 100))',
|
||||||
|
null,
|
||||||
|
false,
|
||||||
|
],
|
||||||
|
'invalid string C' => [
|
||||||
|
'hsla(100, 100, 100',
|
||||||
|
null,
|
||||||
|
false,
|
||||||
|
],
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Undocumented function
|
||||||
|
*
|
||||||
|
* @covers ::validateColor
|
||||||
|
* @dataProvider validateColorProvider
|
||||||
|
* @testdox validateColor $input with flags $flags be $expected [$_dataName]
|
||||||
|
*
|
||||||
|
* @param string $input
|
||||||
|
* @param int|null $flags
|
||||||
|
* @param bool $expected
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function testValidateColor(string $input, ?int $flags, bool $expected)
|
||||||
|
{
|
||||||
|
if ($flags === null) {
|
||||||
|
$result = \CoreLibs\Check\Colors::validateColor($input);
|
||||||
|
} else {
|
||||||
|
$result = \CoreLibs\Check\Colors::validateColor($input, $flags);
|
||||||
|
}
|
||||||
|
$this->assertEquals(
|
||||||
|
$expected,
|
||||||
|
$result
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Undocumented function
|
||||||
|
*
|
||||||
|
* @covers ::validateColor
|
||||||
|
* @testWith [99]
|
||||||
|
* @testdox Check Exception throw for $flag
|
||||||
|
*
|
||||||
|
* @param int $flag
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function testValidateColorException(int $flag): void
|
||||||
|
{
|
||||||
|
$this->expectException(\UnexpectedValueException::class);
|
||||||
|
\CoreLibs\Check\Colors::validateColor('#ffffff', $flag);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// __END__
|
||||||
@@ -24,12 +24,12 @@ final class CoreLibsCheckEmailTest extends TestCase
|
|||||||
'get email regex invalid -1, will be 0' => [
|
'get email regex invalid -1, will be 0' => [
|
||||||
-1,
|
-1,
|
||||||
"^[A-Za-z0-9!#$%&'*+\-\/=?^_`{|}~][A-Za-z0-9!#$%:\(\)&'*+\-\/=?^_`{|}~\.]{0,63}@"
|
"^[A-Za-z0-9!#$%&'*+\-\/=?^_`{|}~][A-Za-z0-9!#$%:\(\)&'*+\-\/=?^_`{|}~\.]{0,63}@"
|
||||||
. "[a-zA-Z0-9\-]+(\.[a-zA-Z0-9\-]{1,})*\.([a-zA-Z]{2,}){1}$"
|
. "(?!-)[A-Za-z0-9-]{1,63}(?<!-)(?:\.[A-Za-z0-9-]{1,63}(?<!-))*\.[a-zA-Z]{2,6}$"
|
||||||
],
|
],
|
||||||
'get email regex invalid 10, will be 0' => [
|
'get email regex invalid 10, will be 0' => [
|
||||||
10,
|
10,
|
||||||
"^[A-Za-z0-9!#$%&'*+\-\/=?^_`{|}~][A-Za-z0-9!#$%:\(\)&'*+\-\/=?^_`{|}~\.]{0,63}@"
|
"^[A-Za-z0-9!#$%&'*+\-\/=?^_`{|}~][A-Za-z0-9!#$%:\(\)&'*+\-\/=?^_`{|}~\.]{0,63}@"
|
||||||
. "[a-zA-Z0-9\-]+(\.[a-zA-Z0-9\-]{1,})*\.([a-zA-Z]{2,}){1}$"
|
. "(?!-)[A-Za-z0-9-]{1,63}(?<!-)(?:\.[A-Za-z0-9-]{1,63}(?<!-))*\.[a-zA-Z]{2,6}$"
|
||||||
],
|
],
|
||||||
'get email regex valid 1, will be 1' => [
|
'get email regex valid 1, will be 1' => [
|
||||||
1,
|
1,
|
||||||
@@ -157,7 +157,7 @@ final class CoreLibsCheckEmailTest extends TestCase
|
|||||||
'error' => 0,
|
'error' => 0,
|
||||||
'message' => 'Invalid email address',
|
'message' => 'Invalid email address',
|
||||||
'regex' => "^[A-Za-z0-9!#$%&'*+\-\/=?^_`{|}~][A-Za-z0-9!#$%:\(\)&'*+\-\/=?^_`{|}~\.]{0,63}@"
|
'regex' => "^[A-Za-z0-9!#$%&'*+\-\/=?^_`{|}~][A-Za-z0-9!#$%:\(\)&'*+\-\/=?^_`{|}~\.]{0,63}@"
|
||||||
. "[a-zA-Z0-9\-]+(\.[a-zA-Z0-9\-]{1,})*\.([a-zA-Z]{2,}){1}$"
|
. "(?!-)[A-Za-z0-9-]{1,63}(?<!-)(?:\.[A-Za-z0-9-]{1,63}(?<!-))*\.[a-zA-Z]{2,6}$"
|
||||||
]
|
]
|
||||||
],
|
],
|
||||||
'error 1 will return double @ error' => [
|
'error 1 will return double @ error' => [
|
||||||
@@ -181,7 +181,7 @@ final class CoreLibsCheckEmailTest extends TestCase
|
|||||||
[
|
[
|
||||||
'error' => 3,
|
'error' => 3,
|
||||||
'message' => 'Invalid domain part after @ sign',
|
'message' => 'Invalid domain part after @ sign',
|
||||||
'regex' => "@[a-zA-Z0-9-]+(\.[a-zA-Z0-9-]{1,})*\.([a-zA-Z]{2,}){1}$"
|
'regex' => "@(?!-)[A-Za-z0-9-]{1,63}(?<!-)(?:\.[A-Za-z0-9-]{1,63}(?<!-))*\.[a-zA-Z]{2,6}$"
|
||||||
]
|
]
|
||||||
],
|
],
|
||||||
'error 4 will be invalid domain' => [
|
'error 4 will be invalid domain' => [
|
||||||
@@ -189,7 +189,7 @@ final class CoreLibsCheckEmailTest extends TestCase
|
|||||||
[
|
[
|
||||||
'error' => 4,
|
'error' => 4,
|
||||||
'message' => 'Invalid domain name part',
|
'message' => 'Invalid domain name part',
|
||||||
'regex' => "@[a-zA-Z0-9-]+(\.[a-zA-Z0-9-]{1,})*\."
|
'regex' => "@(?!-)[A-Za-z0-9-]{1,63}(?<!-)(?:\.[A-Za-z0-9-]{1,63}(?<!-))*\."
|
||||||
]
|
]
|
||||||
],
|
],
|
||||||
'error 5 will be invalid domain top level only' => [
|
'error 5 will be invalid domain top level only' => [
|
||||||
@@ -197,7 +197,7 @@ final class CoreLibsCheckEmailTest extends TestCase
|
|||||||
[
|
[
|
||||||
'error' => 5,
|
'error' => 5,
|
||||||
'message' => 'Wrong domain top level part',
|
'message' => 'Wrong domain top level part',
|
||||||
'regex' => "\.([a-zA-Z]{2,6}){1}$"
|
'regex' => "\.[a-zA-Z]{2,6}$"
|
||||||
]
|
]
|
||||||
],
|
],
|
||||||
'error 6 will be domain double dot' => [
|
'error 6 will be domain double dot' => [
|
||||||
@@ -92,6 +92,7 @@ final class CoreLibsCheckEncodingTest extends TestCase
|
|||||||
$error_char,
|
$error_char,
|
||||||
$expected
|
$expected
|
||||||
): void {
|
): void {
|
||||||
|
$current_subsitute_character = mb_substitute_character();
|
||||||
if ($error_char !== null) {
|
if ($error_char !== null) {
|
||||||
\CoreLibs\Check\Encoding::setErrorChar($error_char);
|
\CoreLibs\Check\Encoding::setErrorChar($error_char);
|
||||||
if (!in_array($error_char, ['none', 'long', 'entity'])) {
|
if (!in_array($error_char, ['none', 'long', 'entity'])) {
|
||||||
@@ -111,6 +112,8 @@ final class CoreLibsCheckEncodingTest extends TestCase
|
|||||||
$expected,
|
$expected,
|
||||||
$return
|
$return
|
||||||
);
|
);
|
||||||
|
// reset after test
|
||||||
|
mb_substitute_character($current_subsitute_character);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -28,10 +28,10 @@ final class CoreLibsCheckFileTest extends TestCase
|
|||||||
public function filesList(): array
|
public function filesList(): array
|
||||||
{
|
{
|
||||||
return [
|
return [
|
||||||
['filename.txt', 'txt', 5],
|
['filename.txt', 'txt', 5, 'text/plain'],
|
||||||
['filename.csv', 'csv', 15],
|
['filename.csv', 'csv', 15, 'text/csv'],
|
||||||
['filename.tsv', 'tsv', 0],
|
['filename.tsv', 'tsv', 0, 'text/plain'],
|
||||||
['file_does_not_exits', '', -1],
|
['file_does_not_exits', '', -1, ''],
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -63,6 +63,15 @@ final class CoreLibsCheckFileTest extends TestCase
|
|||||||
return $list;
|
return $list;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function mimeTypeProvider(): array
|
||||||
|
{
|
||||||
|
$list = [];
|
||||||
|
foreach ($this->filesList() as $row) {
|
||||||
|
$list[$row[0] . ' must be mime type ' . $row[3]] = [$row[0], $row[3]];
|
||||||
|
}
|
||||||
|
return $list;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tests if file extension matches
|
* Tests if file extension matches
|
||||||
*
|
*
|
||||||
@@ -115,6 +124,51 @@ final class CoreLibsCheckFileTest extends TestCase
|
|||||||
unlink($this->base_folder . $input);
|
unlink($this->base_folder . $input);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Undocumented function
|
||||||
|
*
|
||||||
|
* @covers ::getMimeType
|
||||||
|
* @dataProvider mimeTypeProvider
|
||||||
|
* @testdox getMimeType $input must be mime type $expected [$_dataName]
|
||||||
|
*
|
||||||
|
* @param string $input
|
||||||
|
* @param string $expected
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function testGetMimeType(string $input, string $expected): void
|
||||||
|
{
|
||||||
|
if (!empty($expected)) {
|
||||||
|
$file = $this->base_folder . $input;
|
||||||
|
$fp = fopen($file, 'w');
|
||||||
|
switch ($expected) {
|
||||||
|
case 'text/csv':
|
||||||
|
for ($i = 1; $i <= 10; $i++) {
|
||||||
|
fwrite($fp, '"This is row","' . $expected . '",' . $i . PHP_EOL);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 'text/tsv':
|
||||||
|
for ($i = 1; $i <= 10; $i++) {
|
||||||
|
fwrite($fp, "\"This is row\"\t\"" . $expected . "\"\t\"" . $i . PHP_EOL);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 'text/plain':
|
||||||
|
fwrite($fp, 'This is mime type: ' . $expected . PHP_EOL);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
fclose($fp);
|
||||||
|
} else {
|
||||||
|
$this->expectException(\UnexpectedValueException::class);
|
||||||
|
}
|
||||||
|
$this->assertEquals(
|
||||||
|
$expected,
|
||||||
|
\CoreLibs\Check\File::getMimeType($this->base_folder . $input)
|
||||||
|
);
|
||||||
|
// unlink file
|
||||||
|
if (is_file($this->base_folder . $input)) {
|
||||||
|
unlink($this->base_folder . $input);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// __END__
|
// __END__
|
||||||
@@ -0,0 +1,404 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
// This code was created by Claude Sonnet 4
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace tests;
|
||||||
|
|
||||||
|
use PHPUnit\Framework\TestCase;
|
||||||
|
use CoreLibs\Combined\ArrayHandler;
|
||||||
|
|
||||||
|
class CoreLibsCombinedArrayHandlerFindArraysMissingKeyTest extends TestCase
|
||||||
|
{
|
||||||
|
private const DATA_SEPARATOR = ':'; // Updated to match your class's separator
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test finding missing single key when searching by value without specific key
|
||||||
|
*/
|
||||||
|
public function testFindMissingSingleKeyWithValueSearch()
|
||||||
|
{
|
||||||
|
$array = [
|
||||||
|
'item1' => [
|
||||||
|
'name' => 'John',
|
||||||
|
'age' => 25
|
||||||
|
// missing 'email' key
|
||||||
|
],
|
||||||
|
'item2' => [
|
||||||
|
'name' => 'Jane',
|
||||||
|
'age' => 30,
|
||||||
|
'email' => 'jane@example.com'
|
||||||
|
],
|
||||||
|
'item3' => [
|
||||||
|
'name' => 'John', // same value as item1
|
||||||
|
'age' => 35,
|
||||||
|
'email' => 'john2@example.com'
|
||||||
|
]
|
||||||
|
];
|
||||||
|
|
||||||
|
$result = ArrayHandler::findArraysMissingKey($array, 'John', 'email');
|
||||||
|
|
||||||
|
$this->assertCount(1, $result);
|
||||||
|
$this->assertEquals($array['item1'], $result[0]['content']);
|
||||||
|
$this->assertEquals('item1', $result[0]['path']);
|
||||||
|
$this->assertEquals(['email'], $result[0]['missing_key']);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test finding missing single key when searching by specific key-value pair
|
||||||
|
*/
|
||||||
|
public function testFindMissingSingleKeyWithKeyValueSearch()
|
||||||
|
{
|
||||||
|
$array = [
|
||||||
|
'user1' => [
|
||||||
|
'id' => 1,
|
||||||
|
'name' => 'Alice'
|
||||||
|
// missing 'status' key
|
||||||
|
],
|
||||||
|
'user2' => [
|
||||||
|
'id' => 2,
|
||||||
|
'name' => 'Bob',
|
||||||
|
'status' => 'active'
|
||||||
|
],
|
||||||
|
'user3' => [
|
||||||
|
'id' => 1, // same id as user1
|
||||||
|
'name' => 'Charlie',
|
||||||
|
'status' => 'inactive'
|
||||||
|
]
|
||||||
|
];
|
||||||
|
|
||||||
|
$result = ArrayHandler::findArraysMissingKey($array, 1, 'status', 'id');
|
||||||
|
|
||||||
|
$this->assertCount(1, $result);
|
||||||
|
$this->assertEquals($array['user1'], $result[0]['content']);
|
||||||
|
$this->assertEquals('user1', $result[0]['path']);
|
||||||
|
$this->assertEquals(['status'], $result[0]['missing_key']);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test finding missing multiple keys
|
||||||
|
*/
|
||||||
|
public function testFindMissingMultipleKeys()
|
||||||
|
{
|
||||||
|
$array = [
|
||||||
|
'record1' => [
|
||||||
|
'name' => 'Test',
|
||||||
|
'value' => 100
|
||||||
|
// missing both 'date' and 'status' keys
|
||||||
|
],
|
||||||
|
'record2' => [
|
||||||
|
'name' => 'Test',
|
||||||
|
'value' => 200,
|
||||||
|
'date' => '2023-01-01'
|
||||||
|
// missing 'status' key
|
||||||
|
],
|
||||||
|
'record3' => [
|
||||||
|
'name' => 'Test',
|
||||||
|
'value' => 300,
|
||||||
|
'date' => '2023-01-02',
|
||||||
|
'status' => 'complete'
|
||||||
|
]
|
||||||
|
];
|
||||||
|
|
||||||
|
$result = ArrayHandler::findArraysMissingKey($array, 'Test', ['date', 'status']);
|
||||||
|
|
||||||
|
$this->assertCount(2, $result);
|
||||||
|
|
||||||
|
// First result should be record1 missing both keys
|
||||||
|
$this->assertEquals($array['record1'], $result[0]['content']);
|
||||||
|
$this->assertEquals('record1', $result[0]['path']);
|
||||||
|
$this->assertContains('date', $result[0]['missing_key']);
|
||||||
|
$this->assertContains('status', $result[0]['missing_key']);
|
||||||
|
$this->assertCount(2, $result[0]['missing_key']);
|
||||||
|
|
||||||
|
// Second result should be record2 missing status key
|
||||||
|
$this->assertEquals($array['record2'], $result[1]['content']);
|
||||||
|
$this->assertEquals('record2', $result[1]['path']);
|
||||||
|
$this->assertEquals(['status'], $result[1]['missing_key']);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test with nested arrays
|
||||||
|
*/
|
||||||
|
public function testFindMissingKeyInNestedArrays()
|
||||||
|
{
|
||||||
|
$array = [
|
||||||
|
'section1' => [
|
||||||
|
'items' => [
|
||||||
|
'item1' => [
|
||||||
|
'name' => 'Product A',
|
||||||
|
'price' => 99.99
|
||||||
|
// missing 'category' key
|
||||||
|
],
|
||||||
|
'item2' => [
|
||||||
|
'name' => 'Product B',
|
||||||
|
'price' => 149.99,
|
||||||
|
'category' => 'electronics'
|
||||||
|
]
|
||||||
|
]
|
||||||
|
],
|
||||||
|
'section2' => [
|
||||||
|
'data' => [
|
||||||
|
'name' => 'Product A', // same name as nested item
|
||||||
|
'category' => 'books'
|
||||||
|
]
|
||||||
|
]
|
||||||
|
];
|
||||||
|
|
||||||
|
$result = ArrayHandler::findArraysMissingKey($array, 'Product A', 'category');
|
||||||
|
|
||||||
|
$this->assertCount(1, $result);
|
||||||
|
$this->assertEquals($array['section1']['items']['item1'], $result[0]['content']);
|
||||||
|
$this->assertEquals('section1:items:item1', $result[0]['path']);
|
||||||
|
$this->assertEquals(['category'], $result[0]['missing_key']);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test when no arrays are missing the required key
|
||||||
|
*/
|
||||||
|
public function testNoMissingKeys()
|
||||||
|
{
|
||||||
|
$array = [
|
||||||
|
'item1' => [
|
||||||
|
'name' => 'John',
|
||||||
|
'email' => 'john@example.com'
|
||||||
|
],
|
||||||
|
'item2' => [
|
||||||
|
'name' => 'Jane',
|
||||||
|
'email' => 'jane@example.com'
|
||||||
|
]
|
||||||
|
];
|
||||||
|
|
||||||
|
$result = ArrayHandler::findArraysMissingKey($array, 'John', 'email');
|
||||||
|
|
||||||
|
$this->assertEmpty($result);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test when search value is not found in any array
|
||||||
|
*/
|
||||||
|
public function testSearchValueNotFound()
|
||||||
|
{
|
||||||
|
$array = [
|
||||||
|
'item1' => [
|
||||||
|
'name' => 'John',
|
||||||
|
'age' => 25
|
||||||
|
],
|
||||||
|
'item2' => [
|
||||||
|
'name' => 'Jane',
|
||||||
|
'age' => 30
|
||||||
|
]
|
||||||
|
];
|
||||||
|
|
||||||
|
$result = ArrayHandler::findArraysMissingKey($array, 'Bob', 'email');
|
||||||
|
|
||||||
|
$this->assertEmpty($result);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test with different data types for search value
|
||||||
|
*/
|
||||||
|
public function testDifferentSearchValueTypes()
|
||||||
|
{
|
||||||
|
$array = [
|
||||||
|
'item1' => [
|
||||||
|
'active' => true,
|
||||||
|
'count' => 5
|
||||||
|
// missing 'label' key
|
||||||
|
],
|
||||||
|
'item2' => [
|
||||||
|
'active' => false,
|
||||||
|
'count' => 10,
|
||||||
|
'label' => 'test'
|
||||||
|
],
|
||||||
|
'item3' => [
|
||||||
|
'active' => true, // same boolean as item1
|
||||||
|
'count' => 15,
|
||||||
|
'label' => 'another'
|
||||||
|
]
|
||||||
|
];
|
||||||
|
|
||||||
|
// Test with boolean
|
||||||
|
$result = ArrayHandler::findArraysMissingKey($array, true, 'label', 'active');
|
||||||
|
$this->assertCount(1, $result);
|
||||||
|
$this->assertEquals('item1', $result[0]['path']);
|
||||||
|
|
||||||
|
// Test with integer
|
||||||
|
$result = ArrayHandler::findArraysMissingKey($array, 5, 'label', 'count');
|
||||||
|
$this->assertCount(1, $result);
|
||||||
|
$this->assertEquals('item1', $result[0]['path']);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test with empty array
|
||||||
|
*/
|
||||||
|
public function testEmptyArray()
|
||||||
|
{
|
||||||
|
$array = [];
|
||||||
|
|
||||||
|
$result = ArrayHandler::findArraysMissingKey($array, 'test', 'key');
|
||||||
|
|
||||||
|
$this->assertEmpty($result);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test with array containing non-array values
|
||||||
|
*/
|
||||||
|
public function testMixedArrayTypes()
|
||||||
|
{
|
||||||
|
$array = [
|
||||||
|
'string_value' => 'hello',
|
||||||
|
'numeric_value' => 123,
|
||||||
|
'array_value' => [
|
||||||
|
'name' => 'test',
|
||||||
|
// missing 'type' key
|
||||||
|
],
|
||||||
|
'another_array' => [
|
||||||
|
'name' => 'test',
|
||||||
|
'type' => 'example'
|
||||||
|
]
|
||||||
|
];
|
||||||
|
|
||||||
|
$result = ArrayHandler::findArraysMissingKey($array, 'test', 'type');
|
||||||
|
|
||||||
|
$this->assertCount(1, $result);
|
||||||
|
$this->assertEquals($array['array_value'], $result[0]['content']);
|
||||||
|
$this->assertEquals('array_value', $result[0]['path']);
|
||||||
|
$this->assertEquals(['type'], $result[0]['missing_key']);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test path building with deeper nesting
|
||||||
|
*/
|
||||||
|
public function testDeepNestingPathBuilding()
|
||||||
|
{
|
||||||
|
$array = [
|
||||||
|
'level1' => [
|
||||||
|
'level2' => [
|
||||||
|
'level3' => [
|
||||||
|
'items' => [
|
||||||
|
'target_item' => [
|
||||||
|
'name' => 'deep_test',
|
||||||
|
// missing 'required_field'
|
||||||
|
]
|
||||||
|
]
|
||||||
|
]
|
||||||
|
]
|
||||||
|
]
|
||||||
|
];
|
||||||
|
|
||||||
|
$result = ArrayHandler::findArraysMissingKey($array, 'deep_test', 'required_field');
|
||||||
|
|
||||||
|
$this->assertCount(1, $result);
|
||||||
|
$this->assertEquals('level1:level2:level3:items:target_item', $result[0]['path']);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test with custom path separator
|
||||||
|
*/
|
||||||
|
public function testCustomPathSeparator()
|
||||||
|
{
|
||||||
|
$array = [
|
||||||
|
'level1' => [
|
||||||
|
'level2' => [
|
||||||
|
'item' => [
|
||||||
|
'name' => 'test',
|
||||||
|
// missing 'type' key
|
||||||
|
]
|
||||||
|
]
|
||||||
|
]
|
||||||
|
];
|
||||||
|
|
||||||
|
$result = ArrayHandler::findArraysMissingKey($array, 'test', 'type', null, '/');
|
||||||
|
|
||||||
|
$this->assertCount(1, $result);
|
||||||
|
$this->assertEquals('level1/level2/item', $result[0]['path']);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test default path separator behavior
|
||||||
|
*/
|
||||||
|
public function testDefaultPathSeparator()
|
||||||
|
{
|
||||||
|
$array = [
|
||||||
|
'parent' => [
|
||||||
|
'child' => [
|
||||||
|
'name' => 'test',
|
||||||
|
// missing 'value' key
|
||||||
|
]
|
||||||
|
]
|
||||||
|
];
|
||||||
|
|
||||||
|
// Using default separator (should be ':')
|
||||||
|
$result = ArrayHandler::findArraysMissingKey($array, 'test', 'value');
|
||||||
|
|
||||||
|
$this->assertCount(1, $result);
|
||||||
|
$this->assertEquals('parent:child', $result[0]['path']);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test different path separators don't affect search logic
|
||||||
|
*/
|
||||||
|
public function testPathSeparatorDoesNotAffectSearchLogic()
|
||||||
|
{
|
||||||
|
$array = [
|
||||||
|
'section' => [
|
||||||
|
'data' => [
|
||||||
|
'id' => 123,
|
||||||
|
'name' => 'item'
|
||||||
|
// missing 'status'
|
||||||
|
]
|
||||||
|
]
|
||||||
|
];
|
||||||
|
|
||||||
|
// Test with different separators - results should be identical except for path
|
||||||
|
$result1 = ArrayHandler::findArraysMissingKey($array, 123, 'status', 'id', ':');
|
||||||
|
$result2 = ArrayHandler::findArraysMissingKey($array, 123, 'status', 'id', '.');
|
||||||
|
$result3 = ArrayHandler::findArraysMissingKey($array, 123, 'status', 'id', '/');
|
||||||
|
|
||||||
|
$this->assertCount(1, $result1);
|
||||||
|
$this->assertCount(1, $result2);
|
||||||
|
$this->assertCount(1, $result3);
|
||||||
|
|
||||||
|
// Content and missing_key should be the same
|
||||||
|
$this->assertEquals($result1[0]['content'], $result2[0]['content']);
|
||||||
|
$this->assertEquals($result1[0]['content'], $result3[0]['content']);
|
||||||
|
$this->assertEquals($result1[0]['missing_key'], $result2[0]['missing_key']);
|
||||||
|
$this->assertEquals($result1[0]['missing_key'], $result3[0]['missing_key']);
|
||||||
|
|
||||||
|
// Paths should be different based on separator
|
||||||
|
$this->assertEquals('section:data', $result1[0]['path']);
|
||||||
|
$this->assertEquals('section.data', $result2[0]['path']);
|
||||||
|
$this->assertEquals('section/data', $result3[0]['path']);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* test type checking
|
||||||
|
*/
|
||||||
|
public function testStrictTypeChecking()
|
||||||
|
{
|
||||||
|
$array = [
|
||||||
|
'item1' => [
|
||||||
|
'id' => '123', // string
|
||||||
|
'name' => 'test'
|
||||||
|
// missing 'status'
|
||||||
|
],
|
||||||
|
'item2' => [
|
||||||
|
'id' => 123, // integer
|
||||||
|
'name' => 'test2',
|
||||||
|
'status' => 'active'
|
||||||
|
]
|
||||||
|
];
|
||||||
|
|
||||||
|
// Search for integer 123 - should only match item2
|
||||||
|
$result = ArrayHandler::findArraysMissingKey($array, 123, 'status', 'id');
|
||||||
|
$this->assertEmpty($result); // item2 has the status key
|
||||||
|
|
||||||
|
// Search for string '123' - should only match item1
|
||||||
|
$result = ArrayHandler::findArraysMissingKey($array, '123', 'status', 'id');
|
||||||
|
$this->assertCount(1, $result);
|
||||||
|
$this->assertEquals('item1', $result[0]['path']);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// __END__
|
||||||
@@ -0,0 +1,333 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
// This code was created by Claude Sonnet 4
|
||||||
|
// modification for value checks with assertEqualsCanonicalizing
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace tests;
|
||||||
|
|
||||||
|
use PHPUnit\Framework\TestCase;
|
||||||
|
use CoreLibs\Combined\ArrayHandler;
|
||||||
|
|
||||||
|
class CoreLibsCombinedArrayHandlerKsortArrayTest extends TestCase
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Test basic ascending sort (default behavior)
|
||||||
|
*/
|
||||||
|
public function testKsortArrayBasicAscending(): void
|
||||||
|
{
|
||||||
|
$input = [
|
||||||
|
'zebra' => 'value1',
|
||||||
|
'apple' => 'value2',
|
||||||
|
'banana' => 'value3',
|
||||||
|
'cherry' => 'value4'
|
||||||
|
];
|
||||||
|
|
||||||
|
$expected = [
|
||||||
|
'apple' => 'value2',
|
||||||
|
'banana' => 'value3',
|
||||||
|
'cherry' => 'value4',
|
||||||
|
'zebra' => 'value1'
|
||||||
|
];
|
||||||
|
|
||||||
|
$result = ArrayHandler::ksortArray($input);
|
||||||
|
$this->assertEquals($expected, $result);
|
||||||
|
$this->assertEquals(array_keys($expected), array_keys($result));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test descending sort with reverse=true
|
||||||
|
*/
|
||||||
|
public function testKsortArrayDescending(): void
|
||||||
|
{
|
||||||
|
$input = [
|
||||||
|
'zebra' => 'value1',
|
||||||
|
'apple' => 'value2',
|
||||||
|
'banana' => 'value3',
|
||||||
|
'cherry' => 'value4'
|
||||||
|
];
|
||||||
|
|
||||||
|
$expected = [
|
||||||
|
'zebra' => 'value1',
|
||||||
|
'cherry' => 'value4',
|
||||||
|
'banana' => 'value3',
|
||||||
|
'apple' => 'value2'
|
||||||
|
];
|
||||||
|
|
||||||
|
$result = ArrayHandler::ksortArray($input, false, true);
|
||||||
|
$this->assertEquals($expected, $result);
|
||||||
|
$this->assertEquals(array_keys($expected), array_keys($result));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test case-insensitive ascending sort
|
||||||
|
*/
|
||||||
|
public function testKsortArrayCaseInsensitiveAscending(): void
|
||||||
|
{
|
||||||
|
$input = [
|
||||||
|
'Zebra' => 'value1',
|
||||||
|
'apple' => 'value2',
|
||||||
|
'Banana' => 'value3',
|
||||||
|
'cherry' => 'value4'
|
||||||
|
];
|
||||||
|
|
||||||
|
$expected = [
|
||||||
|
'apple' => 'value2',
|
||||||
|
'Banana' => 'value3',
|
||||||
|
'cherry' => 'value4',
|
||||||
|
'Zebra' => 'value1'
|
||||||
|
];
|
||||||
|
|
||||||
|
$result = ArrayHandler::ksortArray($input, true);
|
||||||
|
$this->assertEquals($expected, $result);
|
||||||
|
$this->assertEquals(array_keys($expected), array_keys($result));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test case-insensitive descending sort
|
||||||
|
*/
|
||||||
|
public function testKsortArrayCaseInsensitiveDescending(): void
|
||||||
|
{
|
||||||
|
$input = [
|
||||||
|
'Zebra' => 'value1',
|
||||||
|
'apple' => 'value2',
|
||||||
|
'Banana' => 'value3',
|
||||||
|
'cherry' => 'value4'
|
||||||
|
];
|
||||||
|
|
||||||
|
$expected = [
|
||||||
|
'Zebra' => 'value1',
|
||||||
|
'cherry' => 'value4',
|
||||||
|
'Banana' => 'value3',
|
||||||
|
'apple' => 'value2'
|
||||||
|
];
|
||||||
|
|
||||||
|
$result = ArrayHandler::ksortArray($input, true, true);
|
||||||
|
$this->assertEquals($expected, $result);
|
||||||
|
$this->assertEquals(array_keys($expected), array_keys($result));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test with mixed case keys to verify case sensitivity behavior
|
||||||
|
*/
|
||||||
|
public function testKsortArrayCaseSensitivityComparison(): void
|
||||||
|
{
|
||||||
|
$input = [
|
||||||
|
'B' => 'value1',
|
||||||
|
'a' => 'value2',
|
||||||
|
'C' => 'value3',
|
||||||
|
'b' => 'value4'
|
||||||
|
];
|
||||||
|
|
||||||
|
// Case-sensitive sort (uppercase comes before lowercase in ASCII)
|
||||||
|
$expectedCaseSensitive = [
|
||||||
|
'B' => 'value1',
|
||||||
|
'C' => 'value3',
|
||||||
|
'a' => 'value2',
|
||||||
|
'b' => 'value4'
|
||||||
|
];
|
||||||
|
|
||||||
|
// Case-insensitive sort
|
||||||
|
$expectedCaseInsensitive = [
|
||||||
|
'a' => 'value2',
|
||||||
|
'B' => 'value1',
|
||||||
|
'b' => 'value4',
|
||||||
|
'C' => 'value3'
|
||||||
|
];
|
||||||
|
|
||||||
|
$resultCaseSensitive = ArrayHandler::ksortArray($input, false);
|
||||||
|
$resultCaseInsensitive = ArrayHandler::ksortArray($input, true);
|
||||||
|
|
||||||
|
$this->assertEquals($expectedCaseSensitive, $resultCaseSensitive);
|
||||||
|
$this->assertEquals($expectedCaseInsensitive, $resultCaseInsensitive);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test with numeric string keys
|
||||||
|
*/
|
||||||
|
public function testKsortArrayNumericStringKeys(): void
|
||||||
|
{
|
||||||
|
$input = [
|
||||||
|
'10' => 'value1',
|
||||||
|
'2' => 'value2',
|
||||||
|
'1' => 'value3',
|
||||||
|
'20' => 'value4'
|
||||||
|
];
|
||||||
|
|
||||||
|
// String comparison, not numeric
|
||||||
|
$expected = [
|
||||||
|
'1' => 'value3',
|
||||||
|
'10' => 'value1',
|
||||||
|
'2' => 'value2',
|
||||||
|
'20' => 'value4'
|
||||||
|
];
|
||||||
|
|
||||||
|
$result = ArrayHandler::ksortArray($input);
|
||||||
|
$this->assertEquals($expected, $result);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test with special characters in keys
|
||||||
|
*/
|
||||||
|
public function testKsortArraySpecialCharacters(): void
|
||||||
|
{
|
||||||
|
$input = [
|
||||||
|
'key_with_underscore' => 'value1',
|
||||||
|
'key-with-dash' => 'value2',
|
||||||
|
'key.with.dot' => 'value3',
|
||||||
|
'key with space' => 'value4',
|
||||||
|
'keyWithCamelCase' => 'value5'
|
||||||
|
];
|
||||||
|
|
||||||
|
$result = ArrayHandler::ksortArray($input);
|
||||||
|
|
||||||
|
// Verify it doesn't throw an error and maintains all keys
|
||||||
|
$this->assertCount(5, $result);
|
||||||
|
$this->assertArrayHasKey('key_with_underscore', $result);
|
||||||
|
$this->assertArrayHasKey('key-with-dash', $result);
|
||||||
|
$this->assertArrayHasKey('key.with.dot', $result);
|
||||||
|
$this->assertArrayHasKey('key with space', $result);
|
||||||
|
$this->assertArrayHasKey('keyWithCamelCase', $result);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test with empty array
|
||||||
|
*/
|
||||||
|
public function testKsortArrayEmpty(): void
|
||||||
|
{
|
||||||
|
$input = [];
|
||||||
|
$result = ArrayHandler::ksortArray($input);
|
||||||
|
$this->assertEquals([], $result);
|
||||||
|
$this->assertIsArray($result);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test with single element array
|
||||||
|
*/
|
||||||
|
public function testKsortArraySingleElement(): void
|
||||||
|
{
|
||||||
|
$input = ['onlykey' => 'onlyvalue'];
|
||||||
|
$result = ArrayHandler::ksortArray($input);
|
||||||
|
$this->assertEquals($input, $result);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test that original array is not modified (function returns new array)
|
||||||
|
*/
|
||||||
|
public function testKsortArrayDoesNotModifyOriginal(): void
|
||||||
|
{
|
||||||
|
$original = [
|
||||||
|
'zebra' => 'value1',
|
||||||
|
'apple' => 'value2',
|
||||||
|
'banana' => 'value3'
|
||||||
|
];
|
||||||
|
|
||||||
|
$originalCopy = $original; // Keep a copy for comparison
|
||||||
|
$result = ArrayHandler::ksortArray($original);
|
||||||
|
|
||||||
|
// Original array should remain unchanged
|
||||||
|
$this->assertEquals($originalCopy, $original);
|
||||||
|
$this->assertNotEquals(array_keys($original), array_keys($result));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test with complex mixed data types as values
|
||||||
|
*/
|
||||||
|
public function testKsortArrayMixedValueTypes(): void
|
||||||
|
{
|
||||||
|
$input = [
|
||||||
|
'string_key' => 'string_value',
|
||||||
|
'array_key' => ['nested', 'array'],
|
||||||
|
'int_key' => 42,
|
||||||
|
'bool_key' => true,
|
||||||
|
'null_key' => null
|
||||||
|
];
|
||||||
|
|
||||||
|
$result = ArrayHandler::ksortArray($input);
|
||||||
|
|
||||||
|
// Check that all keys are preserved and sorted
|
||||||
|
$expectedKeys = ['array_key', 'bool_key', 'int_key', 'null_key', 'string_key'];
|
||||||
|
$this->assertEquals($expectedKeys, array_keys($result));
|
||||||
|
|
||||||
|
// Check that values are preserved correctly
|
||||||
|
$this->assertEquals('string_value', $result['string_key']);
|
||||||
|
$this->assertEquals(['nested', 'array'], $result['array_key']);
|
||||||
|
$this->assertEquals(42, $result['int_key']);
|
||||||
|
$this->assertTrue($result['bool_key']);
|
||||||
|
$this->assertNull($result['null_key']);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test all parameter combinations
|
||||||
|
*/
|
||||||
|
public function testKsortArrayAllParameterCombinations(): void
|
||||||
|
{
|
||||||
|
$input = [
|
||||||
|
'Delta' => 'value1',
|
||||||
|
'alpha' => 'value2',
|
||||||
|
'Charlie' => 'value3',
|
||||||
|
'bravo' => 'value4'
|
||||||
|
];
|
||||||
|
|
||||||
|
// Test all 4 combinations
|
||||||
|
$result1 = ArrayHandler::ksortArray($input, false, false); // default
|
||||||
|
$result2 = ArrayHandler::ksortArray($input, false, true); // reverse only
|
||||||
|
$result3 = ArrayHandler::ksortArray($input, true, false); // lowercase only
|
||||||
|
$result4 = ArrayHandler::ksortArray($input, true, true); // both
|
||||||
|
|
||||||
|
// Each should produce different ordering
|
||||||
|
$this->assertNotEquals(array_keys($result1), array_keys($result2));
|
||||||
|
$this->assertNotEquals(array_keys($result1), array_keys($result3));
|
||||||
|
$this->assertNotEquals(array_keys($result1), array_keys($result4));
|
||||||
|
$this->assertNotEquals(array_keys($result2), array_keys($result3));
|
||||||
|
$this->assertNotEquals(array_keys($result2), array_keys($result4));
|
||||||
|
$this->assertNotEquals(array_keys($result3), array_keys($result4));
|
||||||
|
|
||||||
|
// But all should have same keys and values, just different order
|
||||||
|
$this->assertEqualsCanonicalizing(array_values($input), array_values($result1));
|
||||||
|
$this->assertEqualsCanonicalizing(array_values($input), array_values($result2));
|
||||||
|
$this->assertEqualsCanonicalizing(array_values($input), array_values($result3));
|
||||||
|
$this->assertEqualsCanonicalizing(array_values($input), array_values($result4));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Data provider for comprehensive testing
|
||||||
|
*/
|
||||||
|
public function sortingParametersProvider(): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'default' => [false, false],
|
||||||
|
'reverse' => [false, true],
|
||||||
|
'lowercase' => [true, false],
|
||||||
|
'lowercase_reverse' => [true, true],
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test that function works with all parameter combinations using data provider
|
||||||
|
*
|
||||||
|
* @dataProvider sortingParametersProvider
|
||||||
|
*/
|
||||||
|
public function testKsortArrayWithDataProvider(bool $lowerCase, bool $reverse): void
|
||||||
|
{
|
||||||
|
$input = [
|
||||||
|
'Zebra' => 'animal1',
|
||||||
|
'apple' => 'fruit1',
|
||||||
|
'Banana' => 'fruit2',
|
||||||
|
'cat' => 'animal2'
|
||||||
|
];
|
||||||
|
|
||||||
|
$result = ArrayHandler::ksortArray($input, $lowerCase, $reverse);
|
||||||
|
|
||||||
|
// Basic assertions that apply to all combinations
|
||||||
|
$this->assertIsArray($result);
|
||||||
|
$this->assertCount(4, $result);
|
||||||
|
$this->assertArrayHasKey('Zebra', $result);
|
||||||
|
$this->assertArrayHasKey('apple', $result);
|
||||||
|
$this->assertArrayHasKey('Banana', $result);
|
||||||
|
$this->assertArrayHasKey('cat', $result);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// __END__
|
||||||
@@ -0,0 +1,383 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
// created by Claude Sonnet 4
|
||||||
|
|
||||||
|
// testRecursiveSearchWithFlatResult had wrong retunr count
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace tests;
|
||||||
|
|
||||||
|
use PHPUnit\Framework\TestCase;
|
||||||
|
use CoreLibs\Combined\ArrayHandler;
|
||||||
|
|
||||||
|
class CoreLibsCombinedArrayHandlerSelectArrayFromOptionTest extends TestCase
|
||||||
|
{
|
||||||
|
private array $testData;
|
||||||
|
private array $nestedTestData;
|
||||||
|
|
||||||
|
protected function setUp(): void
|
||||||
|
{
|
||||||
|
$this->testData = [
|
||||||
|
'item1' => [
|
||||||
|
'name' => 'John',
|
||||||
|
'age' => 25,
|
||||||
|
'status' => 'active',
|
||||||
|
'score' => 85.5
|
||||||
|
],
|
||||||
|
'item2' => [
|
||||||
|
'name' => 'jane',
|
||||||
|
'age' => 30,
|
||||||
|
'status' => 'inactive',
|
||||||
|
'score' => 92.0
|
||||||
|
],
|
||||||
|
'item3' => [
|
||||||
|
'name' => 'Bob',
|
||||||
|
'age' => 25,
|
||||||
|
'status' => 'active',
|
||||||
|
'score' => 78.3
|
||||||
|
],
|
||||||
|
'item4' => [
|
||||||
|
'name' => 'Alice',
|
||||||
|
'age' => 35,
|
||||||
|
'status' => 'pending',
|
||||||
|
'score' => 88.7
|
||||||
|
]
|
||||||
|
];
|
||||||
|
|
||||||
|
$this->nestedTestData = [
|
||||||
|
'level1_a' => [
|
||||||
|
'name' => 'Level1A',
|
||||||
|
'type' => 'parent',
|
||||||
|
'children' => [
|
||||||
|
'child1' => [
|
||||||
|
'name' => 'Child1',
|
||||||
|
'type' => 'child',
|
||||||
|
'active' => true
|
||||||
|
],
|
||||||
|
'child2' => [
|
||||||
|
'name' => 'Child2',
|
||||||
|
'type' => 'child',
|
||||||
|
'active' => false
|
||||||
|
]
|
||||||
|
]
|
||||||
|
],
|
||||||
|
'level1_b' => [
|
||||||
|
'name' => 'Level1B',
|
||||||
|
'type' => 'parent',
|
||||||
|
'children' => [
|
||||||
|
'child3' => [
|
||||||
|
'name' => 'Child3',
|
||||||
|
'type' => 'child',
|
||||||
|
'active' => true,
|
||||||
|
'nested' => [
|
||||||
|
'deep1' => [
|
||||||
|
'name' => 'Deep1',
|
||||||
|
'type' => 'deep',
|
||||||
|
'active' => true
|
||||||
|
]
|
||||||
|
]
|
||||||
|
]
|
||||||
|
]
|
||||||
|
],
|
||||||
|
'item5' => [
|
||||||
|
'name' => 'Direct',
|
||||||
|
'type' => 'child',
|
||||||
|
'active' => false
|
||||||
|
]
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testEmptyArrayReturnsEmpty(): void
|
||||||
|
{
|
||||||
|
$result = ArrayHandler::selectArrayFromOption([], 'name', 'John');
|
||||||
|
$this->assertEmpty($result);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testBasicStringSearch(): void
|
||||||
|
{
|
||||||
|
$result = ArrayHandler::selectArrayFromOption($this->testData, 'name', 'John');
|
||||||
|
|
||||||
|
$this->assertCount(1, $result);
|
||||||
|
$this->assertArrayHasKey('item1', $result);
|
||||||
|
$this->assertEquals('John', $result['item1']['name']);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testBasicIntegerSearch(): void
|
||||||
|
{
|
||||||
|
$result = ArrayHandler::selectArrayFromOption($this->testData, 'age', 25);
|
||||||
|
|
||||||
|
$this->assertCount(2, $result);
|
||||||
|
$this->assertArrayHasKey('item1', $result);
|
||||||
|
$this->assertArrayHasKey('item3', $result);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testBasicFloatSearch(): void
|
||||||
|
{
|
||||||
|
$result = ArrayHandler::selectArrayFromOption($this->testData, 'score', 85.5);
|
||||||
|
|
||||||
|
$this->assertCount(1, $result);
|
||||||
|
$this->assertArrayHasKey('item1', $result);
|
||||||
|
$this->assertEquals(85.5, $result['item1']['score']);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testBasicBooleanSearch(): void
|
||||||
|
{
|
||||||
|
$data = [
|
||||||
|
'item1' => ['enabled' => true, 'name' => 'Test1'],
|
||||||
|
'item2' => ['enabled' => false, 'name' => 'Test2'],
|
||||||
|
'item3' => ['enabled' => true, 'name' => 'Test3']
|
||||||
|
];
|
||||||
|
|
||||||
|
$result = ArrayHandler::selectArrayFromOption($data, 'enabled', true);
|
||||||
|
|
||||||
|
$this->assertCount(2, $result);
|
||||||
|
$this->assertArrayHasKey('item1', $result);
|
||||||
|
$this->assertArrayHasKey('item3', $result);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testStrictComparison(): void
|
||||||
|
{
|
||||||
|
$data = [
|
||||||
|
'item1' => ['value' => '25', 'name' => 'String25'],
|
||||||
|
'item2' => ['value' => 25, 'name' => 'Int25'],
|
||||||
|
'item3' => ['value' => 25.0, 'name' => 'Float25']
|
||||||
|
];
|
||||||
|
|
||||||
|
// Non-strict should match all
|
||||||
|
$nonStrictResult = ArrayHandler::selectArrayFromOption($data, 'value', 25, false);
|
||||||
|
$this->assertCount(3, $nonStrictResult);
|
||||||
|
|
||||||
|
// Strict should only match exact type
|
||||||
|
$strictResult = ArrayHandler::selectArrayFromOption($data, 'value', 25, true);
|
||||||
|
$this->assertCount(1, $strictResult);
|
||||||
|
$this->assertArrayHasKey('item2', $strictResult);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testCaseInsensitiveSearch(): void
|
||||||
|
{
|
||||||
|
$result = ArrayHandler::selectArrayFromOption($this->testData, 'name', 'JANE', false, true);
|
||||||
|
|
||||||
|
$this->assertCount(1, $result);
|
||||||
|
$this->assertArrayHasKey('item2', $result);
|
||||||
|
$this->assertEquals('jane', $result['item2']['name']);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testCaseSensitiveSearch(): void
|
||||||
|
{
|
||||||
|
$result = ArrayHandler::selectArrayFromOption($this->testData, 'name', 'JANE', false, false);
|
||||||
|
|
||||||
|
$this->assertEmpty($result);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testRecursiveSearchWithFlatResult(): void
|
||||||
|
{
|
||||||
|
$result = ArrayHandler::selectArrayFromOption(
|
||||||
|
$this->nestedTestData,
|
||||||
|
'type',
|
||||||
|
'child',
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
true,
|
||||||
|
true,
|
||||||
|
':*'
|
||||||
|
);
|
||||||
|
|
||||||
|
$this->assertCount(4, $result);
|
||||||
|
$this->assertArrayHasKey('level1_a:*children:*child1', $result);
|
||||||
|
$this->assertArrayHasKey('level1_a:*children:*child2', $result);
|
||||||
|
$this->assertArrayHasKey('level1_b:*children:*child3', $result);
|
||||||
|
$this->assertArrayHasKey('item5', $result);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testRecursiveSearchWithNestedResult(): void
|
||||||
|
{
|
||||||
|
$result = ArrayHandler::selectArrayFromOption(
|
||||||
|
$this->nestedTestData,
|
||||||
|
'type',
|
||||||
|
'child',
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
true,
|
||||||
|
false
|
||||||
|
);
|
||||||
|
|
||||||
|
$this->assertCount(3, $result);
|
||||||
|
$this->assertArrayHasKey('level1_a', $result);
|
||||||
|
$this->assertArrayHasKey('level1_b', $result);
|
||||||
|
$this->assertArrayHasKey('item5', $result);
|
||||||
|
|
||||||
|
// Check nested structure is preserved
|
||||||
|
$this->assertArrayHasKey('children', $result['level1_a']);
|
||||||
|
$this->assertArrayHasKey('child1', $result['level1_a']['children']);
|
||||||
|
$this->assertArrayHasKey('child2', $result['level1_a']['children']);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testRecursiveSearchDeepNesting(): void
|
||||||
|
{
|
||||||
|
$result = ArrayHandler::selectArrayFromOption(
|
||||||
|
$this->nestedTestData,
|
||||||
|
'type',
|
||||||
|
'deep',
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
true,
|
||||||
|
true,
|
||||||
|
':*'
|
||||||
|
);
|
||||||
|
|
||||||
|
$this->assertCount(1, $result);
|
||||||
|
$this->assertArrayHasKey('level1_b:*children:*child3:*nested:*deep1', $result);
|
||||||
|
$this->assertEquals('Deep1', $result['level1_b:*children:*child3:*nested:*deep1']['name']);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testCustomFlatSeparator(): void
|
||||||
|
{
|
||||||
|
$result = ArrayHandler::selectArrayFromOption(
|
||||||
|
$this->nestedTestData,
|
||||||
|
'type',
|
||||||
|
'child',
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
true,
|
||||||
|
true,
|
||||||
|
'|'
|
||||||
|
);
|
||||||
|
|
||||||
|
$this->assertArrayHasKey('level1_a|children|child1', $result);
|
||||||
|
$this->assertArrayHasKey('level1_a|children|child2', $result);
|
||||||
|
$this->assertArrayHasKey('level1_b|children|child3', $result);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testNonRecursiveSearch(): void
|
||||||
|
{
|
||||||
|
$result = ArrayHandler::selectArrayFromOption(
|
||||||
|
$this->nestedTestData,
|
||||||
|
'type',
|
||||||
|
'child',
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
false
|
||||||
|
);
|
||||||
|
|
||||||
|
// Should only find direct matches, not nested ones
|
||||||
|
$this->assertCount(1, $result);
|
||||||
|
$this->assertArrayHasKey('item5', $result);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testNoMatchesFound(): void
|
||||||
|
{
|
||||||
|
$result = ArrayHandler::selectArrayFromOption($this->testData, 'name', 'NonExistent');
|
||||||
|
|
||||||
|
$this->assertEmpty($result);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testMissingLookupKey(): void
|
||||||
|
{
|
||||||
|
$result = ArrayHandler::selectArrayFromOption($this->testData, 'nonexistent_key', 'value');
|
||||||
|
|
||||||
|
$this->assertEmpty($result);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testCombinedStrictAndCaseInsensitive(): void
|
||||||
|
{
|
||||||
|
$data = [
|
||||||
|
'item1' => ['name' => 'Test', 'id' => '123'],
|
||||||
|
'item2' => ['name' => 'test', 'id' => 123],
|
||||||
|
'item3' => ['name' => 'TEST', 'id' => '123']
|
||||||
|
];
|
||||||
|
|
||||||
|
// Case insensitive but strict type matching
|
||||||
|
$result = ArrayHandler::selectArrayFromOption($data, 'id', '123', true, true);
|
||||||
|
|
||||||
|
$this->assertCount(2, $result);
|
||||||
|
$this->assertArrayHasKey('item1', $result);
|
||||||
|
$this->assertArrayHasKey('item3', $result);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testBooleanWithCaseInsensitive(): void
|
||||||
|
{
|
||||||
|
$data = [
|
||||||
|
'item1' => ['active' => true, 'name' => 'Test1'],
|
||||||
|
'item2' => ['active' => false, 'name' => 'Test2']
|
||||||
|
];
|
||||||
|
|
||||||
|
// Case insensitive flag should not affect boolean comparison
|
||||||
|
$result = ArrayHandler::selectArrayFromOption($data, 'active', true, false, true);
|
||||||
|
|
||||||
|
$this->assertCount(1, $result);
|
||||||
|
$this->assertArrayHasKey('item1', $result);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testArrayWithNumericKeys(): void
|
||||||
|
{
|
||||||
|
$data = [
|
||||||
|
0 => ['name' => 'First', 'type' => 'test'],
|
||||||
|
1 => ['name' => 'Second', 'type' => 'test'],
|
||||||
|
2 => ['name' => 'Third', 'type' => 'other']
|
||||||
|
];
|
||||||
|
|
||||||
|
$result = ArrayHandler::selectArrayFromOption($data, 'type', 'test');
|
||||||
|
|
||||||
|
$this->assertCount(2, $result);
|
||||||
|
$this->assertArrayHasKey(0, $result);
|
||||||
|
$this->assertArrayHasKey(1, $result);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testRecursiveWithMixedKeyTypes(): void
|
||||||
|
{
|
||||||
|
$data = [
|
||||||
|
'string_key' => [
|
||||||
|
'name' => 'Parent',
|
||||||
|
'type' => 'parent',
|
||||||
|
0 => [
|
||||||
|
'name' => 'Child0',
|
||||||
|
'type' => 'child'
|
||||||
|
],
|
||||||
|
'child_key' => [
|
||||||
|
'name' => 'ChildKey',
|
||||||
|
'type' => 'child'
|
||||||
|
]
|
||||||
|
]
|
||||||
|
];
|
||||||
|
|
||||||
|
$result = ArrayHandler::selectArrayFromOption($data, 'type', 'child', false, false, true, true, ':*');
|
||||||
|
|
||||||
|
$this->assertCount(2, $result);
|
||||||
|
$this->assertArrayHasKey('string_key:*0', $result);
|
||||||
|
$this->assertArrayHasKey('string_key:*child_key', $result);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testAllParametersCombined(): void
|
||||||
|
{
|
||||||
|
$data = [
|
||||||
|
'parent1' => [
|
||||||
|
'name' => 'Parent1',
|
||||||
|
'status' => 'ACTIVE',
|
||||||
|
'children' => [
|
||||||
|
'child1' => [
|
||||||
|
'name' => 'Child1',
|
||||||
|
'status' => 'active'
|
||||||
|
]
|
||||||
|
]
|
||||||
|
]
|
||||||
|
];
|
||||||
|
|
||||||
|
$result = ArrayHandler::selectArrayFromOption(
|
||||||
|
$data,
|
||||||
|
'status',
|
||||||
|
'active',
|
||||||
|
false, // not strict
|
||||||
|
true, // case insensitive
|
||||||
|
true, // recursive
|
||||||
|
true, // flat result
|
||||||
|
'|' // custom separator
|
||||||
|
);
|
||||||
|
|
||||||
|
$this->assertCount(2, $result);
|
||||||
|
$this->assertArrayHasKey('parent1', $result);
|
||||||
|
$this->assertArrayHasKey('parent1|children|child1', $result);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// __END__
|
||||||
@@ -0,0 +1,328 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
// This code was created by Claude Sonnet 4
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace tests;
|
||||||
|
|
||||||
|
use PHPUnit\Framework\TestCase;
|
||||||
|
use CoreLibs\Combined\ArrayHandler;
|
||||||
|
|
||||||
|
class CoreLibsCombinedArrayHandlerSortArrayTest extends TestCase
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Test basic ascending sort without maintaining keys
|
||||||
|
*/
|
||||||
|
public function testBasicAscendingSort()
|
||||||
|
{
|
||||||
|
$input = [3, 1, 4, 1, 5, 9];
|
||||||
|
$expected = [1, 1, 3, 4, 5, 9];
|
||||||
|
|
||||||
|
$result = ArrayHandler::sortArray($input);
|
||||||
|
|
||||||
|
$this->assertEquals($expected, $result);
|
||||||
|
$this->assertEquals(array_keys($expected), array_keys($result));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test basic descending sort without maintaining keys
|
||||||
|
*/
|
||||||
|
public function testBasicDescendingSort()
|
||||||
|
{
|
||||||
|
$input = [3, 1, 4, 1, 5, 9];
|
||||||
|
$expected = [9, 5, 4, 3, 1, 1];
|
||||||
|
|
||||||
|
$result = ArrayHandler::sortArray($input, false, true);
|
||||||
|
|
||||||
|
$this->assertEquals($expected, $result);
|
||||||
|
$this->assertEquals(array_keys($expected), array_keys($result));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test ascending sort with key maintenance
|
||||||
|
*/
|
||||||
|
public function testAscendingSortWithKeyMaintenance()
|
||||||
|
{
|
||||||
|
$input = ['c' => 3, 'a' => 1, 'd' => 4, 'b' => 1, 'e' => 5];
|
||||||
|
$expected = ['a' => 1, 'b' => 1, 'c' => 3, 'd' => 4, 'e' => 5];
|
||||||
|
|
||||||
|
$result = ArrayHandler::sortArray($input, false, false, true);
|
||||||
|
|
||||||
|
$this->assertEquals($expected, $result);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test descending sort with key maintenance
|
||||||
|
*/
|
||||||
|
public function testDescendingSortWithKeyMaintenance()
|
||||||
|
{
|
||||||
|
$input = ['c' => 3, 'a' => 1, 'd' => 4, 'b' => 1, 'e' => 5];
|
||||||
|
$expected = ['e' => 5, 'd' => 4, 'c' => 3, 'a' => 1, 'b' => 1];
|
||||||
|
|
||||||
|
$result = ArrayHandler::sortArray($input, false, true, true);
|
||||||
|
|
||||||
|
$this->assertEquals($expected, $result);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test string sorting with lowercase conversion
|
||||||
|
*/
|
||||||
|
public function testStringLowerCaseSort()
|
||||||
|
{
|
||||||
|
$input = ['Banana', 'apple', 'Cherry', 'date'];
|
||||||
|
$expected = ['apple', 'Banana', 'Cherry', 'date'];
|
||||||
|
|
||||||
|
$result = ArrayHandler::sortArray($input, true);
|
||||||
|
|
||||||
|
$this->assertEquals($expected, $result);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test string sorting with lowercase conversion in reverse
|
||||||
|
*/
|
||||||
|
public function testStringLowerCaseSortReverse()
|
||||||
|
{
|
||||||
|
$input = ['Banana', 'apple', 'Cherry', 'date'];
|
||||||
|
$expected = ['date', 'Cherry', 'Banana', 'apple'];
|
||||||
|
|
||||||
|
$result = ArrayHandler::sortArray($input, true, true);
|
||||||
|
|
||||||
|
$this->assertEquals($expected, $result);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test string sorting with lowercase conversion and key maintenance
|
||||||
|
*/
|
||||||
|
public function testStringLowerCaseSortWithKeys()
|
||||||
|
{
|
||||||
|
$input = ['b' => 'Banana', 'a' => 'apple', 'c' => 'Cherry', 'd' => 'date'];
|
||||||
|
$expected = ['a' => 'apple', 'b' => 'Banana', 'c' => 'Cherry', 'd' => 'date'];
|
||||||
|
|
||||||
|
$result = ArrayHandler::sortArray($input, true, false, true);
|
||||||
|
|
||||||
|
$this->assertEquals($expected, $result);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test string sorting with lowercase conversion, reverse, and key maintenance
|
||||||
|
*/
|
||||||
|
public function testStringLowerCaseSortReverseWithKeys()
|
||||||
|
{
|
||||||
|
$input = ['b' => 'Banana', 'a' => 'apple', 'c' => 'Cherry', 'd' => 'date'];
|
||||||
|
$expected = ['d' => 'date', 'c' => 'Cherry', 'b' => 'Banana', 'a' => 'apple'];
|
||||||
|
|
||||||
|
$result = ArrayHandler::sortArray($input, true, true, true);
|
||||||
|
|
||||||
|
$this->assertEquals($expected, $result);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test numeric string sorting with SORT_NUMERIC flag
|
||||||
|
*/
|
||||||
|
public function testNumericStringSorting()
|
||||||
|
{
|
||||||
|
$input = ['10', '2', '1', '20'];
|
||||||
|
$expected = ['1', '2', '10', '20'];
|
||||||
|
|
||||||
|
$result = ArrayHandler::sortArray($input, false, false, false, SORT_NUMERIC);
|
||||||
|
|
||||||
|
$this->assertEquals($expected, $result);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test natural string sorting with SORT_NATURAL flag
|
||||||
|
*/
|
||||||
|
public function testNaturalStringSorting()
|
||||||
|
{
|
||||||
|
$input = ['img1.png', 'img10.png', 'img2.png', 'img20.png'];
|
||||||
|
$expected = ['img1.png', 'img2.png', 'img10.png', 'img20.png'];
|
||||||
|
|
||||||
|
$result = ArrayHandler::sortArray($input, false, false, false, SORT_NATURAL);
|
||||||
|
|
||||||
|
$this->assertEquals($expected, $result);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test with empty array
|
||||||
|
*/
|
||||||
|
public function testEmptyArray()
|
||||||
|
{
|
||||||
|
$input = [];
|
||||||
|
$expected = [];
|
||||||
|
|
||||||
|
$result = ArrayHandler::sortArray($input);
|
||||||
|
|
||||||
|
$this->assertEquals($expected, $result);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test with single element array
|
||||||
|
*/
|
||||||
|
public function testSingleElementArray()
|
||||||
|
{
|
||||||
|
$input = [42];
|
||||||
|
$expected = [42];
|
||||||
|
|
||||||
|
$result = ArrayHandler::sortArray($input);
|
||||||
|
|
||||||
|
$this->assertEquals($expected, $result);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test with array containing null values
|
||||||
|
*/
|
||||||
|
public function testArrayWithNullValues()
|
||||||
|
{
|
||||||
|
$input = [3, null, 1, null, 2];
|
||||||
|
$expected = [null, null, 1, 2, 3];
|
||||||
|
|
||||||
|
$result = ArrayHandler::sortArray($input);
|
||||||
|
|
||||||
|
$this->assertEquals($expected, $result);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test with mixed data types
|
||||||
|
*/
|
||||||
|
public function testMixedDataTypes()
|
||||||
|
{
|
||||||
|
$input = [3, '1', 4.5, '2', 1];
|
||||||
|
|
||||||
|
$result = ArrayHandler::sortArray($input);
|
||||||
|
|
||||||
|
// Should sort according to PHP's natural comparison rules
|
||||||
|
$this->assertIsArray($result);
|
||||||
|
$this->assertCount(5, $result);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test that original array is not modified (immutability)
|
||||||
|
*/
|
||||||
|
public function testOriginalArrayNotModified()
|
||||||
|
{
|
||||||
|
$original = [3, 1, 4, 1, 5, 9];
|
||||||
|
$input = $original;
|
||||||
|
|
||||||
|
$result = ArrayHandler::sortArray($input);
|
||||||
|
|
||||||
|
$this->assertEquals($original, $input);
|
||||||
|
$this->assertNotEquals($input, $result);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test case sensitivity without lowercase flag
|
||||||
|
*/
|
||||||
|
public function testCaseSensitivityWithoutLowercase()
|
||||||
|
{
|
||||||
|
$input = ['Banana', 'apple', 'Cherry'];
|
||||||
|
|
||||||
|
$result = ArrayHandler::sortArray($input);
|
||||||
|
|
||||||
|
// Capital letters should come before lowercase in ASCII sort
|
||||||
|
$this->assertEquals('Banana', $result[0]);
|
||||||
|
$this->assertEquals('Cherry', $result[1]);
|
||||||
|
$this->assertEquals('apple', $result[2]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test all parameters combination
|
||||||
|
*/
|
||||||
|
public function testAllParametersCombination()
|
||||||
|
{
|
||||||
|
$input = ['z' => 'Zebra', 'a' => 'apple', 'b' => 'Banana'];
|
||||||
|
|
||||||
|
$result = ArrayHandler::sortArray($input, true, true, true, SORT_REGULAR);
|
||||||
|
|
||||||
|
// Should be sorted by lowercase, reversed, with keys maintained
|
||||||
|
$keys = array_keys($result);
|
||||||
|
$values = array_values($result);
|
||||||
|
|
||||||
|
$this->assertEquals(['z', 'b', 'a'], $keys);
|
||||||
|
$this->assertEquals(['Zebra', 'Banana', 'apple'], $values);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test floating point numbers
|
||||||
|
*/
|
||||||
|
public function testFloatingPointNumbers()
|
||||||
|
{
|
||||||
|
$input = [3.14, 2.71, 1.41, 1.73];
|
||||||
|
$expected = [1.41, 1.73, 2.71, 3.14];
|
||||||
|
|
||||||
|
$result = ArrayHandler::sortArray($input);
|
||||||
|
|
||||||
|
$this->assertEquals($expected, $result);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test with duplicate values and key maintenance
|
||||||
|
*/
|
||||||
|
public function testDuplicateValuesWithKeyMaintenance()
|
||||||
|
{
|
||||||
|
$input = ['first' => 1, 'second' => 2, 'third' => 1, 'fourth' => 2];
|
||||||
|
|
||||||
|
$result = ArrayHandler::sortArray($input, false, false, true);
|
||||||
|
|
||||||
|
$this->assertCount(4, $result);
|
||||||
|
$this->assertEquals([1, 1, 2, 2], array_values($result));
|
||||||
|
// Keys should be preserved
|
||||||
|
$this->assertArrayHasKey('first', $result);
|
||||||
|
$this->assertArrayHasKey('second', $result);
|
||||||
|
$this->assertArrayHasKey('third', $result);
|
||||||
|
$this->assertArrayHasKey('fourth', $result);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Data provider for comprehensive parameter testing
|
||||||
|
*/
|
||||||
|
public function sortParameterProvider(): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'basic_ascending' => [
|
||||||
|
[3, 1, 4, 2],
|
||||||
|
false, false, false, SORT_REGULAR,
|
||||||
|
[1, 2, 3, 4]
|
||||||
|
],
|
||||||
|
'basic_descending' => [
|
||||||
|
[3, 1, 4, 2],
|
||||||
|
false, true, false, SORT_REGULAR,
|
||||||
|
[4, 3, 2, 1]
|
||||||
|
],
|
||||||
|
'lowercase_ascending' => [
|
||||||
|
['Banana', 'apple', 'Cherry'],
|
||||||
|
true, false, false, SORT_REGULAR,
|
||||||
|
['apple', 'Banana', 'Cherry']
|
||||||
|
],
|
||||||
|
'lowercase_descending' => [
|
||||||
|
['Banana', 'apple', 'Cherry'],
|
||||||
|
true, true, false, SORT_REGULAR,
|
||||||
|
['Cherry', 'Banana', 'apple']
|
||||||
|
]
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test various parameter combinations using data provider
|
||||||
|
*
|
||||||
|
* @dataProvider sortParameterProvider
|
||||||
|
*/
|
||||||
|
public function testSortParameterCombinations(
|
||||||
|
array $input,
|
||||||
|
bool $lowercase,
|
||||||
|
bool $reverse,
|
||||||
|
bool $maintainKeys,
|
||||||
|
int $params,
|
||||||
|
array $expected
|
||||||
|
) {
|
||||||
|
$result = ArrayHandler::sortArray($input, $lowercase, $reverse, $maintainKeys, $params);
|
||||||
|
|
||||||
|
if (!$maintainKeys) {
|
||||||
|
$this->assertEquals($expected, $result);
|
||||||
|
} else {
|
||||||
|
$this->assertEquals($expected, array_values($result));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// __END__
|
||||||
2383
4dev/tests/Combined/CoreLibsCombinedArrayHandlerTest.php
Normal file
2383
4dev/tests/Combined/CoreLibsCombinedArrayHandlerTest.php
Normal file
File diff suppressed because it is too large
Load Diff
1608
4dev/tests/Combined/CoreLibsCombinedDateTimeTest.php
Normal file
1608
4dev/tests/Combined/CoreLibsCombinedDateTimeTest.php
Normal file
File diff suppressed because it is too large
Load Diff
@@ -16,7 +16,6 @@ use PHPUnit\Framework\TestCase;
|
|||||||
*/
|
*/
|
||||||
final class CoreLibsConvertByteTest extends TestCase
|
final class CoreLibsConvertByteTest extends TestCase
|
||||||
{
|
{
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Undocumented function
|
* Undocumented function
|
||||||
*
|
*
|
||||||
@@ -24,7 +23,31 @@ final class CoreLibsConvertByteTest extends TestCase
|
|||||||
*/
|
*/
|
||||||
public function byteProvider(): array
|
public function byteProvider(): array
|
||||||
{
|
{
|
||||||
|
/*
|
||||||
|
* 0: input string
|
||||||
|
* 1: default flags
|
||||||
|
* 2: BYTE_FORMAT_SI
|
||||||
|
* 3: BYTE_FORMAT_NOSPACE
|
||||||
|
* 4: BYTE_FORMAT_ADJUST
|
||||||
|
* 5: BYTE_FORMAT_SI | BYTE_FORMAT_NOSPACE
|
||||||
|
*/
|
||||||
return [
|
return [
|
||||||
|
'string number' => [
|
||||||
|
0 => '1024',
|
||||||
|
1 => '1 KB',
|
||||||
|
2 => '1.02 KiB',
|
||||||
|
3 => '1KB',
|
||||||
|
4 => '1.00 KB',
|
||||||
|
5 => '1.02KiB',
|
||||||
|
],
|
||||||
|
'invalid string number' => [
|
||||||
|
0 => '1024 MB',
|
||||||
|
1 => '1024 MB',
|
||||||
|
2 => '1024 MB',
|
||||||
|
3 => '1024 MB',
|
||||||
|
4 => '1024 MB',
|
||||||
|
5 => '1024 MB',
|
||||||
|
],
|
||||||
'negative number' => [
|
'negative number' => [
|
||||||
0 => -123123123,
|
0 => -123123123,
|
||||||
1 => '-117.42 MB',
|
1 => '-117.42 MB',
|
||||||
@@ -100,47 +123,6 @@ final class CoreLibsConvertByteTest extends TestCase
|
|||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Undocumented function
|
|
||||||
*
|
|
||||||
* @return array
|
|
||||||
*/
|
|
||||||
public function byteStringProvider(): array
|
|
||||||
{
|
|
||||||
return [
|
|
||||||
'negative number' => [
|
|
||||||
0 => '-117.42 MB',
|
|
||||||
1 => -123123794,
|
|
||||||
2 => -117420000,
|
|
||||||
],
|
|
||||||
'megabyte' => [
|
|
||||||
0 => '242.98 MB',
|
|
||||||
1 => 254782996,
|
|
||||||
2 => 242980000
|
|
||||||
],
|
|
||||||
'megabyte si' => [
|
|
||||||
0 => '254.78 MiB',
|
|
||||||
1 => 267156193,
|
|
||||||
2 => 254780000
|
|
||||||
],
|
|
||||||
'petabyte' => [
|
|
||||||
0 => '1 EiB',
|
|
||||||
1 => 1152921504606846976,
|
|
||||||
2 => 1000000000000000000,
|
|
||||||
],
|
|
||||||
'max int' => [
|
|
||||||
0 => '8 EB',
|
|
||||||
1 => -9223372036854775807 - 1,
|
|
||||||
2 => 8000000000000000000,
|
|
||||||
],
|
|
||||||
'exabyte, overflow' => [
|
|
||||||
0 => '867.36EB',
|
|
||||||
1 => 3873816255479021568,
|
|
||||||
2 => 363028535651074048,
|
|
||||||
]
|
|
||||||
];
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Undocumented function
|
* Undocumented function
|
||||||
*
|
*
|
||||||
@@ -157,7 +139,7 @@ final class CoreLibsConvertByteTest extends TestCase
|
|||||||
* @return void
|
* @return void
|
||||||
*/
|
*/
|
||||||
public function testHumanReadableByteFormat(
|
public function testHumanReadableByteFormat(
|
||||||
$input,
|
string|int|float $input,
|
||||||
string $expected,
|
string $expected,
|
||||||
string $expected_si,
|
string $expected_si,
|
||||||
string $expected_no_space,
|
string $expected_no_space,
|
||||||
@@ -194,6 +176,73 @@ final class CoreLibsConvertByteTest extends TestCase
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Undocumented function
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function byteStringProvider(): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'negative number' => [
|
||||||
|
0 => '-117.42 MB',
|
||||||
|
1 => -123123794,
|
||||||
|
2 => -117420000,
|
||||||
|
3 => "-123123793",
|
||||||
|
4 => "-117420000",
|
||||||
|
5 => null,
|
||||||
|
],
|
||||||
|
'megabyte' => [
|
||||||
|
0 => '242.98 MB',
|
||||||
|
1 => 254782996,
|
||||||
|
2 => 242980000,
|
||||||
|
3 => "254782996",
|
||||||
|
4 => "242980000",
|
||||||
|
5 => null,
|
||||||
|
],
|
||||||
|
'megabyte si' => [
|
||||||
|
0 => '254.78 MiB',
|
||||||
|
1 => 267156193,
|
||||||
|
2 => 254780000,
|
||||||
|
3 => "267156193",
|
||||||
|
4 => "254780000",
|
||||||
|
5 => null,
|
||||||
|
],
|
||||||
|
'petabyte' => [
|
||||||
|
0 => '1 EiB',
|
||||||
|
1 => 1152921504606846976,
|
||||||
|
2 => 1000000000000000000,
|
||||||
|
3 => "1152921504606846976",
|
||||||
|
4 => "1000000000000000000",
|
||||||
|
5 => null,
|
||||||
|
],
|
||||||
|
'max int' => [
|
||||||
|
0 => '8 EB',
|
||||||
|
1 => 0,
|
||||||
|
2 => 0,
|
||||||
|
3 => "9223372036854775808",
|
||||||
|
4 => "8000000000000000000",
|
||||||
|
5 => \LengthException::class,
|
||||||
|
],
|
||||||
|
'exabyte, overflow' => [
|
||||||
|
0 => '867.36EB',
|
||||||
|
1 => 0,
|
||||||
|
2 => 0,
|
||||||
|
3 => "999997996235794808832",
|
||||||
|
4 => "867360000000000000000",
|
||||||
|
5 => \LengthException::class,
|
||||||
|
],
|
||||||
|
'huge exabyte, overflow' => [
|
||||||
|
0 => '1000EB',
|
||||||
|
1 => 0,
|
||||||
|
2 => 0,
|
||||||
|
3 => "1152921504606846976000",
|
||||||
|
4 => "1000000000000000000000",
|
||||||
|
5 => \LengthException::class,
|
||||||
|
],
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Undocumented function
|
* Undocumented function
|
||||||
*
|
*
|
||||||
@@ -204,10 +253,22 @@ final class CoreLibsConvertByteTest extends TestCase
|
|||||||
* @param string|int|float $input
|
* @param string|int|float $input
|
||||||
* @param string|int|float $expected
|
* @param string|int|float $expected
|
||||||
* @param string|int|float $expected_si
|
* @param string|int|float $expected_si
|
||||||
|
* @param string|int|float $expected_string
|
||||||
|
* @param string|int|float $expected_string_si
|
||||||
|
* @param ?string $exception
|
||||||
* @return void
|
* @return void
|
||||||
*/
|
*/
|
||||||
public function testStringByteFormat($input, $expected, $expected_si): void
|
public function testStringByteFormat(
|
||||||
{
|
string|int|float $input,
|
||||||
|
string|int|float $expected,
|
||||||
|
string|int|float $expected_si,
|
||||||
|
string|int|float $expected_string,
|
||||||
|
string|int|float $expected_string_si,
|
||||||
|
?string $exception
|
||||||
|
): void {
|
||||||
|
if ($exception !== null) {
|
||||||
|
$this->expectException($exception);
|
||||||
|
}
|
||||||
$this->assertEquals(
|
$this->assertEquals(
|
||||||
$expected,
|
$expected,
|
||||||
\CoreLibs\Convert\Byte::stringByteFormat($input)
|
\CoreLibs\Convert\Byte::stringByteFormat($input)
|
||||||
@@ -216,6 +277,54 @@ final class CoreLibsConvertByteTest extends TestCase
|
|||||||
$expected_si,
|
$expected_si,
|
||||||
\CoreLibs\Convert\Byte::stringByteFormat($input, \CoreLibs\Convert\Byte::BYTE_FORMAT_SI)
|
\CoreLibs\Convert\Byte::stringByteFormat($input, \CoreLibs\Convert\Byte::BYTE_FORMAT_SI)
|
||||||
);
|
);
|
||||||
|
$this->assertEquals(
|
||||||
|
$expected_string,
|
||||||
|
\CoreLibs\Convert\Byte::stringByteFormat($input, \CoreLibs\Convert\Byte::RETURN_AS_STRING)
|
||||||
|
);
|
||||||
|
$this->assertEquals(
|
||||||
|
$expected_string_si,
|
||||||
|
\CoreLibs\Convert\Byte::stringByteFormat(
|
||||||
|
$input,
|
||||||
|
\CoreLibs\Convert\Byte::BYTE_FORMAT_SI | \CoreLibs\Convert\Byte::RETURN_AS_STRING
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Exceptions tests
|
||||||
|
*
|
||||||
|
* @covers ::humanReadableByteFormat
|
||||||
|
* @testWith [99]
|
||||||
|
* @testdox Test exception for humanReadableByteFormat with flag $flag
|
||||||
|
*
|
||||||
|
* @param int $flag
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function testHumanReadableByteFormatException(int $flag): void
|
||||||
|
{
|
||||||
|
$this->expectException(\InvalidArgumentException::class);
|
||||||
|
$this->expectExceptionCode(1);
|
||||||
|
\CoreLibs\Convert\Byte::humanReadableByteFormat(12, $flag);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Exceptions tests
|
||||||
|
* can only be 4, try 1,2 and over
|
||||||
|
*
|
||||||
|
* @covers ::stringByteFormat
|
||||||
|
* @testWith [1]
|
||||||
|
* [2]
|
||||||
|
* [99]
|
||||||
|
* @testdox Test exception for stringByteFormat with flag $flag
|
||||||
|
*
|
||||||
|
* @param int $flag
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function testStringByteFormatException(int $flag): void
|
||||||
|
{
|
||||||
|
$this->expectException(\InvalidArgumentException::class);
|
||||||
|
$this->expectExceptionCode(1);
|
||||||
|
\CoreLibs\Convert\Byte::stringByteFormat(12, $flag);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
1186
4dev/tests/Convert/CoreLibsConvertColorTest.php
Normal file
1186
4dev/tests/Convert/CoreLibsConvertColorTest.php
Normal file
File diff suppressed because it is too large
Load Diff
@@ -9,7 +9,7 @@ use PHPUnit\Framework\TestCase;
|
|||||||
/**
|
/**
|
||||||
* Test class for Convert\Colors
|
* Test class for Convert\Colors
|
||||||
* @coversDefaultClass \CoreLibs\Convert\Colors
|
* @coversDefaultClass \CoreLibs\Convert\Colors
|
||||||
* @testdox \CoreLibs\Convert\Colors method tests
|
* @testdox \CoreLibs\Convert\Colors legacy method tests
|
||||||
*/
|
*/
|
||||||
final class CoreLibsConvertColorsTest extends TestCase
|
final class CoreLibsConvertColorsTest extends TestCase
|
||||||
{
|
{
|
||||||
@@ -21,7 +21,7 @@ final class CoreLibsConvertColorsTest extends TestCase
|
|||||||
*
|
*
|
||||||
* @return array
|
* @return array
|
||||||
*/
|
*/
|
||||||
public function rgb2hexColorProvider(): array
|
public function providerRgb2hexColor(): array
|
||||||
{
|
{
|
||||||
return [
|
return [
|
||||||
'color' => [
|
'color' => [
|
||||||
@@ -59,6 +59,27 @@ final class CoreLibsConvertColorsTest extends TestCase
|
|||||||
3 => false,
|
3 => false,
|
||||||
4 => false
|
4 => false
|
||||||
],
|
],
|
||||||
|
'invalid color red ' => [
|
||||||
|
0 => -12,
|
||||||
|
1 => 12,
|
||||||
|
2 => 12,
|
||||||
|
3 => false,
|
||||||
|
4 => false
|
||||||
|
],
|
||||||
|
'invalid color green ' => [
|
||||||
|
0 => 12,
|
||||||
|
1 => -12,
|
||||||
|
2 => 12,
|
||||||
|
3 => false,
|
||||||
|
4 => false
|
||||||
|
],
|
||||||
|
'invalid color blue ' => [
|
||||||
|
0 => 12,
|
||||||
|
1 => 12,
|
||||||
|
2 => -12,
|
||||||
|
3 => false,
|
||||||
|
4 => false
|
||||||
|
],
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -67,7 +88,7 @@ final class CoreLibsConvertColorsTest extends TestCase
|
|||||||
*
|
*
|
||||||
* @return array
|
* @return array
|
||||||
*/
|
*/
|
||||||
public function hex2rgbColorProvider(): array
|
public function providerHex2rgbColor(): array
|
||||||
{
|
{
|
||||||
return [
|
return [
|
||||||
'color' => [
|
'color' => [
|
||||||
@@ -122,6 +143,8 @@ final class CoreLibsConvertColorsTest extends TestCase
|
|||||||
*/
|
*/
|
||||||
public function rgb2hslAndhsbList(): array
|
public function rgb2hslAndhsbList(): array
|
||||||
{
|
{
|
||||||
|
// if hsb_from or hsl_from is set, this will be used in hsb/hsl convert
|
||||||
|
// hsb_rgb is used for adjusted rgb valus due to round error to in
|
||||||
return [
|
return [
|
||||||
'valid gray' => [
|
'valid gray' => [
|
||||||
'rgb' => [12, 12, 12],
|
'rgb' => [12, 12, 12],
|
||||||
@@ -137,11 +160,51 @@ final class CoreLibsConvertColorsTest extends TestCase
|
|||||||
'hsl' => [211.6, 90.5, 41.2],
|
'hsl' => [211.6, 90.5, 41.2],
|
||||||
'valid' => true,
|
'valid' => true,
|
||||||
],
|
],
|
||||||
|
// hsg/hsl with 360 which is seen as 0
|
||||||
|
'valid color hue 360' => [
|
||||||
|
'rgb' => [200, 10, 10],
|
||||||
|
'hsb' => [0, 95, 78.0],
|
||||||
|
'hsb_from' => [360, 95, 78.0],
|
||||||
|
'hsb_rgb' => [199, 10, 10], // should be rgb, but rounding error
|
||||||
|
'hsl' => [0.0, 90.5, 41.2],
|
||||||
|
'hsl_from' => [360.0, 90.5, 41.2],
|
||||||
|
'valid' => true,
|
||||||
|
],
|
||||||
// invalid values
|
// invalid values
|
||||||
'invalid color' => [
|
'invalid color r/h/h low' => [
|
||||||
'rgb' => [-12, 300, 12],
|
'rgb' => [-1, 12, 12],
|
||||||
'hsb' => [-12, 300, 12],
|
'hsb' => [-1, 50, 50],
|
||||||
'hsl' => [-12, 300, 12],
|
'hsl' => [-1, 50, 50],
|
||||||
|
'valid' => false,
|
||||||
|
],
|
||||||
|
'invalid color r/h/h high' => [
|
||||||
|
'rgb' => [256, 12, 12],
|
||||||
|
'hsb' => [361, 50, 50],
|
||||||
|
'hsl' => [361, 50, 50],
|
||||||
|
'valid' => false,
|
||||||
|
],
|
||||||
|
'invalid color g/s/s low' => [
|
||||||
|
'rgb' => [12, -1, 12],
|
||||||
|
'hsb' => [1, -1, 50],
|
||||||
|
'hsl' => [1, -1, 50],
|
||||||
|
'valid' => false,
|
||||||
|
],
|
||||||
|
'invalid color g/s/s high' => [
|
||||||
|
'rgb' => [12, 256, 12],
|
||||||
|
'hsb' => [1, 101, 50],
|
||||||
|
'hsl' => [1, 101, 50],
|
||||||
|
'valid' => false,
|
||||||
|
],
|
||||||
|
'invalid color b/b/l low' => [
|
||||||
|
'rgb' => [12, 12, -1],
|
||||||
|
'hsb' => [1, 50, -1],
|
||||||
|
'hsl' => [1, 50, -1],
|
||||||
|
'valid' => false,
|
||||||
|
],
|
||||||
|
'invalid color b/b/l high' => [
|
||||||
|
'rgb' => [12, 12, 256],
|
||||||
|
'hsb' => [1, 50, 101],
|
||||||
|
'hsl' => [1, 50, 101],
|
||||||
'valid' => false,
|
'valid' => false,
|
||||||
],
|
],
|
||||||
];
|
];
|
||||||
@@ -152,7 +215,7 @@ final class CoreLibsConvertColorsTest extends TestCase
|
|||||||
*
|
*
|
||||||
* @return array
|
* @return array
|
||||||
*/
|
*/
|
||||||
public function rgb2hsbColorProvider(): array
|
public function providerRgb2hsbColor(): array
|
||||||
{
|
{
|
||||||
$list = [];
|
$list = [];
|
||||||
foreach ($this->rgb2hslAndhsbList() as $name => $values) {
|
foreach ($this->rgb2hslAndhsbList() as $name => $values) {
|
||||||
@@ -171,14 +234,14 @@ final class CoreLibsConvertColorsTest extends TestCase
|
|||||||
*
|
*
|
||||||
* @return array
|
* @return array
|
||||||
*/
|
*/
|
||||||
public function hsb2rgbColorProvider(): array
|
public function providerHsb2rgbColor(): array
|
||||||
{
|
{
|
||||||
$list = [];
|
$list = [];
|
||||||
foreach ($this->rgb2hslAndhsbList() as $name => $values) {
|
foreach ($this->rgb2hslAndhsbList() as $name => $values) {
|
||||||
$list[$name . ', hsb to rgb'] = [
|
$list[$name . ', hsb to rgb'] = [
|
||||||
0 => $values['hsb'][0],
|
0 => $values['hsb_from'][0] ?? $values['hsb'][0],
|
||||||
1 => $values['hsb'][1],
|
1 => $values['hsb_from'][1] ?? $values['hsb'][1],
|
||||||
2 => $values['hsb'][2],
|
2 => $values['hsb_from'][2] ?? $values['hsb'][2],
|
||||||
3 => $values['valid'] ? $values['hsb_rgb'] : false
|
3 => $values['valid'] ? $values['hsb_rgb'] : false
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
@@ -190,7 +253,7 @@ final class CoreLibsConvertColorsTest extends TestCase
|
|||||||
*
|
*
|
||||||
* @return array
|
* @return array
|
||||||
*/
|
*/
|
||||||
public function rgb2hslColorProvider(): array
|
public function providerRgb2hslColor(): array
|
||||||
{
|
{
|
||||||
$list = [];
|
$list = [];
|
||||||
foreach ($this->rgb2hslAndhsbList() as $name => $values) {
|
foreach ($this->rgb2hslAndhsbList() as $name => $values) {
|
||||||
@@ -209,14 +272,14 @@ final class CoreLibsConvertColorsTest extends TestCase
|
|||||||
*
|
*
|
||||||
* @return array
|
* @return array
|
||||||
*/
|
*/
|
||||||
public function hsl2rgbColorProvider(): array
|
public function providerHsl2rgbColor(): array
|
||||||
{
|
{
|
||||||
$list = [];
|
$list = [];
|
||||||
foreach ($this->rgb2hslAndhsbList() as $name => $values) {
|
foreach ($this->rgb2hslAndhsbList() as $name => $values) {
|
||||||
$list[$name . ', hsl to rgb'] = [
|
$list[$name . ', hsl to rgb'] = [
|
||||||
0 => $values['hsl'][0],
|
0 => $values['hsl_from'][0] ?? $values['hsl'][0],
|
||||||
1 => $values['hsl'][1],
|
1 => $values['hsl_from'][1] ?? $values['hsl'][1],
|
||||||
2 => $values['hsl'][2],
|
2 => $values['hsl_from'][2] ?? $values['hsl'][2],
|
||||||
3 => $values['valid'] ? $values['rgb'] : false
|
3 => $values['valid'] ? $values['rgb'] : false
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
@@ -228,17 +291,28 @@ final class CoreLibsConvertColorsTest extends TestCase
|
|||||||
* TODO: add cross convert check
|
* TODO: add cross convert check
|
||||||
*
|
*
|
||||||
* @covers ::rgb2hex
|
* @covers ::rgb2hex
|
||||||
* @dataProvider rgb2hexColorProvider
|
* @dataProvider providerRgb2hexColor
|
||||||
* @testdox rgb2hex $input_r,$input_g,$input_b will be $expected [$_dataName]
|
* @testdox rgb2hex $input_r,$input_g,$input_b will be $expected [$_dataName]
|
||||||
*
|
*
|
||||||
* @param int $input_r
|
* @param int $input_r
|
||||||
* @param int $input_g
|
* @param int $input_g
|
||||||
* @param int $input_b
|
* @param int $input_b
|
||||||
|
* @param string|bool $expected_hash
|
||||||
* @param string|bool $expected
|
* @param string|bool $expected
|
||||||
* @return void
|
* @return void
|
||||||
*/
|
*/
|
||||||
public function testRgb2hex(int $input_r, int $input_g, int $input_b, $expected_hash, $expected)
|
public function testRgb2hex(
|
||||||
{
|
int $input_r,
|
||||||
|
int $input_g,
|
||||||
|
int $input_b,
|
||||||
|
string|bool $expected_hash,
|
||||||
|
string|bool $expected
|
||||||
|
) {
|
||||||
|
// if expected hash is or expected is false, we need to check for
|
||||||
|
// LengthException
|
||||||
|
if ($expected_hash === false || $expected === false) {
|
||||||
|
$this->expectException(\LengthException::class);
|
||||||
|
}
|
||||||
// with #
|
// with #
|
||||||
$this->assertEquals(
|
$this->assertEquals(
|
||||||
$expected_hash,
|
$expected_hash,
|
||||||
@@ -268,7 +342,7 @@ final class CoreLibsConvertColorsTest extends TestCase
|
|||||||
* Undocumented function
|
* Undocumented function
|
||||||
*
|
*
|
||||||
* @covers ::hex2rgb
|
* @covers ::hex2rgb
|
||||||
* @dataProvider hex2rgbColorProvider
|
* @dataProvider providerHex2rgbColor
|
||||||
* @testdox hex2rgb $input will be $expected, $expected_str str[,], $expected_str_sep str[$separator] [$_dataName]
|
* @testdox hex2rgb $input will be $expected, $expected_str str[,], $expected_str_sep str[$separator] [$_dataName]
|
||||||
*
|
*
|
||||||
* @param string $input
|
* @param string $input
|
||||||
@@ -280,11 +354,19 @@ final class CoreLibsConvertColorsTest extends TestCase
|
|||||||
*/
|
*/
|
||||||
public function testHex2rgb(
|
public function testHex2rgb(
|
||||||
string $input,
|
string $input,
|
||||||
$expected,
|
array|bool $expected,
|
||||||
$expected_str,
|
string|bool $expected_str,
|
||||||
string $separator,
|
string $separator,
|
||||||
$expected_str_sep
|
string|bool $expected_str_sep
|
||||||
): void {
|
): void {
|
||||||
|
if ($expected === false || $expected_str === false || $expected_str_sep === false) {
|
||||||
|
$hex_string = preg_replace("/[^0-9A-Fa-f]/", '', $input);
|
||||||
|
if (!is_string($hex_string)) {
|
||||||
|
$this->expectException(\InvalidArgumentException::class);
|
||||||
|
} else {
|
||||||
|
$this->expectException(\UnexpectedValueException::class);
|
||||||
|
}
|
||||||
|
}
|
||||||
$this->assertEquals(
|
$this->assertEquals(
|
||||||
$expected,
|
$expected,
|
||||||
\CoreLibs\Convert\Colors::hex2rgb($input)
|
\CoreLibs\Convert\Colors::hex2rgb($input)
|
||||||
@@ -303,7 +385,7 @@ final class CoreLibsConvertColorsTest extends TestCase
|
|||||||
* Undocumented function
|
* Undocumented function
|
||||||
*
|
*
|
||||||
* @covers ::rgb2hsb
|
* @covers ::rgb2hsb
|
||||||
* @dataProvider rgb2hsbColorProvider
|
* @dataProvider providerRgb2hsbColor
|
||||||
* @testdox rgb2hsb $input_r,$input_g,$input_b will be $expected [$_dataName]
|
* @testdox rgb2hsb $input_r,$input_g,$input_b will be $expected [$_dataName]
|
||||||
*
|
*
|
||||||
* @param integer $input_r
|
* @param integer $input_r
|
||||||
@@ -312,8 +394,11 @@ final class CoreLibsConvertColorsTest extends TestCase
|
|||||||
* @param array|bool $expected
|
* @param array|bool $expected
|
||||||
* @return void
|
* @return void
|
||||||
*/
|
*/
|
||||||
public function testRgb2hsb(int $input_r, int $input_g, int $input_b, $expected): void
|
public function testRgb2hsb(int $input_r, int $input_g, int $input_b, array|bool $expected): void
|
||||||
{
|
{
|
||||||
|
if ($expected === false) {
|
||||||
|
$this->expectException(\LengthException::class);
|
||||||
|
}
|
||||||
$this->assertEquals(
|
$this->assertEquals(
|
||||||
$expected,
|
$expected,
|
||||||
\CoreLibs\Convert\Colors::rgb2hsb($input_r, $input_g, $input_b)
|
\CoreLibs\Convert\Colors::rgb2hsb($input_r, $input_g, $input_b)
|
||||||
@@ -324,7 +409,7 @@ final class CoreLibsConvertColorsTest extends TestCase
|
|||||||
* Undocumented function
|
* Undocumented function
|
||||||
*
|
*
|
||||||
* @covers ::hsb2rgb
|
* @covers ::hsb2rgb
|
||||||
* @dataProvider hsb2rgbColorProvider
|
* @dataProvider providerHsb2rgbColor
|
||||||
* @testdox hsb2rgb $input_h,$input_s,$input_b will be $expected [$_dataName]
|
* @testdox hsb2rgb $input_h,$input_s,$input_b will be $expected [$_dataName]
|
||||||
*
|
*
|
||||||
* @param float $input_h
|
* @param float $input_h
|
||||||
@@ -333,8 +418,12 @@ final class CoreLibsConvertColorsTest extends TestCase
|
|||||||
* @param array|bool $expected
|
* @param array|bool $expected
|
||||||
* @return void
|
* @return void
|
||||||
*/
|
*/
|
||||||
public function testHsb2rgb(float $input_h, float $input_s, float $input_b, $expected): void
|
public function testHsb2rgb(float $input_h, float $input_s, float $input_b, array|bool $expected): void
|
||||||
{
|
{
|
||||||
|
if ($expected === false) {
|
||||||
|
$this->expectException(\LengthException::class);
|
||||||
|
$expected = [];
|
||||||
|
}
|
||||||
$this->assertEquals(
|
$this->assertEquals(
|
||||||
$expected,
|
$expected,
|
||||||
\CoreLibs\Convert\Colors::hsb2rgb($input_h, $input_s, $input_b)
|
\CoreLibs\Convert\Colors::hsb2rgb($input_h, $input_s, $input_b)
|
||||||
@@ -345,7 +434,7 @@ final class CoreLibsConvertColorsTest extends TestCase
|
|||||||
* Undocumented function
|
* Undocumented function
|
||||||
*
|
*
|
||||||
* @covers ::rgb2hsl
|
* @covers ::rgb2hsl
|
||||||
* @dataProvider rgb2hslColorProvider
|
* @dataProvider providerRgb2hslColor
|
||||||
* @testdox rgb2hsl $input_r,$input_g,$input_b will be $expected [$_dataName]
|
* @testdox rgb2hsl $input_r,$input_g,$input_b will be $expected [$_dataName]
|
||||||
*
|
*
|
||||||
* @param integer $input_r
|
* @param integer $input_r
|
||||||
@@ -354,8 +443,11 @@ final class CoreLibsConvertColorsTest extends TestCase
|
|||||||
* @param array|bool $expected
|
* @param array|bool $expected
|
||||||
* @return void
|
* @return void
|
||||||
*/
|
*/
|
||||||
public function testRgb2hsl(int $input_r, int $input_g, int $input_b, $expected): void
|
public function testRgb2hsl(int $input_r, int $input_g, int $input_b, array|bool $expected): void
|
||||||
{
|
{
|
||||||
|
if ($expected === false) {
|
||||||
|
$this->expectException(\LengthException::class);
|
||||||
|
}
|
||||||
$this->assertEquals(
|
$this->assertEquals(
|
||||||
$expected,
|
$expected,
|
||||||
\CoreLibs\Convert\Colors::rgb2hsl($input_r, $input_g, $input_b)
|
\CoreLibs\Convert\Colors::rgb2hsl($input_r, $input_g, $input_b)
|
||||||
@@ -366,7 +458,7 @@ final class CoreLibsConvertColorsTest extends TestCase
|
|||||||
* Undocumented function
|
* Undocumented function
|
||||||
*
|
*
|
||||||
* @covers ::hsl2rgb
|
* @covers ::hsl2rgb
|
||||||
* @dataProvider hsl2rgbColorProvider
|
* @dataProvider providerHsl2rgbColor
|
||||||
* @testdox hsl2rgb $input_h,$input_s,$input_l will be $expected [$_dataName]
|
* @testdox hsl2rgb $input_h,$input_s,$input_l will be $expected [$_dataName]
|
||||||
*
|
*
|
||||||
* @param integer|float $input_h
|
* @param integer|float $input_h
|
||||||
@@ -375,13 +467,37 @@ final class CoreLibsConvertColorsTest extends TestCase
|
|||||||
* @param array|bool $expected
|
* @param array|bool $expected
|
||||||
* @return void
|
* @return void
|
||||||
*/
|
*/
|
||||||
public function testHsl2rgb($input_h, float $input_s, float $input_l, $expected): void
|
public function testHsl2rgb(int|float $input_h, float $input_s, float $input_l, array|bool $expected): void
|
||||||
{
|
{
|
||||||
|
if ($expected === false) {
|
||||||
|
$this->expectException(\LengthException::class);
|
||||||
|
}
|
||||||
$this->assertEquals(
|
$this->assertEquals(
|
||||||
$expected,
|
$expected,
|
||||||
\CoreLibs\Convert\Colors::hsl2rgb($input_h, $input_s, $input_l)
|
\CoreLibs\Convert\Colors::hsl2rgb($input_h, $input_s, $input_l)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* edge case check hsl/hsb and hue 360 (= 0)
|
||||||
|
*
|
||||||
|
* @covers ::hsl2rgb
|
||||||
|
* @covers ::hsb2rgb
|
||||||
|
* @testdox hsl2rgb/hsb2rgb hue 360 valid check
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function testHslHsb360hue(): void
|
||||||
|
{
|
||||||
|
$this->assertIsArray(
|
||||||
|
\CoreLibs\Convert\Colors::hsl2rgb(360.0, 90.5, 41.2),
|
||||||
|
'HSL to RGB with 360 hue'
|
||||||
|
);
|
||||||
|
$this->assertIsArray(
|
||||||
|
\CoreLibs\Convert\Colors::hsb2rgb(360, 95, 78.0),
|
||||||
|
'HSB to RGB with 360 hue'
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// __END__
|
// __END__
|
||||||
@@ -16,7 +16,7 @@ final class CoreLibsConvertJsonTest extends TestCase
|
|||||||
/**
|
/**
|
||||||
* test list for json convert tests
|
* test list for json convert tests
|
||||||
*
|
*
|
||||||
* @return array
|
* @return array<mixed>
|
||||||
*/
|
*/
|
||||||
public function jsonProvider(): array
|
public function jsonProvider(): array
|
||||||
{
|
{
|
||||||
@@ -54,10 +54,36 @@ final class CoreLibsConvertJsonTest extends TestCase
|
|||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Undocumented function
|
||||||
|
*
|
||||||
|
* @return array<mixed>
|
||||||
|
*/
|
||||||
|
public function jsonArrayProvider(): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'valid json' => [
|
||||||
|
[
|
||||||
|
'm' => 2,
|
||||||
|
'f' => 'sub_2'
|
||||||
|
],
|
||||||
|
'{"m":2,"f":"sub_2"}',
|
||||||
|
],
|
||||||
|
'empty json array' => [
|
||||||
|
[],
|
||||||
|
'[]'
|
||||||
|
],
|
||||||
|
'empty json hash' => [
|
||||||
|
['' => ''],
|
||||||
|
'{"":""}'
|
||||||
|
]
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* json error list
|
* json error list
|
||||||
*
|
*
|
||||||
* @return array JSON error list
|
* @return array<mixed> JSON error list
|
||||||
*/
|
*/
|
||||||
public function jsonErrorProvider(): array
|
public function jsonErrorProvider(): array
|
||||||
{
|
{
|
||||||
@@ -127,7 +153,7 @@ final class CoreLibsConvertJsonTest extends TestCase
|
|||||||
*
|
*
|
||||||
* @param string|null $input
|
* @param string|null $input
|
||||||
* @param bool $flag
|
* @param bool $flag
|
||||||
* @param array $expected
|
* @param array<mixed> $expected
|
||||||
* @return void
|
* @return void
|
||||||
*/
|
*/
|
||||||
public function testJsonConvertToArray(?string $input, bool $flag, array $expected): void
|
public function testJsonConvertToArray(?string $input, bool $flag, array $expected): void
|
||||||
@@ -138,6 +164,51 @@ final class CoreLibsConvertJsonTest extends TestCase
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* test with flags
|
||||||
|
*
|
||||||
|
* @covers ::jsonConvertToArray
|
||||||
|
* @testdox jsonConvertToArray flag test, if flag is used
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function testJsonConvertToArrayWithFlags(): void
|
||||||
|
{
|
||||||
|
$input = '{"valid":"json","invalid":"\xB1\x31"}';
|
||||||
|
/* $expected_without_flag = [
|
||||||
|
'valid' => 'json'
|
||||||
|
];
|
||||||
|
$expected_with_flag = [
|
||||||
|
'valid' => 'json',
|
||||||
|
'invalid' => "\xB1\x31"
|
||||||
|
]; */
|
||||||
|
// no idea why in both it throws an erro
|
||||||
|
$expected_without_flag = [];
|
||||||
|
$expected_with_flag = [];
|
||||||
|
$this->assertEquals(
|
||||||
|
$expected_without_flag,
|
||||||
|
\CoreLibs\Convert\Json::jsonConvertToArray($input)
|
||||||
|
);
|
||||||
|
$this->assertEquals(
|
||||||
|
$expected_with_flag,
|
||||||
|
\CoreLibs\Convert\Json::jsonConvertToArray($input, flags:JSON_INVALID_UTF8_IGNORE)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testJsonConvertToArrayRemoveThrowFlag(): void
|
||||||
|
{
|
||||||
|
$input = '{"valid":"json","invalid":"\xB1\x31"}';
|
||||||
|
// show NOT throw an exception
|
||||||
|
try {
|
||||||
|
$this->assertEquals(
|
||||||
|
[],
|
||||||
|
\CoreLibs\Convert\Json::jsonConvertToArray($input, flags:JSON_THROW_ON_ERROR)
|
||||||
|
);
|
||||||
|
} catch (\Exception $e) {
|
||||||
|
$this->fail('Exception was thrown despite flag removal');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* test json error states
|
* test json error states
|
||||||
*
|
*
|
||||||
@@ -146,7 +217,8 @@ final class CoreLibsConvertJsonTest extends TestCase
|
|||||||
* @testdox jsonGetLastError $input will be $expected_i/$expected_s [$_dataName]
|
* @testdox jsonGetLastError $input will be $expected_i/$expected_s [$_dataName]
|
||||||
*
|
*
|
||||||
* @param string|null $input
|
* @param string|null $input
|
||||||
* @param string $expected
|
* @param int $expected_i
|
||||||
|
* @param string $expected_s
|
||||||
* @return void
|
* @return void
|
||||||
*/
|
*/
|
||||||
public function testJsonGetLastError(?string $input, int $expected_i, string $expected_s): void
|
public function testJsonGetLastError(?string $input, int $expected_i, string $expected_s): void
|
||||||
@@ -161,6 +233,68 @@ final class CoreLibsConvertJsonTest extends TestCase
|
|||||||
\CoreLibs\Convert\Json::jsonGetLastError(true)
|
\CoreLibs\Convert\Json::jsonGetLastError(true)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* test json error states
|
||||||
|
*
|
||||||
|
* @covers ::jsonValidate
|
||||||
|
* @dataProvider jsonErrorProvider
|
||||||
|
* @testdox jsonValidate $input will be $expected_i/$expected_s [$_dataName]
|
||||||
|
*
|
||||||
|
* @param string|null $input
|
||||||
|
* @param int $expected_i
|
||||||
|
* @param string $expected_s
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function testJsonValidateGetLastError(?string $input, int $expected_i, string $expected_s): void
|
||||||
|
{
|
||||||
|
\CoreLibs\Convert\Json::jsonValidate($input);
|
||||||
|
$this->assertEquals(
|
||||||
|
$expected_i,
|
||||||
|
\CoreLibs\Convert\Json::jsonGetLastError()
|
||||||
|
);
|
||||||
|
$this->assertEquals(
|
||||||
|
$expected_s,
|
||||||
|
\CoreLibs\Convert\Json::jsonGetLastError(true)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* test json validation
|
||||||
|
*
|
||||||
|
* @covers ::jsonValidate
|
||||||
|
* @testdox jsonValidate test valid and invalid json
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function testJsonValidate(): void
|
||||||
|
{
|
||||||
|
$this->assertTrue(
|
||||||
|
\CoreLibs\Convert\Json::jsonValidate('{"valid": "json"}')
|
||||||
|
);
|
||||||
|
$this->assertFalse(
|
||||||
|
\CoreLibs\Convert\Json::jsonValidate('not valid json')
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Undocumented function
|
||||||
|
*
|
||||||
|
* @covers ::jsonConvertArrayTo
|
||||||
|
* @dataProvider jsonArrayProvider
|
||||||
|
* @testdox jsonConvertArrayTo $input (Override: $flag) will be $expected [$_dataName]
|
||||||
|
*
|
||||||
|
* @param array<mixed> $input
|
||||||
|
* @param string $expected
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function testJsonConvertArrayto(array $input, string $expected): void
|
||||||
|
{
|
||||||
|
$this->assertEquals(
|
||||||
|
$expected,
|
||||||
|
\CoreLibs\Convert\Json::jsonConvertArrayTo($input)
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// __END__
|
// __END__
|
||||||
504
4dev/tests/Convert/CoreLibsConvertMathTest.php
Normal file
504
4dev/tests/Convert/CoreLibsConvertMathTest.php
Normal file
@@ -0,0 +1,504 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace tests;
|
||||||
|
|
||||||
|
use PHPUnit\Framework\TestCase;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Undocumented class
|
||||||
|
* @coversDefaultClass \CoreLibs\Convert\Math
|
||||||
|
* @testdox \CoreLibs\Convert\Math method tests
|
||||||
|
*/
|
||||||
|
final class CoreLibsConvertMathTest extends TestCase
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Undocumented function
|
||||||
|
*
|
||||||
|
* @return array<mixed>
|
||||||
|
*/
|
||||||
|
public function providerFceil(): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'5.5 must be 6' => [5.5, 6],
|
||||||
|
'5.1234567890 with 5 must be 6' => [5.1234567890, 6],
|
||||||
|
'6 must be 6' => [6, 6]
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Undocumented function
|
||||||
|
*
|
||||||
|
* @covers ::fceil
|
||||||
|
* @dataProvider providerFceil
|
||||||
|
* @testdox fceil: Input $input must be $expected
|
||||||
|
*
|
||||||
|
* @param float $input
|
||||||
|
* @param int $expected
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function testMathFceilValue(float $input, int $expected): void
|
||||||
|
{
|
||||||
|
$this->assertEquals(
|
||||||
|
$expected,
|
||||||
|
\CoreLibs\Convert\Math::fceil($input)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Undocumented function
|
||||||
|
*
|
||||||
|
* @return array<mixed>
|
||||||
|
*/
|
||||||
|
public function providerFloor(): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'5123456 with -3 must be 5123000' => [5123456, -3, 5123000],
|
||||||
|
'5123456 with -10 must be 5000000' => [5123456, -10, 5000000]
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Undocumented function
|
||||||
|
*
|
||||||
|
* @covers ::floorp
|
||||||
|
* @dataProvider providerFloor
|
||||||
|
* @testdox floor: Input $input with cutoff $cutoff must be $expected
|
||||||
|
*
|
||||||
|
* @param int $input
|
||||||
|
* @param int $cutoff
|
||||||
|
* @param int $expected
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function testMathFloorValue(int $input, int $cutoff, int $expected): void
|
||||||
|
{
|
||||||
|
$this->assertEquals(
|
||||||
|
$expected,
|
||||||
|
\CoreLibs\Convert\Math::floorp($input, $cutoff)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Undocumented function
|
||||||
|
*
|
||||||
|
* @return array<mixed>
|
||||||
|
*/
|
||||||
|
public function providerInitNumeric(): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'5 must be 5' => [5, 5, 'int'],
|
||||||
|
'5.123 must be 5.123' => [5.123, 5.123, 'float'],
|
||||||
|
"'5' must be 5" => ['5', 5, 'string'],
|
||||||
|
"'5.123' must be 5.123" => ['5.123', 5.123, 'string'],
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Undocumented function
|
||||||
|
*
|
||||||
|
* @covers ::initNumeric
|
||||||
|
* @dataProvider providerInitNumeric
|
||||||
|
* @testdox initNumeric: Input $info $input must match $expected [$_dataName]
|
||||||
|
*
|
||||||
|
* @param int|float|string $input
|
||||||
|
* @param float $expected
|
||||||
|
* @param string $info
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function testMathInitNumericValue($input, float $expected, string $info): void
|
||||||
|
{
|
||||||
|
$this->assertEquals(
|
||||||
|
$expected,
|
||||||
|
\CoreLibs\Convert\Math::initNumeric($input)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Undocumented function
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function providerCbrt(): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'cube root of 2' => [2, 1.25992, 5, null],
|
||||||
|
'cube root of 3' => [3, 1.44225, 5, null],
|
||||||
|
'cube root of -1' => [-1, 'NAN', 0, \InvalidArgumentException::class],
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Undocumented function
|
||||||
|
*
|
||||||
|
* @covers ::cbrt
|
||||||
|
* @dataProvider providerCbrt
|
||||||
|
* @testdox initNumeric: Input $input must match $expected [$_dataName]
|
||||||
|
*
|
||||||
|
* @param float|int $number
|
||||||
|
* @param float $expected
|
||||||
|
* @param int $round_to
|
||||||
|
* @param ?string $exception
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function testCbrt(float|int $number, float|string $expected, int $round_to, ?string $exception): void
|
||||||
|
{
|
||||||
|
if ($exception !== null) {
|
||||||
|
$this->expectException($exception);
|
||||||
|
}
|
||||||
|
$this->assertEquals(
|
||||||
|
$expected,
|
||||||
|
round(\CoreLibs\Convert\Math::cbrt($number), $round_to)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Undocumented function
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function providerMultiplyMatrices(): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'[3] x [3] => [3x1]' => [
|
||||||
|
[1, 2, 3],
|
||||||
|
[1, 2, 3],
|
||||||
|
[14]
|
||||||
|
],
|
||||||
|
'[3] x [3x1]' => [
|
||||||
|
[1, 2, 3],
|
||||||
|
[[1], [2], [3]],
|
||||||
|
[14]
|
||||||
|
],
|
||||||
|
'[3] x [3x1]' => [
|
||||||
|
[1, 2, 3],
|
||||||
|
[[1], [2], [3]],
|
||||||
|
[14]
|
||||||
|
],
|
||||||
|
'[1x3L] x [3x1]' => [
|
||||||
|
[[1, 2, 3]],
|
||||||
|
[[1], [2], [3]],
|
||||||
|
[14]
|
||||||
|
],
|
||||||
|
'[1x3] x [3x1]' => [
|
||||||
|
[[1], [2], [3]],
|
||||||
|
[[1], [2], [3]],
|
||||||
|
[1, 2, 3]
|
||||||
|
],
|
||||||
|
'[2x3] x [3] => [3x1]' => [
|
||||||
|
[
|
||||||
|
[1, 2, 3],
|
||||||
|
[1, 2, 3]
|
||||||
|
],
|
||||||
|
[1, 2, 3],
|
||||||
|
[
|
||||||
|
14,
|
||||||
|
14
|
||||||
|
]
|
||||||
|
],
|
||||||
|
'[2x3] x [3x1]' => [
|
||||||
|
[
|
||||||
|
[1, 2, 3],
|
||||||
|
[1, 2, 3]
|
||||||
|
],
|
||||||
|
[[1], [2], [3]],
|
||||||
|
[
|
||||||
|
14,
|
||||||
|
14
|
||||||
|
]
|
||||||
|
],
|
||||||
|
'[2x3] x [2x3] => [3x3]' => [
|
||||||
|
[
|
||||||
|
[1, 2, 3],
|
||||||
|
[1, 2, 3],
|
||||||
|
],
|
||||||
|
[
|
||||||
|
[1, 2, 3],
|
||||||
|
[1, 2, 3],
|
||||||
|
],
|
||||||
|
[
|
||||||
|
[3, 6, 9],
|
||||||
|
[3, 6, 9]
|
||||||
|
]
|
||||||
|
],
|
||||||
|
'[2x3] x [3x3]' => [
|
||||||
|
[
|
||||||
|
[1, 2, 3],
|
||||||
|
[1, 2, 3],
|
||||||
|
],
|
||||||
|
[
|
||||||
|
[1, 2, 3],
|
||||||
|
[1, 2, 3],
|
||||||
|
[0, 0, 0],
|
||||||
|
],
|
||||||
|
[
|
||||||
|
[3, 6, 9],
|
||||||
|
[3, 6, 9]
|
||||||
|
]
|
||||||
|
],
|
||||||
|
'[2x3] x [3x2]' => [
|
||||||
|
'a' => [
|
||||||
|
[1, 2, 3],
|
||||||
|
[1, 2, 3],
|
||||||
|
],
|
||||||
|
'b' => [
|
||||||
|
[1, 1],
|
||||||
|
[2, 2],
|
||||||
|
[3, 3],
|
||||||
|
],
|
||||||
|
'prod' => [
|
||||||
|
[14, 14],
|
||||||
|
[14, 14],
|
||||||
|
]
|
||||||
|
],
|
||||||
|
'[3x3] x [3] => [1x3]' => [
|
||||||
|
[
|
||||||
|
[1, 2, 3],
|
||||||
|
[1, 2, 3],
|
||||||
|
[1, 2, 3],
|
||||||
|
],
|
||||||
|
[1, 2, 3],
|
||||||
|
[
|
||||||
|
14,
|
||||||
|
14,
|
||||||
|
14
|
||||||
|
]
|
||||||
|
],
|
||||||
|
'[3x3] x [2x3] => [3x3]' => [
|
||||||
|
[
|
||||||
|
[1, 2, 3],
|
||||||
|
[1, 2, 3],
|
||||||
|
[1, 2, 3],
|
||||||
|
],
|
||||||
|
[
|
||||||
|
[1, 2, 3],
|
||||||
|
[1, 2, 3],
|
||||||
|
],
|
||||||
|
[
|
||||||
|
[3, 6, 9],
|
||||||
|
[3, 6, 9],
|
||||||
|
[3, 6, 9],
|
||||||
|
]
|
||||||
|
],
|
||||||
|
'[3x3] x [3x3]' => [
|
||||||
|
[
|
||||||
|
[1, 2, 3],
|
||||||
|
[1, 2, 3],
|
||||||
|
[1, 2, 3],
|
||||||
|
],
|
||||||
|
[
|
||||||
|
[1, 2, 3],
|
||||||
|
[1, 2, 3],
|
||||||
|
// [0, 0, 0],
|
||||||
|
],
|
||||||
|
[
|
||||||
|
[3, 6, 9],
|
||||||
|
[3, 6, 9],
|
||||||
|
[3, 6, 9],
|
||||||
|
]
|
||||||
|
],
|
||||||
|
'[3] x [3x3]' => [
|
||||||
|
[1, 2, 3],
|
||||||
|
[
|
||||||
|
[1, 2, 3],
|
||||||
|
[1, 2, 3],
|
||||||
|
[1, 2, 3],
|
||||||
|
],
|
||||||
|
[
|
||||||
|
[6, 12, 18],
|
||||||
|
]
|
||||||
|
],
|
||||||
|
'[2x3] x [3x3]' => [
|
||||||
|
[
|
||||||
|
[1, 2, 3],
|
||||||
|
[1, 2, 3],
|
||||||
|
],
|
||||||
|
[
|
||||||
|
[1, 2, 3],
|
||||||
|
[1, 2, 3],
|
||||||
|
[1, 2, 3],
|
||||||
|
],
|
||||||
|
[
|
||||||
|
[6, 12, 18],
|
||||||
|
[6, 12, 18],
|
||||||
|
]
|
||||||
|
],
|
||||||
|
'inblanaced [2x2,3] x [3x2]' => [
|
||||||
|
'a' => [
|
||||||
|
[1, 2, 3],
|
||||||
|
[4, 5]
|
||||||
|
],
|
||||||
|
'b' => [
|
||||||
|
[6, 7],
|
||||||
|
[8, 9],
|
||||||
|
[10, 11]
|
||||||
|
],
|
||||||
|
'result' => [
|
||||||
|
[52, 58],
|
||||||
|
[64, 73],
|
||||||
|
]
|
||||||
|
],
|
||||||
|
'inblanaced [2x3] x [3x1,2]' => [
|
||||||
|
'a' => [
|
||||||
|
[1, 2, 3],
|
||||||
|
[4, 5, 7]
|
||||||
|
],
|
||||||
|
'b' => [
|
||||||
|
[7, 8],
|
||||||
|
[9, 10],
|
||||||
|
[11]
|
||||||
|
],
|
||||||
|
'result' => [
|
||||||
|
[58, 28],
|
||||||
|
[150, 82],
|
||||||
|
]
|
||||||
|
],
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Undocumented function
|
||||||
|
*
|
||||||
|
* @covers ::multiplyMatrices
|
||||||
|
* @dataProvider providerMultiplyMatrices
|
||||||
|
* @testdox initNumeric: Input $input_a x $input_b must match $expected [$_dataName]
|
||||||
|
*
|
||||||
|
* @param array $input_a
|
||||||
|
* @param array $input_b
|
||||||
|
* @param array $expected
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function testMultiplyMatrices(array $input_a, array $input_b, array $expected): void
|
||||||
|
{
|
||||||
|
$this->assertEquals(
|
||||||
|
$expected,
|
||||||
|
\CoreLibs\Convert\Math::multiplyMatrices($input_a, $input_b)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Undocumented function
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function providerEqualWithEpsilon(): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'equal' => [
|
||||||
|
'a' => 0.000000000000000222,
|
||||||
|
'b' => 0.000000000000000222,
|
||||||
|
'epsilon' => PHP_FLOAT_EPSILON,
|
||||||
|
'equal' => true,
|
||||||
|
],
|
||||||
|
'almost equal' => [
|
||||||
|
'a' => 0.000000000000000222,
|
||||||
|
'b' => 0.000000000000000232,
|
||||||
|
'epsilon' => PHP_FLOAT_EPSILON,
|
||||||
|
'equal' => true,
|
||||||
|
],
|
||||||
|
'not equal' => [
|
||||||
|
'a' => 0.000000000000000222,
|
||||||
|
'b' => 0.000000000000004222,
|
||||||
|
'epsilon' => PHP_FLOAT_EPSILON,
|
||||||
|
'equal' => false,
|
||||||
|
],
|
||||||
|
'equal, different epsilon' => [
|
||||||
|
'a' => 0.000000000000000222,
|
||||||
|
'b' => 0.000000000000004222,
|
||||||
|
'epsilon' => 0.0001,
|
||||||
|
'equal' => true,
|
||||||
|
],
|
||||||
|
'not equal, different epsilon' => [
|
||||||
|
'a' => 0.0001,
|
||||||
|
'b' => 0.0002,
|
||||||
|
'epsilon' => 0.0001,
|
||||||
|
'equal' => false,
|
||||||
|
]
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Undocumented function
|
||||||
|
*
|
||||||
|
* @covers ::equalWithEpsilon
|
||||||
|
* @dataProvider providerEqualWithEpsilon
|
||||||
|
* @testdox equalWithEpsilon with $a and $b and Epsilon: $epsilon must be equal: $equal [$_dataName]
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function testEqualWithEpsilon(float $a, float $b, float $epsilon, bool $equal): void
|
||||||
|
{
|
||||||
|
$this->assertEquals(
|
||||||
|
$equal,
|
||||||
|
\CoreLibs\Convert\Math::equalWithEpsilon($a, $b, $epsilon)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Undocumented function
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function providerCompareWithEpsilon(): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'smaller, true' => [
|
||||||
|
'value' => 0.0001,
|
||||||
|
'compare' => '<',
|
||||||
|
'limit' => 0.0002,
|
||||||
|
'epsilon' => 0.00001,
|
||||||
|
'match' => true,
|
||||||
|
],
|
||||||
|
'smaller, false' => [
|
||||||
|
'value' => 0.0001,
|
||||||
|
'compare' => '<',
|
||||||
|
'limit' => 0.0001,
|
||||||
|
'epsilon' => 0.00001,
|
||||||
|
'match' => false,
|
||||||
|
],
|
||||||
|
'bigger, true' => [
|
||||||
|
'value' => 0.0002,
|
||||||
|
'compare' => '>',
|
||||||
|
'limit' => 0.0001,
|
||||||
|
'epsilon' => 0.00001,
|
||||||
|
'match' => true,
|
||||||
|
],
|
||||||
|
'bigger, false' => [
|
||||||
|
'value' => 0.0001,
|
||||||
|
'compare' => '>',
|
||||||
|
'limit' => 0.0001,
|
||||||
|
'epsilon' => 0.00001,
|
||||||
|
'match' => false,
|
||||||
|
],
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Undocumented function
|
||||||
|
*
|
||||||
|
* @covers ::compareWithEpsilon
|
||||||
|
* @dataProvider providerCompareWithEpsilon
|
||||||
|
* @testdox compareWithEpsilon $value $compare $limit with $epsilon must match: $match [$_dataName]
|
||||||
|
*
|
||||||
|
* @param float $value
|
||||||
|
* @param string $compare
|
||||||
|
* @param float $limit
|
||||||
|
* @param float $epslion
|
||||||
|
* @param bool $match
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function testCompareWithEpsilon(
|
||||||
|
float $value,
|
||||||
|
string $compare,
|
||||||
|
float $limit,
|
||||||
|
float $epsilon,
|
||||||
|
bool $match
|
||||||
|
): void {
|
||||||
|
$this->assertEquals(
|
||||||
|
$match,
|
||||||
|
\CoreLibs\Convert\Math::compareWithEpsilon($value, $compare, $limit, $epsilon)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// __END__
|
||||||
@@ -33,15 +33,14 @@ final class CoreLibsConvertMimeEncodeTest extends TestCase
|
|||||||
'The quick brown fox jumps over the lazy sheep that sleeps in the ravine '
|
'The quick brown fox jumps over the lazy sheep that sleeps in the ravine '
|
||||||
. 'and has no idea what is going on here',
|
. 'and has no idea what is going on here',
|
||||||
'UTF-8',
|
'UTF-8',
|
||||||
'The quick brown fox jumps over the lazy sheep that sleeps in the ravine '
|
"The quick brown fox jumps over the lazy sheep that sleeps in the ravine and\r\n"
|
||||||
. 'and has no idea what is going on here'
|
. ' has no idea what is going on here'
|
||||||
],
|
],
|
||||||
'standard with special chars UTF-8' => [
|
'standard with special chars UTF-8' => [
|
||||||
'This is ümläßtと漢字もカタカナ!!^$%&',
|
'This is ümläßtと漢字もカタカナ!!^$%&',
|
||||||
'UTF-8',
|
'UTF-8',
|
||||||
'This is =?UTF-8?B?w7xtbMOkw59044Go5ryi5a2X44KC44Kr44K/44Kr44OK77yBIV4k?='
|
"This is =?UTF-8?B?w7xtbMOkw59044Go5ryi5a2X44KC44Kr44K/44Kr44OK77yBIV4k?=\r\n"
|
||||||
. "\r\n"
|
. ' =?UTF-8?B?JSY=?='
|
||||||
. ' =?UTF-8?B?JQ==?=&'
|
|
||||||
],
|
],
|
||||||
'35 chars and space at the end UTF-8' => [
|
'35 chars and space at the end UTF-8' => [
|
||||||
'12345678901234567890123456789012345 '
|
'12345678901234567890123456789012345 '
|
||||||
@@ -62,9 +61,8 @@ final class CoreLibsConvertMimeEncodeTest extends TestCase
|
|||||||
. 'is there a space?',
|
. 'is there a space?',
|
||||||
'UTF-8',
|
'UTF-8',
|
||||||
"=?UTF-8?B?44Kr44K/44Kr44OK44Kr44K/44Kr44OK44GL44Gq44Kr44K/44Kr44OK44Kr?=\r\n"
|
"=?UTF-8?B?44Kr44K/44Kr44OK44Kr44K/44Kr44OK44GL44Gq44Kr44K/44Kr44OK44Kr?=\r\n"
|
||||||
. " =?UTF-8?B?44K/44Kr44OK?=\r\n"
|
. " =?UTF-8?B?44K/44Kr44OK44GL44Gq44Kr44K/44Kr44OK44Kr44K/44Kr44OK44GL44Gq?=\r\n"
|
||||||
. " =?UTF-8?B?44GL44Gq44Kr44K/44Kr44OK44Kr44K/44Kr44OK44GL44Gq44Kr44K/44Kr?=\r\n"
|
. " =?UTF-8?B?44Kr44K/44Kr44OK44Kr44K/IGlzIHRoZXJlIGEgc3BhY2U/?="
|
||||||
. " =?UTF-8?B?44OK44Kr44K/?= is there a =?UTF-8?B?c3BhY2U/?="
|
|
||||||
]
|
]
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
@@ -85,16 +83,28 @@ final class CoreLibsConvertMimeEncodeTest extends TestCase
|
|||||||
// print "MIME: -" . $encoded . "-\n";
|
// print "MIME: -" . $encoded . "-\n";
|
||||||
$this->assertEquals(
|
$this->assertEquals(
|
||||||
$expected,
|
$expected,
|
||||||
$encoded
|
$encoded,
|
||||||
|
"__mbMimeEncode"
|
||||||
);
|
);
|
||||||
$decoded = mb_decode_mimeheader($encoded);
|
$decoded = mb_decode_mimeheader($encoded);
|
||||||
// print "INPUT : " . $input . "\n";
|
// print "ENCODED: " . $encoded . "\n";
|
||||||
// print "DECODED: " . $decoded . "\n";
|
// print "INPUT : " . $input . " | " . mb_strlen($input) . "\n";
|
||||||
|
// print "DECODED: " . $decoded . " | " . mb_strlen($decoded) . "\n";
|
||||||
|
// $test_enc = mb_encode_mimeheader($input, $encoding);
|
||||||
|
// $test_dec = mb_decode_mimeheader($test_enc);
|
||||||
|
// print "TEST ENC: " . $test_enc . "\n";
|
||||||
// back compare decoded
|
// back compare decoded
|
||||||
$this->assertEquals(
|
$this->assertEquals(
|
||||||
$input,
|
$input,
|
||||||
$decoded
|
$decoded,
|
||||||
|
"mb_decode_mimeheader"
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// $this->assertEquals(
|
||||||
|
// $input,
|
||||||
|
// $test_dec,
|
||||||
|
// 'mb_encode_to_decode'
|
||||||
|
// );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
657
4dev/tests/Convert/CoreLibsConvertSetVarTypeNullTest.php
Normal file
657
4dev/tests/Convert/CoreLibsConvertSetVarTypeNullTest.php
Normal file
@@ -0,0 +1,657 @@
|
|||||||
|
<?php // phpcs:disable Generic.Files.LineLength
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace tests;
|
||||||
|
|
||||||
|
use PHPUnit\Framework\TestCase;
|
||||||
|
use CoreLibs\Convert\SetVarTypeNull;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test class for Convert\Strings
|
||||||
|
* @coversDefaultClass \CoreLibs\Convert\SetVarTypeNull
|
||||||
|
* @testdox \CoreLibs\Convert\SetVarTypeNull method tests
|
||||||
|
*/
|
||||||
|
final class CoreLibsConvertSetVarTypeNullTest extends TestCase
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Undocumented function
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function varSetTypeStringProvider(): array
|
||||||
|
{
|
||||||
|
// 0: input
|
||||||
|
// 1: default (null default)
|
||||||
|
// 2: expected
|
||||||
|
return [
|
||||||
|
'empty string' => [
|
||||||
|
'',
|
||||||
|
null,
|
||||||
|
''
|
||||||
|
],
|
||||||
|
'filled string' => [
|
||||||
|
'string',
|
||||||
|
null,
|
||||||
|
'string'
|
||||||
|
],
|
||||||
|
'valid string, override set' => [
|
||||||
|
'string',
|
||||||
|
'override',
|
||||||
|
'string'
|
||||||
|
],
|
||||||
|
'int, no override' => [
|
||||||
|
1,
|
||||||
|
null,
|
||||||
|
'1'
|
||||||
|
],
|
||||||
|
'int, override set' => [
|
||||||
|
1,
|
||||||
|
'not int',
|
||||||
|
'1'
|
||||||
|
],
|
||||||
|
'array, override set' => [
|
||||||
|
[1, 2],
|
||||||
|
null,
|
||||||
|
null
|
||||||
|
]
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Undocumented function
|
||||||
|
* @covers ::setStr
|
||||||
|
* @dataProvider varSetTypeStringProvider
|
||||||
|
* @testdox setStr $input with override $default will be $expected [$_dataName]
|
||||||
|
*
|
||||||
|
* @param mixed $input
|
||||||
|
* @param string|null $default
|
||||||
|
* @param string|null $expected
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function testSetString(mixed $input, ?string $default, ?string $expected): void
|
||||||
|
{
|
||||||
|
$set_var = SetVarTypeNull::setStr($input, $default);
|
||||||
|
if ($expected !== null) {
|
||||||
|
$this->assertIsString($set_var);
|
||||||
|
} else {
|
||||||
|
$this->assertNull($set_var);
|
||||||
|
}
|
||||||
|
$this->assertEquals(
|
||||||
|
$expected,
|
||||||
|
$set_var
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Undocumented function
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function varMakeTypeStringProvider(): array
|
||||||
|
{
|
||||||
|
// 0: input
|
||||||
|
// 1: default (null default)
|
||||||
|
// 2: expected
|
||||||
|
return [
|
||||||
|
'empty string' => [
|
||||||
|
'',
|
||||||
|
null,
|
||||||
|
''
|
||||||
|
],
|
||||||
|
'filled string' => [
|
||||||
|
'string',
|
||||||
|
null,
|
||||||
|
'string'
|
||||||
|
],
|
||||||
|
'valid string, override set' => [
|
||||||
|
'string',
|
||||||
|
'override',
|
||||||
|
'string'
|
||||||
|
],
|
||||||
|
'int, no override' => [
|
||||||
|
1,
|
||||||
|
null,
|
||||||
|
'1'
|
||||||
|
],
|
||||||
|
'int, override set' => [
|
||||||
|
1,
|
||||||
|
'not int',
|
||||||
|
'1'
|
||||||
|
],
|
||||||
|
'float, no override' => [
|
||||||
|
1.5,
|
||||||
|
null,
|
||||||
|
'1.5'
|
||||||
|
],
|
||||||
|
// all the strange things here
|
||||||
|
'function, override set' => [
|
||||||
|
$foo = function () {
|
||||||
|
return '';
|
||||||
|
},
|
||||||
|
'function',
|
||||||
|
'function'
|
||||||
|
],
|
||||||
|
'function, no override' => [
|
||||||
|
$foo = function () {
|
||||||
|
return '';
|
||||||
|
},
|
||||||
|
null,
|
||||||
|
null
|
||||||
|
],
|
||||||
|
'hex value, override set' => [
|
||||||
|
0x55,
|
||||||
|
'hex',
|
||||||
|
'85'
|
||||||
|
]
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Undocumented function
|
||||||
|
* @covers ::makeStr
|
||||||
|
* @dataProvider varMakeTypeStringProvider
|
||||||
|
* @testdox makeStr $input with override $default will be $expected [$_dataName]
|
||||||
|
*
|
||||||
|
* @param mixed $input
|
||||||
|
* @param string|null $default
|
||||||
|
* @param string|null $expected
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function testMakeString(mixed $input, ?string $default, ?string $expected): void
|
||||||
|
{
|
||||||
|
$set_var = SetVarTypeNull::makeStr($input, $default);
|
||||||
|
if ($expected !== null) {
|
||||||
|
$this->assertIsString($set_var);
|
||||||
|
} else {
|
||||||
|
$this->assertNull($set_var);
|
||||||
|
}
|
||||||
|
$this->assertEquals(
|
||||||
|
$expected,
|
||||||
|
$set_var
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Undocumented function
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function varSetTypeIntProvider(): array
|
||||||
|
{
|
||||||
|
// 0: input
|
||||||
|
// 1: default (null default)
|
||||||
|
// 2: expected
|
||||||
|
return [
|
||||||
|
'int' => [
|
||||||
|
1,
|
||||||
|
null,
|
||||||
|
1
|
||||||
|
],
|
||||||
|
'int, override set' => [
|
||||||
|
1,
|
||||||
|
-1,
|
||||||
|
1
|
||||||
|
],
|
||||||
|
'string, no override' => [
|
||||||
|
'string',
|
||||||
|
null,
|
||||||
|
null
|
||||||
|
],
|
||||||
|
'string, override' => [
|
||||||
|
'string',
|
||||||
|
-1,
|
||||||
|
-1
|
||||||
|
],
|
||||||
|
'float' => [
|
||||||
|
1.5,
|
||||||
|
null,
|
||||||
|
1
|
||||||
|
]
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Undocumented function
|
||||||
|
* @covers ::setInt
|
||||||
|
* @dataProvider varSetTypeIntProvider
|
||||||
|
* @testdox setInt $input with override $default will be $expected [$_dataName]
|
||||||
|
*
|
||||||
|
* @param mixed $input
|
||||||
|
* @param int|null $default
|
||||||
|
* @param int|null $expected
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function testSetInt(mixed $input, ?int $default, ?int $expected): void
|
||||||
|
{
|
||||||
|
$set_var = SetVarTypeNull::setInt($input, $default);
|
||||||
|
if ($expected !== null) {
|
||||||
|
$this->assertIsInt($set_var);
|
||||||
|
} else {
|
||||||
|
$this->assertNull($set_var);
|
||||||
|
}
|
||||||
|
$this->assertEquals(
|
||||||
|
$expected,
|
||||||
|
$set_var
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Undocumented function
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function varMakeTypeIntProvider(): array
|
||||||
|
{
|
||||||
|
// 0: input
|
||||||
|
// 1: default (null default)
|
||||||
|
// 2: expected
|
||||||
|
return [
|
||||||
|
'int' => [
|
||||||
|
1,
|
||||||
|
null,
|
||||||
|
1
|
||||||
|
],
|
||||||
|
'int, override set' => [
|
||||||
|
1,
|
||||||
|
-1,
|
||||||
|
1
|
||||||
|
],
|
||||||
|
'string, no override' => [
|
||||||
|
'string',
|
||||||
|
null,
|
||||||
|
0
|
||||||
|
],
|
||||||
|
'string, override' => [
|
||||||
|
'string',
|
||||||
|
-1,
|
||||||
|
0
|
||||||
|
],
|
||||||
|
'float' => [
|
||||||
|
1.5,
|
||||||
|
null,
|
||||||
|
1
|
||||||
|
],
|
||||||
|
// all the strange things here
|
||||||
|
'function, override set' => [
|
||||||
|
$foo = function () {
|
||||||
|
return '';
|
||||||
|
},
|
||||||
|
-1,
|
||||||
|
-1
|
||||||
|
],
|
||||||
|
'function, no override ' => [
|
||||||
|
$foo = function () {
|
||||||
|
return '';
|
||||||
|
},
|
||||||
|
null,
|
||||||
|
null
|
||||||
|
],
|
||||||
|
'hex value, override set' => [
|
||||||
|
0x55,
|
||||||
|
-1,
|
||||||
|
85
|
||||||
|
],
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Undocumented function
|
||||||
|
* @covers ::makeInt
|
||||||
|
* @dataProvider varMakeTypeIntProvider
|
||||||
|
* @testdox makeInt $input with override $default will be $expected [$_dataName]
|
||||||
|
*
|
||||||
|
* @param mixed $input
|
||||||
|
* @param int|null $default
|
||||||
|
* @param int|null $expected
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function testMakeInt(mixed $input, ?int $default, ?int $expected): void
|
||||||
|
{
|
||||||
|
$set_var = SetVarTypeNull::makeInt($input, $default);
|
||||||
|
if ($expected !== null) {
|
||||||
|
$this->assertIsInt($set_var);
|
||||||
|
} else {
|
||||||
|
$this->assertNull($set_var);
|
||||||
|
}
|
||||||
|
$this->assertEquals(
|
||||||
|
$expected,
|
||||||
|
$set_var
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Undocumented function
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function varSetTypeFloatProvider(): array
|
||||||
|
{
|
||||||
|
// 0: input
|
||||||
|
// 1: default (null default)
|
||||||
|
// 2: expected
|
||||||
|
return [
|
||||||
|
'float' => [
|
||||||
|
1.5,
|
||||||
|
null,
|
||||||
|
1.5
|
||||||
|
],
|
||||||
|
'float, override set' => [
|
||||||
|
1.5,
|
||||||
|
-1.5,
|
||||||
|
1.5
|
||||||
|
],
|
||||||
|
'string, no override' => [
|
||||||
|
'string',
|
||||||
|
null,
|
||||||
|
null
|
||||||
|
],
|
||||||
|
'string, override' => [
|
||||||
|
'string',
|
||||||
|
1.5,
|
||||||
|
1.5
|
||||||
|
],
|
||||||
|
'int' => [
|
||||||
|
1,
|
||||||
|
null,
|
||||||
|
1.0
|
||||||
|
]
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Undocumented function
|
||||||
|
* @covers ::setFloat
|
||||||
|
* @dataProvider varSetTypeFloatProvider
|
||||||
|
* @testdox setFloat $input with override $default will be $expected [$_dataName]
|
||||||
|
*
|
||||||
|
* @param mixed $input
|
||||||
|
* @param float|null $default
|
||||||
|
* @param float|null $expected
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function testSetFloat(mixed $input, ?float $default, ?float $expected): void
|
||||||
|
{
|
||||||
|
$set_var = SetVarTypeNull::setFloat($input, $default);
|
||||||
|
if ($expected !== null) {
|
||||||
|
$this->assertIsFloat($set_var);
|
||||||
|
} else {
|
||||||
|
$this->assertNull($set_var);
|
||||||
|
}
|
||||||
|
$this->assertEquals(
|
||||||
|
$expected,
|
||||||
|
$set_var
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Undocumented function
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function varMakeTypeFloatProvider(): array
|
||||||
|
{
|
||||||
|
// 0: input
|
||||||
|
// 1: default (null default)
|
||||||
|
// 2: expected
|
||||||
|
return [
|
||||||
|
'float' => [
|
||||||
|
1.5,
|
||||||
|
null,
|
||||||
|
1.5
|
||||||
|
],
|
||||||
|
'float, override set' => [
|
||||||
|
1.5,
|
||||||
|
-1.5,
|
||||||
|
1.5
|
||||||
|
],
|
||||||
|
'string, no override' => [
|
||||||
|
'string',
|
||||||
|
null,
|
||||||
|
0.0
|
||||||
|
],
|
||||||
|
'string, override' => [
|
||||||
|
'string',
|
||||||
|
1.5,
|
||||||
|
0.0
|
||||||
|
],
|
||||||
|
'int' => [
|
||||||
|
1,
|
||||||
|
null,
|
||||||
|
1.0
|
||||||
|
],
|
||||||
|
// all the strange things here
|
||||||
|
'function, override set' => [
|
||||||
|
$foo = function () {
|
||||||
|
return '';
|
||||||
|
},
|
||||||
|
-1.0,
|
||||||
|
-1.0
|
||||||
|
],
|
||||||
|
// all the strange things here
|
||||||
|
'function, no override' => [
|
||||||
|
$foo = function () {
|
||||||
|
return '';
|
||||||
|
},
|
||||||
|
null,
|
||||||
|
null
|
||||||
|
],
|
||||||
|
'hex value, override set' => [
|
||||||
|
0x55,
|
||||||
|
-1,
|
||||||
|
85.0
|
||||||
|
],
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Undocumented function
|
||||||
|
* @covers ::makeFloat
|
||||||
|
* @dataProvider varMakeTypeFloatProvider
|
||||||
|
* @testdox makeFloat $input with override $default will be $expected [$_dataName]
|
||||||
|
*
|
||||||
|
* @param mixed $input
|
||||||
|
* @param float|null $default
|
||||||
|
* @param float|null $expected
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function testMakeFloat(mixed $input, ?float $default, ?float $expected): void
|
||||||
|
{
|
||||||
|
$set_var = SetVarTypeNull::makeFloat($input, $default);
|
||||||
|
if ($expected !== null) {
|
||||||
|
$this->assertIsFloat($set_var);
|
||||||
|
} else {
|
||||||
|
$this->assertNull($set_var);
|
||||||
|
}
|
||||||
|
$this->assertEquals(
|
||||||
|
$expected,
|
||||||
|
$set_var
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Undocumented function
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function varSetTypeArrayProvider(): array
|
||||||
|
{
|
||||||
|
// 0: input
|
||||||
|
// 1: default (null default)
|
||||||
|
// 2: expected
|
||||||
|
return [
|
||||||
|
'array, empty' => [
|
||||||
|
[],
|
||||||
|
null,
|
||||||
|
[]
|
||||||
|
],
|
||||||
|
'array, filled' => [
|
||||||
|
['array'],
|
||||||
|
null,
|
||||||
|
['array']
|
||||||
|
],
|
||||||
|
'string, no override' => [
|
||||||
|
'string',
|
||||||
|
null,
|
||||||
|
null
|
||||||
|
],
|
||||||
|
'string, override' => [
|
||||||
|
'string',
|
||||||
|
['string'],
|
||||||
|
['string']
|
||||||
|
]
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Undocumented function
|
||||||
|
* @covers ::setArray
|
||||||
|
* @dataProvider varSetTypeArrayProvider
|
||||||
|
* @testdox setArray $input with override $default will be $expected [$_dataName]
|
||||||
|
*
|
||||||
|
* @param mixed $input
|
||||||
|
* @param array|null $default
|
||||||
|
* @param array|null $expected
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function testSetArray(mixed $input, ?array $default, ?array $expected): void
|
||||||
|
{
|
||||||
|
$set_var = SetVarTypeNull::setArray($input, $default);
|
||||||
|
if ($expected !== null) {
|
||||||
|
$this->assertIsArray($set_var);
|
||||||
|
} else {
|
||||||
|
$this->assertNull($set_var);
|
||||||
|
}
|
||||||
|
$this->assertEquals(
|
||||||
|
$expected,
|
||||||
|
$set_var
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Undocumented function
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function varSetTypeBoolProvider(): array
|
||||||
|
{
|
||||||
|
// 0: input
|
||||||
|
// 1: default (null default)
|
||||||
|
// 2: expected
|
||||||
|
return [
|
||||||
|
'bool true' => [
|
||||||
|
true,
|
||||||
|
null,
|
||||||
|
true
|
||||||
|
],
|
||||||
|
'bool false' => [
|
||||||
|
false,
|
||||||
|
null,
|
||||||
|
false
|
||||||
|
],
|
||||||
|
'string, no override' => [
|
||||||
|
'string',
|
||||||
|
null,
|
||||||
|
null
|
||||||
|
],
|
||||||
|
'string, override' => [
|
||||||
|
'string',
|
||||||
|
true,
|
||||||
|
true
|
||||||
|
]
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Undocumented function
|
||||||
|
* @covers ::setBool
|
||||||
|
* @dataProvider varSetTypeBoolProvider
|
||||||
|
* @testdox setBool $input with override $default will be $expected [$_dataName]
|
||||||
|
*
|
||||||
|
* @param mixed $input
|
||||||
|
* @param bool|null $default
|
||||||
|
* @param bool|null $expected
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function testSetBool(mixed $input, ?bool $default, ?bool $expected): void
|
||||||
|
{
|
||||||
|
$set_var = SetVarTypeNull::setBool($input, $default);
|
||||||
|
if ($expected !== null) {
|
||||||
|
$this->assertIsBool($set_var);
|
||||||
|
} else {
|
||||||
|
$this->assertNull($set_var);
|
||||||
|
}
|
||||||
|
$this->assertEquals(
|
||||||
|
$expected,
|
||||||
|
$set_var
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Undocumented function
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function varMakeTypeBoolProvider(): array
|
||||||
|
{
|
||||||
|
// 0: input
|
||||||
|
// 2: expected
|
||||||
|
return [
|
||||||
|
'true' => [
|
||||||
|
true,
|
||||||
|
true
|
||||||
|
],
|
||||||
|
'false' => [
|
||||||
|
false,
|
||||||
|
false
|
||||||
|
],
|
||||||
|
'string on' => [
|
||||||
|
'on',
|
||||||
|
true
|
||||||
|
],
|
||||||
|
'string off' => [
|
||||||
|
'off',
|
||||||
|
false
|
||||||
|
],
|
||||||
|
'invalid string' => [
|
||||||
|
'sulzenbacher',
|
||||||
|
null,
|
||||||
|
],
|
||||||
|
'invalid string, override' => [
|
||||||
|
'sulzenbacher',
|
||||||
|
null,
|
||||||
|
],
|
||||||
|
'array to default' => [
|
||||||
|
[],
|
||||||
|
false
|
||||||
|
],
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Undocumented function
|
||||||
|
* @covers ::setBool
|
||||||
|
* @dataProvider varMakeTypeBoolProvider
|
||||||
|
* @testdox setBool $input will be $expected [$_dataName]
|
||||||
|
*
|
||||||
|
* @param mixed $input
|
||||||
|
* @param bool|null $default
|
||||||
|
* @param bool|null $expected
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function testMakeBool(mixed $input, ?bool $expected): void
|
||||||
|
{
|
||||||
|
$set_var = SetVarTypeNull::makeBool($input);
|
||||||
|
if ($expected !== null) {
|
||||||
|
$this->assertIsBool($set_var);
|
||||||
|
} else {
|
||||||
|
$this->assertNull($set_var);
|
||||||
|
}
|
||||||
|
$this->assertEquals(
|
||||||
|
$expected,
|
||||||
|
$set_var
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// __END__
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user