Compare commits
344 Commits
master
...
release-1.
Author | SHA1 | Date |
---|---|---|
Aleksander Machniak | 0ba44f0d92 | 6 years ago |
Aleksander Machniak | e252736ef1 | 6 years ago |
Thomas Bruederli | 0b42424e41 | 7 years ago |
Aleksander Machniak | 4f5d8ab015 | 7 years ago |
Aleksander Machniak | 8d87bb34f3 | 7 years ago |
Thomas Bruederli | ca74231733 | 7 years ago |
Aleksander Machniak | 62edcc6283 | 7 years ago |
Aleksander Machniak | 271426429b | 7 years ago |
Thomas Bruederli | 511793c25f | 7 years ago |
Thomas Bruederli | 37cae3ecfa | 7 years ago |
Aleksander Machniak | b0f57a7edc | 7 years ago |
Aleksander Machniak | a54dde834c | 8 years ago |
Aleksander Machniak | 5d2aaa68c3 | 8 years ago |
Aleksander Machniak | dc0c6067b7 | 8 years ago |
Aleksander Machniak | 1e275ac13a | 8 years ago |
Aleksander Machniak | f1ca20d993 | 8 years ago |
Thomas Bruederli | 7b37ef8a33 | 8 years ago |
Aleksander Machniak | acf633c73b | 8 years ago |
Thomas Bruederli | cde7a9eb74 | 8 years ago |
Thomas Bruederli | b76d8e91d6 | 8 years ago |
Aleksander Machniak | 74c75ee529 | 8 years ago |
Thomas Bruederli | fca89f0e77 | 8 years ago |
Aleksander Machniak | 10f24c034b | 8 years ago |
Aleksander Machniak | 3c988b0f08 | 8 years ago |
Aleksander Machniak | 5466f71dd6 | 8 years ago |
Aleksander Machniak | efe06f2b12 | 8 years ago |
Aleksander Machniak | b2d4cfa89a | 8 years ago |
Aleksander Machniak | 3e12784cc2 | 8 years ago |
Aleksander Machniak | 7496302945 | 8 years ago |
Aleksander Machniak | a7fac6afb6 | 8 years ago |
Aleksander Machniak | 889989db06 | 8 years ago |
Aleksander Machniak | 73f8b524f3 | 8 years ago |
Aleksander Machniak | 190c658fe3 | 8 years ago |
Aleksander Machniak | ffd5ffc30a | 8 years ago |
Aleksander Machniak | 3faf89c354 | 8 years ago |
Francis Russell | e77b5f7dd7 | 9 years ago |
Francis Russell | 6a70e56e5e | 9 years ago |
Thomas Bruederli | 2c0a550105 | 9 years ago |
Aleksander Machniak | 222f47c042 | 9 years ago |
Aleksander Machniak | 82fcd4e757 | 9 years ago |
Aleksander Machniak | 21b523c29b | 9 years ago |
Aleksander Machniak | 50403d66e0 | 9 years ago |
Aleksander Machniak | 5579ef6621 | 9 years ago |
Aleksander Machniak | 6402eb7f78 | 9 years ago |
Aleksander Machniak | e7d1a80a80 | 9 years ago |
Aleksander Machniak | 48ab1add35 | 9 years ago |
Thomas Bruederli | 7bd7d60add | 9 years ago |
Aleksander Machniak | 969547784e | 9 years ago |
Aleksander Machniak | 4ec947715d | 9 years ago |
Aleksander Machniak | 175ca6fd65 | 9 years ago |
Aleksander Machniak | 98a61c74ee | 9 years ago |
Aleksander Machniak | 3b59a32026 | 9 years ago |
Aleksander Machniak | e6939619f7 | 9 years ago |
Aleksander Machniak | 6ab1553b5e | 9 years ago |
Aleksander Machniak | 8cded09621 | 9 years ago |
Aleksander Machniak | eb318205fc | 9 years ago |
Aleksander Machniak | 67229a86df | 9 years ago |
Aleksander Machniak | d1fa2f7f7a | 9 years ago |
Thomas Bruederli | ccaf87415e | 9 years ago |
Aleksander Machniak | 4b61f35dc9 | 9 years ago |
Aleksander Machniak | a7e552b5a4 | 9 years ago |
Aleksander Machniak | c5157fb74a | 9 years ago |
Aleksander Machniak | e94f5c023c | 9 years ago |
Aleksander Machniak | fb71e73933 | 9 years ago |
Thomas Bruederli | f3277e072e | 9 years ago |
Aleksander Machniak | bfe6570cb0 | 9 years ago |
Aleksander Machniak | 7fdc341a22 | 9 years ago |
Aleksander Machniak | 6d571ee561 | 9 years ago |
Aleksander Machniak | ead2368b71 | 9 years ago |
Aleksander Machniak | 6ccd4c54bc | 9 years ago |
Aleksander Machniak | 3aba794f70 | 9 years ago |
Aleksander Machniak | c2e41a6dd5 | 9 years ago |
Aleksander Machniak | 997ff77ea1 | 9 years ago |
Aleksander Machniak | 331f1d9e20 | 9 years ago |
Aleksander Machniak | b022d7b0d4 | 9 years ago |
Aleksander Machniak | 23bcfc5849 | 9 years ago |
Aleksander Machniak | 8defdaf0b1 | 9 years ago |
Aleksander Machniak | 5321cbd498 | 9 years ago |
Aleksander Machniak | ac93924b1f | 9 years ago |
Aleksander Machniak | f6336f7f7e | 9 years ago |
Aleksander Machniak | 2646758314 | 9 years ago |
Aleksander Machniak | 0ec46f3d40 | 9 years ago |
Aleksander Machniak | 78f948f7b9 | 9 years ago |
Thomas Bruederli | bd3e202787 | 9 years ago |
Aleksander Machniak | 2109fc94fb | 9 years ago |
Aleksander Machniak | 7c26dbd36f | 10 years ago |
Aleksander Machniak | f640e144dc | 10 years ago |
Aleksander Machniak | 56caf85079 | 10 years ago |
Aleksander Machniak | db780e10e4 | 10 years ago |
Aleksander Machniak | 04994005e7 | 10 years ago |
Aleksander Machniak | b134f59eb1 | 10 years ago |
Thomas Bruederli | 37757464fd | 10 years ago |
Aleksander Machniak | ed32835aba | 10 years ago |
Aleksander Machniak | cbacfb30a9 | 10 years ago |
Aleksander Machniak | f2d28ebbbb | 10 years ago |
Thomas Bruederli | be363cdf92 | 10 years ago |
Aleksander Machniak | acbf70d5bd | 10 years ago |
Aleksander Machniak | c608ae1ffe | 10 years ago |
Aleksander Machniak | fa5dabb574 | 10 years ago |
corbosman | 242d3c520b | 10 years ago |
Thomas Bruederli | 1f7e63f786 | 10 years ago |
Aleksander Machniak | 2ae677afd7 | 10 years ago |
Aleksander Machniak | 376cbfd4f2 | 10 years ago |
Aleksander Machniak | 753c8849ac | 10 years ago |
Aleksander Machniak | 35502e04a8 | 10 years ago |
David Carter | 94d8fb5a42 | 10 years ago |
Aleksander Machniak | 7e34e4c5b5 | 10 years ago |
Aleksander Machniak | 9f1fd39695 | 10 years ago |
Thomas Bruederli | ced9e5a5bf | 10 years ago |
Aleksander Machniak | 4446aea1e6 | 10 years ago |
Aleksander Machniak | 33f8bd6918 | 10 years ago |
Aleksander Machniak | 1852f984c0 | 10 years ago |
Aleksander Machniak | a4289060e6 | 10 years ago |
Aleksander Machniak | e03bcf3406 | 10 years ago |
Aleksander Machniak | bc42d0a041 | 10 years ago |
Aleksander Machniak | 73b14686fc | 10 years ago |
Aleksander Machniak | 080f560e0f | 10 years ago |
Aleksander Machniak | b5fd858eb2 | 10 years ago |
Aleksander Machniak | 50341eab43 | 10 years ago |
Bartlomiej Nogas | 281ca0ea2a | 10 years ago |
Aleksander Machniak | 7653ed107e | 10 years ago |
Aleksander Machniak | a23c233db6 | 10 years ago |
Aleksander Machniak | cbac33113a | 10 years ago |
Aleksander Machniak | 89984d01ba | 10 years ago |
Aleksander Machniak | 4efc69e7fd | 10 years ago |
Aleksander Machniak | 793642ed76 | 10 years ago |
Aleksander Machniak | 3db1599538 | 10 years ago |
Aleksander Machniak | 6bdbca3879 | 10 years ago |
Aleksander Machniak | 3eab20980a | 10 years ago |
Aleksander Machniak | 047fc190f3 | 10 years ago |
Aleksander Machniak | 0d6c673546 | 10 years ago |
Aleksander Machniak | 34d179a69a | 10 years ago |
Aleksander Machniak | 5c3bbb9e0d | 10 years ago |
Thomas Bruederli | 3febefe03a | 10 years ago |
Thomas Bruederli | fef904c6b1 | 10 years ago |
Thomas Bruederli | 1070bdb389 | 10 years ago |
Thomas Bruederli | 6c96b1b7cd | 10 years ago |
Thomas Bruederli | 1f4b06a853 | 10 years ago |
Thomas Bruederli | a4dc96e73e | 10 years ago |
Thomas Bruederli | 7d5a1c20e8 | 10 years ago |
Thomas Bruederli | a5ce2d8ae2 | 10 years ago |
Thomas Bruederli | e1db66a4b4 | 10 years ago |
Thomas Bruederli | 2fa50dce32 | 10 years ago |
Aleksander Machniak | 9a49821244 | 10 years ago |
Aleksander Machniak | d6867490ab | 10 years ago |
Thomas Bruederli | 728e6ffb69 | 10 years ago |
Aleksander Machniak | 871a26d328 | 10 years ago |
Aleksander Machniak | 1dafdff79a | 10 years ago |
Aleksander Machniak | 25207f5a65 | 10 years ago |
Aleksander Machniak | 574f416076 | 10 years ago |
Aleksander Machniak | 3b55da7ba6 | 10 years ago |
Aleksander Machniak | 4922ebda5c | 10 years ago |
Aleksander Machniak | 847f5b9a77 | 10 years ago |
Aleksander Machniak | dbf70cc7db | 10 years ago |
Aleksander Machniak | e6f21118b8 | 10 years ago |
Thomas Bruederli | 2d284df861 | 10 years ago |
Aleksander Machniak | ef4e6b9aed | 10 years ago |
brendan braybrook | 7cf6524590 | 10 years ago |
brendan braybrook | 9cbdb6cd69 | 10 years ago |
brendan braybrook | eff2a2768d | 10 years ago |
Aleksander Machniak | a1bb59d601 | 10 years ago |
Aleksander Machniak | dddb9dee61 | 10 years ago |
Aleksander Machniak | f5f056e7f2 | 10 years ago |
Aleksander Machniak | 8d4b4897df | 10 years ago |
Aleksander Machniak | 1fac787d2c | 10 years ago |
Aleksander Machniak | d1749659d2 | 10 years ago |
Aleksander Machniak | 057444bd41 | 10 years ago |
Aleksander Machniak | 5d92a6540a | 10 years ago |
Thomas Bruederli | 39bd9b8e29 | 10 years ago |
Aleksander Machniak | 835638037a | 10 years ago |
Aleksander Machniak | b78ecabaa1 | 10 years ago |
Aleksander Machniak | 9cf50d16d4 | 10 years ago |
Aleksander Machniak | ae502b364d | 10 years ago |
Thomas Bruederli | 7515a28ee9 | 10 years ago |
Thomas Bruederli | d461ae0e8a | 10 years ago |
Thomas Bruederli | 007f1b4438 | 10 years ago |
Thomas Bruederli | 29723da95b | 10 years ago |
Thomas Bruederli | 60eba5df3a | 10 years ago |
Aleksander Machniak | eef107be30 | 10 years ago |
Aleksander Machniak | a8282f1359 | 10 years ago |
Thomas Bruederli | 86fe5378ae | 10 years ago |
Thomas Bruederli | 5a3f8636ec | 10 years ago |
Aleksander Machniak | d323e30a57 | 10 years ago |
Aleksander Machniak | 8437d76389 | 10 years ago |
Aleksander Machniak | 118a170dbc | 10 years ago |
Aleksander Machniak | 224278cc4d | 10 years ago |
Aleksander Machniak | bda3e7d239 | 10 years ago |
Aleksander Machniak | 7152d0fdef | 10 years ago |
Aleksander Machniak | c627d3bb02 | 10 years ago |
Aleksander Machniak | 2a700d7c00 | 10 years ago |
Aleksander Machniak | 64ce35e2a9 | 10 years ago |
Aleksander Machniak | db2c1a53cb | 10 years ago |
Aleksander Machniak | a862e9996b | 10 years ago |
Aleksander Machniak | 702ce09f89 | 10 years ago |
Aleksander Machniak | ee83a48d04 | 10 years ago |
Aleksander Machniak | 4162430a43 | 10 years ago |
Aleksander Machniak | f105dbb769 | 10 years ago |
Aleksander Machniak | 0a5088758e | 10 years ago |
Aleksander Machniak | 53df26f447 | 10 years ago |
Aleksander Machniak | bbce9f5a2e | 10 years ago |
corbosman | 04089eed1c | 10 years ago |
Aleksander Machniak | abb405ab5b | 10 years ago |
Aleksander Machniak | d4df56557a | 10 years ago |
Aleksander Machniak | dbd5c18471 | 10 years ago |
Aleksander Machniak | 4f3f85da39 | 10 years ago |
Aleksander Machniak | 49e260ba58 | 10 years ago |
Aleksander Machniak | 599434f770 | 10 years ago |
Aleksander Machniak | ec62e8a7ee | 10 years ago |
Aleksander Machniak | 2911ca3e96 | 10 years ago |
Aleksander Machniak | 8b93fc9284 | 10 years ago |
Aleksander Machniak | 54b4790fcd | 10 years ago |
Aleksander Machniak | 2d233bf49c | 10 years ago |
Aleksander Machniak | 5c8e60d45d | 10 years ago |
Aleksander Machniak | c9feba8917 | 10 years ago |
Aleksander Machniak | 70ba547d10 | 10 years ago |
Aleksander Machniak | f92cccac38 | 10 years ago |
Thomas Bruederli | 0b70f509fc | 10 years ago |
Thomas Bruederli | 0d9ccfd8f7 | 10 years ago |
Thomas Bruederli | c94971bc6f | 10 years ago |
Thomas Bruederli | e4d87a07b7 | 10 years ago |
Aleksander Machniak | 16ce146d88 | 10 years ago |
Aleksander Machniak | 9b0173c881 | 10 years ago |
Aleksander Machniak | ac828b735b | 10 years ago |
Aleksander Machniak | 4765b261f8 | 10 years ago |
Aleksander Machniak | a88f241250 | 10 years ago |
Aleksander Machniak | b5beb1888f | 10 years ago |
Aleksander Machniak | 80acbd62df | 10 years ago |
Aleksander Machniak | 2ff8b45c48 | 10 years ago |
Aleksander Machniak | 8b5d16d30a | 10 years ago |
Aleksander Machniak | 34e6526c95 | 10 years ago |
Aleksander Machniak | 50fee948fd | 10 years ago |
Aleksander Machniak | 08953a46d9 | 10 years ago |
Aleksander Machniak | 720e7d376f | 10 years ago |
Aleksander Machniak | 7e3af82c4f | 10 years ago |
Aleksander Machniak | f25f6cde39 | 10 years ago |
Aleksander Machniak | cbd5388d2e | 10 years ago |
Thomas Bruederli | e947955367 | 10 years ago |
Felix Eckhofer | 8a4234d2fc | 10 years ago |
Felix Eckhofer | f58a294949 | 10 years ago |
Felix Eckhofer | d71a711ab0 | 10 years ago |
Thomas Bruederli | c3c4842c5f | 10 years ago |
Thomas Bruederli | 6c7452d667 | 10 years ago |
Aleksander Machniak | 7fface125e | 10 years ago |
Aleksander Machniak | 115ba30dcd | 10 years ago |
Aleksander Machniak | e965185265 | 10 years ago |
Aleksander Machniak | 0f820efd6a | 10 years ago |
Aleksander Machniak | adeee1455c | 10 years ago |
Aleksander Machniak | 847e7548d5 | 10 years ago |
Aleksander Machniak | 293d61b16f | 10 years ago |
Aleksander Machniak | 437c0dadd0 | 10 years ago |
Aleksander Machniak | a70234f375 | 10 years ago |
Aleksander Machniak | 36a154e934 | 10 years ago |
Aleksander Machniak | e1e65c4980 | 10 years ago |
Aleksander Machniak | 701d7a369b | 10 years ago |
Aleksander Machniak | ee3dd89c04 | 10 years ago |
Aleksander Machniak | 3a04a3d710 | 10 years ago |
Aleksander Machniak | ef925bb49c | 10 years ago |
Aleksander Machniak | fd309c3650 | 10 years ago |
Aleksander Machniak | f4bd85b8d0 | 10 years ago |
Aleksander Machniak | 4c7daf5cea | 10 years ago |
Aleksander Machniak | d9588ff228 | 10 years ago |
Aleksander Machniak | 7e3b5ef8f3 | 10 years ago |
Aleksander Machniak | 05d419a340 | 10 years ago |
Thomas Bruederli | dbe4eff8d2 | 10 years ago |
Thomas Bruederli | 59d7f87a05 | 10 years ago |
Thomas Bruederli | 0268829299 | 10 years ago |
Thomas Bruederli | d61731e1a3 | 10 years ago |
Aleksander Machniak | 5381636fc4 | 10 years ago |
Thomas Bruederli | 8d956fd455 | 10 years ago |
Aleksander Machniak | c7357ea320 | 10 years ago |
Aleksander Machniak | d22d119e38 | 10 years ago |
Aleksander Machniak | 7a6dd9ad84 | 10 years ago |
Aleksander Machniak | ceff79b14a | 10 years ago |
Aleksander Machniak | 7883ecb8ec | 10 years ago |
Aleksander Machniak | 92e81cbf22 | 10 years ago |
Aleksander Machniak | 4044be4f19 | 10 years ago |
Aleksander Machniak | fda13f337c | 10 years ago |
Aleksander Machniak | 390eacc2af | 10 years ago |
Thomas Bruederli | 2f43fe94cb | 10 years ago |
Thomas Bruederli | 56be9c50ea | 10 years ago |
Thomas Bruederli | de3c333f4e | 10 years ago |
Thomas Bruederli | 548b0ddee9 | 10 years ago |
Thomas Bruederli | 3138879ddb | 10 years ago |
Aleksander Machniak | 677fb747c1 | 10 years ago |
Aleksander Machniak | 5fefe78f75 | 10 years ago |
Thomas Bruederli | eb9c51018d | 10 years ago |
Thomas Bruederli | 5934e23824 | 10 years ago |
Thomas Bruederli | e5bb1357a5 | 10 years ago |
Thomas Bruederli | ab8bad44d0 | 10 years ago |
Thomas Bruederli | b7f95b7efe | 10 years ago |
Aleksander Machniak | 920322a609 | 10 years ago |
Thomas Bruederli | 39d3ab17aa | 10 years ago |
Thomas Bruederli | 8d3b27b9e8 | 10 years ago |
Aleksander Machniak | f4564ae20d | 10 years ago |
Aleksander Machniak | 70eafd53c6 | 10 years ago |
Aleksander Machniak | b23f2007a3 | 10 years ago |
Thomas Bruederli | 1394025bdf | 10 years ago |
Thomas Bruederli | 238c6a0f55 | 10 years ago |
Thomas Bruederli | 5ba53819cf | 10 years ago |
Thomas Bruederli | 881d6b0375 | 10 years ago |
Thomas Bruederli | e3773d46cb | 10 years ago |
Thomas Bruederli | a7d68eaf1a | 10 years ago |
Aleksander Machniak | 3505d57641 | 10 years ago |
Takika | 4b859649ea | 10 years ago |
Thomas Bruederli | 0b1bb84799 | 10 years ago |
Thomas Bruederli | 66c2ff9e1a | 10 years ago |
Aleksander Machniak | 1edb6bbc25 | 10 years ago |
Aleksander Machniak | 1c715f79b4 | 10 years ago |
Aleksander Machniak | 55d9d5e0b7 | 10 years ago |
Thomas Bruederli | 5f5174e3b5 | 10 years ago |
Aleksander Machniak | 7f28120768 | 10 years ago |
Aleksander Machniak | 6345f34565 | 10 years ago |
Aleksander Machniak | a16cbb204e | 10 years ago |
Aleksander Machniak | 7c61ba4953 | 10 years ago |
Aleksander Machniak | ef76ce576c | 10 years ago |
Aleksander Machniak | ce57ca8c5e | 10 years ago |
Thomas Bruederli | dd34e478b3 | 10 years ago |
Thomas Bruederli | e7bcd945bd | 10 years ago |
Aleksander Machniak | a4cd91f6b2 | 10 years ago |
Aleksander Machniak | 59865f3259 | 10 years ago |
Till Krüss | dc52ae0b02 | 10 years ago |
Aleksander Machniak | 6f079094d2 | 10 years ago |
Aleksander Machniak | 21f6f468d6 | 10 years ago |
Thomas Bruederli | ce29296fa9 | 10 years ago |
Aleksander Machniak | e089c5adc8 | 10 years ago |
Aleksander Machniak | c4c3e7822d | 10 years ago |
Till Krüss | 01014a20b9 | 10 years ago |
Aleksander Machniak | 6fdf1f2072 | 10 years ago |
Aleksander Machniak | 4bcb8ac002 | 10 years ago |
Aleksander Machniak | f130f9116e | 10 years ago |
Aleksander Machniak | 8c32f88193 | 10 years ago |
Aleksander Machniak | b37954110d | 10 years ago |
Aleksander Machniak | e445e0acb5 | 10 years ago |
Thomas Bruederli | 92eb72dafc | 10 years ago |
Aleksander Machniak | af15c60f88 | 10 years ago |
Thomas Bruederli | f8a57ebd94 | 10 years ago |
Thomas Bruederli | 63eae4a196 | 10 years ago |
Thomas Bruederli | d3583f0c0e | 10 years ago |
Thomas Bruederli | a7d42915a4 | 10 years ago |
Aleksander Machniak | bd3f5745f0 | 10 years ago |
Aleksander Machniak | 59373ce9cd | 10 years ago |
Aleksander Machniak | c0d8ec001b | 10 years ago |
Thomas Bruederli | 50217a9eb5 | 10 years ago |
Thomas Bruederli | 8c893b79d2 | 10 years ago |
@ -1,30 +0,0 @@
|
||||
<?php
|
||||
|
||||
$config = array();
|
||||
|
||||
// Database configuration
|
||||
$config['db_dsnw'] = 'sqlite:////tmp/sqlite.db?mode=0646';
|
||||
|
||||
// Test user credentials
|
||||
$config['tests_username'] = 'test';
|
||||
$config['tests_password'] = 'test';
|
||||
|
||||
// GreenMail
|
||||
$config['smtp_port'] = 25;
|
||||
|
||||
// Settings required by the tests
|
||||
|
||||
$config['create_default_folders'] = true;
|
||||
$config['skin'] = 'elastic';
|
||||
$config['support_url'] = 'http://support.url';
|
||||
|
||||
// Plugins with tests
|
||||
|
||||
$config['plugins'] = [
|
||||
'archive',
|
||||
'attachment_reminder',
|
||||
'markasjunk',
|
||||
'zipdownload'
|
||||
];
|
||||
|
||||
$config['archive_mbox'] = 'Archive';
|
@ -1,22 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
# The script is intended for use on Travis with Trusty distribution
|
||||
|
||||
DIR=$(dirname $0)
|
||||
|
||||
# Enable xdebug for code coverage
|
||||
if [ "$CODE_COVERAGE" != 1 ]; then phpenv config-rm xdebug.ini || true; fi
|
||||
|
||||
cd $DIR/..
|
||||
|
||||
cp composer.json-dist composer.json
|
||||
|
||||
# Add laravel/dusk for Browser tests
|
||||
if [ "$BROWSER_TESTS" = 1 ]; then composer require "laravel/dusk:~5.9.1" --no-update; fi
|
||||
|
||||
# Remove qr-code as it requires php-gd which is not always available on Travis
|
||||
# and we don't really need it for tests
|
||||
composer remove endroid/qr-code --no-update
|
||||
|
||||
# Install PHP dependencies
|
||||
composer install --prefer-dist
|
@ -1,25 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
# The script is intended for use on Travis with Trusty distribution
|
||||
# It executes unit and functional tests
|
||||
|
||||
DIR=$(dirname $0)
|
||||
cd $DIR/..
|
||||
|
||||
if [ "$CODE_COVERAGE" = 1 ]
|
||||
then
|
||||
CODE_COVERAGE_ARGS="--coverage-text"
|
||||
fi
|
||||
|
||||
vendor/bin/phpunit -c tests/phpunit.xml $CODE_COVERAGE_ARGS
|
||||
|
||||
if [ "$BROWSER_TESTS" = 1 ] && [ $? = 0 ]
|
||||
then
|
||||
.ci/setup.sh \
|
||||
&& echo "TESTS_MODE: DESKTOP" \
|
||||
&& TESTS_MODE=desktop vendor/bin/phpunit -c tests/Browser/phpunit.xml \
|
||||
&& echo "TESTS_MODE: PHONE" \
|
||||
&& TESTS_MODE=phone vendor/bin/phpunit -c tests/Browser/phpunit.xml \
|
||||
&& echo "TESTS_MODE: TABLET" \
|
||||
&& TESTS_MODE=tablet vendor/bin/phpunit -c tests/Browser/phpunit.xml
|
||||
fi
|
@ -1,30 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
# The script is intended for use on Travis with Trusty distribution
|
||||
# It installs in-browser tests dependencies and prepares Roundcube instance
|
||||
|
||||
GMV=1.5.11
|
||||
CHROMEVERSION=$(google-chrome-stable --version | tr -cd [:digit:]. | cut -d . -f 1)
|
||||
GMARGS="-Dgreenmail.setup.all -Dgreenmail.users=test:test -Dgreenmail.startup.timeout=3000"
|
||||
|
||||
# Roundcube tests and instance configuration
|
||||
cp .ci/config-test.inc.php config/config-test.inc.php
|
||||
|
||||
# Make temp and logs writeable
|
||||
sudo chmod 777 temp logs
|
||||
|
||||
# Install javascript dependencies
|
||||
bin/install-jsdeps.sh
|
||||
|
||||
# Compile Elastic's styles
|
||||
lessc skins/elastic/styles/styles.less > skins/elastic/styles/styles.css
|
||||
lessc skins/elastic/styles/print.less > skins/elastic/styles/print.css
|
||||
lessc skins/elastic/styles/embed.less > skins/elastic/styles/embed.css
|
||||
|
||||
# Install proper WebDriver version for installed Chrome browser
|
||||
php tests/Browser/install.php $CHROMEVERSION
|
||||
|
||||
# GreenMail server download, setup and start
|
||||
wget https://repo1.maven.org/maven2/com/icegreen/greenmail-standalone/$GMV/greenmail-standalone-$GMV.jar \
|
||||
&& (sudo java $GMARGS -jar greenmail-standalone-$GMV.jar &) \
|
||||
&& sleep 5
|
@ -1,37 +0,0 @@
|
||||
language: php
|
||||
|
||||
dist: trusty #
|
||||
sudo: false
|
||||
|
||||
matrix:
|
||||
fast_finish: true
|
||||
include:
|
||||
- php: 5.4
|
||||
- php: 5.5
|
||||
- php: 5.6
|
||||
- php: 7.0
|
||||
- php: 7.1
|
||||
env: CODE_COVERAGE=1
|
||||
- php: 7.2
|
||||
- php: 7.3
|
||||
dist: bionic # for proper node-less version
|
||||
env: BROWSER_TESTS=1
|
||||
addons:
|
||||
chrome: stable
|
||||
apt:
|
||||
packages:
|
||||
- node-less
|
||||
- php: 7.4
|
||||
|
||||
cache:
|
||||
directories:
|
||||
- $HOME/.composer
|
||||
|
||||
install:
|
||||
- .ci/install.sh
|
||||
|
||||
script:
|
||||
- .ci/run.sh
|
||||
|
||||
notifications:
|
||||
email: false
|
@ -1 +0,0 @@
|
||||
-- empty
|
@ -1,4 +0,0 @@
|
||||
ALTER TABLE [dbo].[users] ADD [failed_login] [datetime] NULL
|
||||
GO
|
||||
ALTER TABLE [dbo].[users] ADD [failed_login_counter] [int] NULL
|
||||
GO
|
@ -1,2 +0,0 @@
|
||||
ALTER TABLE [dbo].[session] DROP COLUMN [created]
|
||||
GO
|
@ -1,2 +0,0 @@
|
||||
ALTER TABLE [dbo].[session] ALTER COLUMN [ip] [varchar] (40) COLLATE Latin1_General_CI_AI NOT NULL
|
||||
GO
|
@ -1,36 +0,0 @@
|
||||
DROP TABLE [dbo].[cache]
|
||||
GO
|
||||
DROP TABLE [dbo].[cache_shared]
|
||||
GO
|
||||
|
||||
CREATE TABLE [dbo].[cache] (
|
||||
[user_id] [int] NOT NULL ,
|
||||
[cache_key] [varchar] (128) COLLATE Latin1_General_CI_AI NOT NULL ,
|
||||
[expires] [datetime] NULL ,
|
||||
[data] [text] COLLATE Latin1_General_CI_AI NOT NULL
|
||||
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
|
||||
GO
|
||||
CREATE TABLE [dbo].[cache_shared] (
|
||||
[cache_key] [varchar] (255) COLLATE Latin1_General_CI_AI NOT NULL ,
|
||||
[expires] [datetime] NULL ,
|
||||
[data] [text] COLLATE Latin1_General_CI_AI NOT NULL
|
||||
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
|
||||
GO
|
||||
ALTER TABLE [dbo].[cache] ADD
|
||||
CONSTRAINT [DF_cache_user_id] DEFAULT ('0') FOR [user_id],
|
||||
CONSTRAINT [DF_cache_cache_key] DEFAULT ('') FOR [cache_key],
|
||||
GO
|
||||
CREATE INDEX [IX_cache_expires] ON [dbo].[cache]([expires]) ON [PRIMARY]
|
||||
GO
|
||||
CREATE INDEX [IX_cache_shared_expires] ON [dbo].[cache_shared]([expires]) ON [PRIMARY]
|
||||
GO
|
||||
ALTER TABLE [dbo].[cache] WITH NOCHECK ADD
|
||||
PRIMARY KEY CLUSTERED (
|
||||
[user_id],[cache_key]
|
||||
) ON [PRIMARY]
|
||||
GO
|
||||
ALTER TABLE [dbo].[cache_shared] WITH NOCHECK ADD
|
||||
PRIMARY KEY CLUSTERED (
|
||||
[cache_key]
|
||||
) ON [PRIMARY]
|
||||
GO
|
@ -1,24 +0,0 @@
|
||||
CREATE TABLE [dbo].[filestore] (
|
||||
[file_id] [int] IDENTITY (1, 1) NOT NULL ,
|
||||
[user_id] [int] NOT NULL ,
|
||||
[filename] [varchar] (128) COLLATE Latin1_General_CI_AI NOT NULL ,
|
||||
[mtime] [int] NOT NULL ,
|
||||
[data] [text] COLLATE Latin1_General_CI_AI NULL ,
|
||||
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
|
||||
GO
|
||||
|
||||
ALTER TABLE [dbo].[filestore] WITH NOCHECK ADD
|
||||
CONSTRAINT [PK_filestore_file_id] PRIMARY KEY CLUSTERED
|
||||
(
|
||||
[file_id]
|
||||
) ON [PRIMARY]
|
||||
GO
|
||||
|
||||
CREATE INDEX [IX_filestore_user_id] ON [dbo].[filestore]([user_id]) ON [PRIMARY]
|
||||
GO
|
||||
|
||||
ALTER TABLE [dbo].[filestore] ADD CONSTRAINT [FK_filestore_user_id]
|
||||
FOREIGN KEY ([user_id]) REFERENCES [dbo].[users] ([user_id])
|
||||
ON DELETE CASCADE ON UPDATE CASCADE
|
||||
GO
|
||||
|
@ -1,9 +0,0 @@
|
||||
ALTER TABLE [dbo].[filestore] ADD COLUMN [context] [varchar] (32) COLLATE Latin1_General_CI_AI NOT NULL
|
||||
GO
|
||||
|
||||
UPDATE [dbo].[filestore] SET [dbo].[context] = 'enigma'
|
||||
GO
|
||||
|
||||
CREATE UNIQUE INDEX [IX_filestore_user_id_context_filename] ON [dbo].[filestore]([user_id],[context],[filename]) ON [PRIMARY]
|
||||
GO
|
||||
|
@ -1,18 +0,0 @@
|
||||
ALTER TABLE [dbo].[cache] ALTER COLUMN
|
||||
[cache_key] [varchar] (128) COLLATE Latin1_General_CS_AS NOT NULL
|
||||
GO
|
||||
ALTER TABLE [dbo].[cache_shared] ALTER COLUMN
|
||||
[cache_key] [varchar] (255) COLLATE Latin1_General_CS_AS NOT NULL
|
||||
GO
|
||||
ALTER TABLE [dbo].[cache_index] ALTER COLUMN
|
||||
[mailbox] [varchar] (128) COLLATE Latin1_General_CS_AS NOT NULL
|
||||
GO
|
||||
ALTER TABLE [dbo].[cache_messages] ALTER COLUMN
|
||||
[mailbox] [varchar] (128) COLLATE Latin1_General_CS_AS NOT NULL
|
||||
GO
|
||||
ALTER TABLE [dbo].[cache_thread] ALTER COLUMN
|
||||
[mailbox] [varchar] (128) COLLATE Latin1_General_CS_AS NOT NULL
|
||||
GO
|
||||
ALTER TABLE [dbo].[users] ALTER COLUMN
|
||||
[username] [varchar] (128) COLLATE Latin1_General_CS_AS NOT NULL
|
||||
GO
|
@ -1,4 +0,0 @@
|
||||
ALTER TABLE [dbo].[users] ALTER COLUMN [language] [varchar] (16) COLLATE Latin1_General_CI_AI NULL
|
||||
GO
|
||||
ALTER TABLE [dbo].[dictionary] ALTER COLUMN [language] [varchar] (16) COLLATE Latin1_General_CI_AI NOT NULL
|
||||
GO
|
@ -1 +0,0 @@
|
||||
-- empty
|
@ -1 +0,0 @@
|
||||
ALTER TABLE `identities` CHANGE `signature` `signature` longtext;
|
@ -1,3 +0,0 @@
|
||||
ALTER TABLE `users`
|
||||
ADD `failed_login` datetime DEFAULT NULL,
|
||||
ADD `failed_login_counter` int(10) UNSIGNED DEFAULT NULL;
|
@ -1 +0,0 @@
|
||||
ALTER TABLE `session` DROP COLUMN `created`;
|
@ -1 +0,0 @@
|
||||
ALTER TABLE `session` MODIFY `ip` varchar(40) NOT NULL;
|
@ -1,24 +0,0 @@
|
||||
ALTER TABLE `dictionary` ADD COLUMN `id` int(10) UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY FIRST; -- redundant, for compat. with Galera Cluster
|
||||
|
||||
DROP TABLE `cache`;
|
||||
DROP TABLE `cache_shared`;
|
||||
|
||||
CREATE TABLE `cache` (
|
||||
`user_id` int(10) UNSIGNED NOT NULL,
|
||||
`cache_key` varchar(128) /*!40101 CHARACTER SET ascii COLLATE ascii_general_ci */ NOT NULL,
|
||||
`expires` datetime DEFAULT NULL,
|
||||
`data` longtext NOT NULL,
|
||||
PRIMARY KEY (`user_id`, `cache_key`),
|
||||
CONSTRAINT `user_id_fk_cache` FOREIGN KEY (`user_id`)
|
||||
REFERENCES `users`(`user_id`) ON DELETE CASCADE ON UPDATE CASCADE,
|
||||
INDEX `expires_index` (`expires`)
|
||||
) /*!40000 ENGINE=INNODB */ /*!40101 CHARACTER SET utf8 COLLATE utf8_general_ci */;
|
||||
|
||||
|
||||
CREATE TABLE `cache_shared` (
|
||||
`cache_key` varchar(255) /*!40101 CHARACTER SET ascii COLLATE ascii_general_ci */ NOT NULL,
|
||||
`expires` datetime DEFAULT NULL,
|
||||
`data` longtext NOT NULL,
|
||||
PRIMARY KEY (`cache_key`),
|
||||
INDEX `expires_index` (`expires`)
|
||||
) /*!40000 ENGINE=INNODB */ /*!40101 CHARACTER SET utf8 COLLATE utf8_general_ci */;
|
@ -1,11 +0,0 @@
|
||||
CREATE TABLE `filestore` (
|
||||
`file_id` int(10) UNSIGNED NOT NULL AUTO_INCREMENT,
|
||||
`user_id` int(10) UNSIGNED NOT NULL,
|
||||
`filename` varchar(128) NOT NULL,
|
||||
`mtime` int(10) NOT NULL,
|
||||
`data` longtext NOT NULL,
|
||||
PRIMARY KEY (`file_id`),
|
||||
CONSTRAINT `user_id_fk_filestore` FOREIGN KEY (`user_id`)
|
||||
REFERENCES `users` (`user_id`) ON DELETE CASCADE ON UPDATE CASCADE,
|
||||
UNIQUE `uniqueness` (`user_id`, `filename`)
|
||||
) /*!40000 ENGINE=INNODB */ /*!40101 CHARACTER SET utf8 COLLATE utf8_general_ci */;
|
@ -1,7 +0,0 @@
|
||||
ALTER TABLE `filestore` ADD COLUMN `context` varchar(32) NOT NULL;
|
||||
UPDATE `filestore` SET `context` = 'enigma';
|
||||
ALTER TABLE `filestore` DROP FOREIGN KEY `user_id_fk_filestore`;
|
||||
ALTER TABLE `filestore` DROP INDEX `uniqueness`;
|
||||
ALTER TABLE `filestore` ADD UNIQUE INDEX `uniqueness` (`user_id`, `context`, `filename`);
|
||||
ALTER TABLE `filestore` ADD CONSTRAINT `user_id_fk_filestore` FOREIGN KEY (`user_id`)
|
||||
REFERENCES `users` (`user_id`) ON DELETE CASCADE ON UPDATE CASCADE;
|
@ -1,2 +0,0 @@
|
||||
ALTER TABLE `cache` CHANGE `cache_key` `cache_key` varchar(128) BINARY NOT NULL;
|
||||
ALTER TABLE `cache_shared` CHANGE `cache_key` `cache_key` varchar(255) BINARY NOT NULL;
|
@ -1,2 +0,0 @@
|
||||
ALTER TABLE `users` MODIFY `language` varchar(16);
|
||||
ALTER TABLE `dictionary` MODIFY `language` varchar(16) NOT NULL;
|
@ -1,21 +0,0 @@
|
||||
ALTER TABLE `session` CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
|
||||
ALTER TABLE `users` CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
|
||||
ALTER TABLE `cache` CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
|
||||
ALTER TABLE `cache_shared` CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
|
||||
ALTER TABLE `cache_index` CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
|
||||
ALTER TABLE `cache_thread` CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
|
||||
ALTER TABLE `cache_messages` CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
|
||||
ALTER TABLE `contacts` CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
|
||||
ALTER TABLE `contactgroups` CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
|
||||
ALTER TABLE `identities` CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
|
||||
ALTER TABLE `dictionary` CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
|
||||
ALTER TABLE `searches` CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
|
||||
ALTER TABLE `filestore` CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
|
||||
ALTER TABLE `system` CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
|
||||
|
||||
ALTER TABLE `users` CHANGE `username` `username` varchar(128) BINARY NOT NULL;
|
||||
ALTER TABLE `cache` CHANGE `cache_key` `cache_key` varchar(128) BINARY NOT NULL;
|
||||
ALTER TABLE `cache_shared` CHANGE `cache_key` `cache_key` varchar(255) BINARY NOT NULL;
|
||||
ALTER TABLE `cache_index` CHANGE `mailbox` `mailbox` varchar(255) BINARY NOT NULL;
|
||||
ALTER TABLE `cache_thread` CHANGE `mailbox` `mailbox` varchar(255) BINARY NOT NULL;
|
||||
ALTER TABLE `cache_messages` CHANGE `mailbox` `mailbox` varchar(255) BINARY NOT NULL;
|
@ -1,241 +0,0 @@
|
||||
-- Roundcube Webmail initial database structure
|
||||
-- This was tested with Oracle 11g
|
||||
|
||||
CREATE TABLE "users" (
|
||||
"user_id" integer PRIMARY KEY,
|
||||
"username" varchar(128) NOT NULL,
|
||||
"mail_host" varchar(128) NOT NULL,
|
||||
"created" timestamp with time zone DEFAULT current_timestamp NOT NULL,
|
||||
"last_login" timestamp with time zone DEFAULT NULL,
|
||||
"failed_login" timestamp with time zone DEFAULT NULL,
|
||||
"failed_login_counter" integer DEFAULT NULL,
|
||||
"language" varchar(16),
|
||||
"preferences" long DEFAULT NULL,
|
||||
CONSTRAINT "users_username_key" UNIQUE ("username", "mail_host")
|
||||
);
|
||||
|
||||
CREATE SEQUENCE "users_seq"
|
||||
START WITH 1 INCREMENT BY 1 NOMAXVALUE;
|
||||
|
||||
CREATE TRIGGER "users_seq_trig"
|
||||
BEFORE INSERT ON "users" FOR EACH ROW
|
||||
BEGIN
|
||||
:NEW."user_id" := "users_seq".nextval;
|
||||
END;
|
||||
/
|
||||
|
||||
CREATE TABLE "session" (
|
||||
"sess_id" varchar(128) NOT NULL PRIMARY KEY,
|
||||
"changed" timestamp with time zone DEFAULT current_timestamp NOT NULL,
|
||||
"ip" varchar(41) NOT NULL,
|
||||
"vars" long NOT NULL
|
||||
);
|
||||
|
||||
CREATE INDEX "session_changed_idx" ON "session" ("changed");
|
||||
|
||||
|
||||
CREATE TABLE "identities" (
|
||||
"identity_id" integer PRIMARY KEY,
|
||||
"user_id" integer NOT NULL
|
||||
REFERENCES "users" ("user_id") ON DELETE CASCADE,
|
||||
"changed" timestamp with time zone DEFAULT current_timestamp NOT NULL,
|
||||
"del" smallint DEFAULT 0 NOT NULL,
|
||||
"standard" smallint DEFAULT 0 NOT NULL,
|
||||
"name" varchar(128) NOT NULL,
|
||||
"organization" varchar(128),
|
||||
"email" varchar(128) NOT NULL,
|
||||
"reply-to" varchar(128),
|
||||
"bcc" varchar(128),
|
||||
"signature" long,
|
||||
"html_signature" integer DEFAULT 0 NOT NULL
|
||||
);
|
||||
|
||||
CREATE INDEX "identities_user_id_idx" ON "identities" ("user_id", "del");
|
||||
CREATE INDEX "identities_email_idx" ON "identities" ("email", "del");
|
||||
|
||||
CREATE SEQUENCE "identities_seq"
|
||||
START WITH 1 INCREMENT BY 1 NOMAXVALUE;
|
||||
|
||||
CREATE TRIGGER "identities_seq_trig"
|
||||
BEFORE INSERT ON "identities" FOR EACH ROW
|
||||
BEGIN
|
||||
:NEW."identity_id" := "identities_seq".nextval;
|
||||
END;
|
||||
/
|
||||
|
||||
CREATE TABLE "contacts" (
|
||||
"contact_id" integer PRIMARY KEY,
|
||||
"user_id" integer NOT NULL
|
||||
REFERENCES "users" ("user_id") ON DELETE CASCADE,
|
||||
"changed" timestamp with time zone DEFAULT current_timestamp NOT NULL,
|
||||
"del" smallint DEFAULT 0 NOT NULL,
|
||||
"name" varchar(128) DEFAULT NULL,
|
||||
"email" varchar(4000) DEFAULT NULL,
|
||||
"firstname" varchar(128) DEFAULT NULL,
|
||||
"surname" varchar(128) DEFAULT NULL,
|
||||
"vcard" long,
|
||||
"words" varchar(4000)
|
||||
);
|
||||
|
||||
CREATE INDEX "contacts_user_id_idx" ON "contacts" ("user_id", "del");
|
||||
|
||||
CREATE SEQUENCE "contacts_seq"
|
||||
START WITH 1 INCREMENT BY 1 NOMAXVALUE;
|
||||
|
||||
CREATE TRIGGER "contacts_seq_trig"
|
||||
BEFORE INSERT ON "contacts" FOR EACH ROW
|
||||
BEGIN
|
||||
:NEW."contact_id" := "contacts_seq".nextval;
|
||||
END;
|
||||
/
|
||||
|
||||
CREATE TABLE "contactgroups" (
|
||||
"contactgroup_id" integer PRIMARY KEY,
|
||||
"user_id" integer NOT NULL
|
||||
REFERENCES "users" ("user_id") ON DELETE CASCADE,
|
||||
"changed" timestamp with time zone DEFAULT current_timestamp NOT NULL,
|
||||
"del" smallint DEFAULT 0 NOT NULL,
|
||||
"name" varchar(128) NOT NULL
|
||||
);
|
||||
|
||||
CREATE INDEX "contactgroups_user_id_idx" ON "contactgroups" ("user_id", "del");
|
||||
|
||||
CREATE SEQUENCE "contactgroups_seq"
|
||||
START WITH 1 INCREMENT BY 1 NOMAXVALUE;
|
||||
|
||||
CREATE TRIGGER "contactgroups_seq_trig"
|
||||
BEFORE INSERT ON "contactgroups" FOR EACH ROW
|
||||
BEGIN
|
||||
:NEW."contactgroup_id" := "contactgroups_seq".nextval;
|
||||
END;
|
||||
/
|
||||
|
||||
CREATE TABLE "contactgroupmembers" (
|
||||
"contactgroup_id" integer NOT NULL
|
||||
REFERENCES "contactgroups" ("contactgroup_id") ON DELETE CASCADE,
|
||||
"contact_id" integer NOT NULL
|
||||
REFERENCES "contacts" ("contact_id") ON DELETE CASCADE,
|
||||
"created" timestamp with time zone DEFAULT current_timestamp NOT NULL,
|
||||
PRIMARY KEY ("contactgroup_id", "contact_id")
|
||||
);
|
||||
|
||||
CREATE INDEX "contactgroupmembers_idx" ON "contactgroupmembers" ("contact_id");
|
||||
|
||||
|
||||
CREATE TABLE "cache" (
|
||||
"user_id" integer NOT NULL
|
||||
REFERENCES "users" ("user_id") ON DELETE CASCADE,
|
||||
"cache_key" varchar(128) NOT NULL,
|
||||
"expires" timestamp with time zone DEFAULT NULL,
|
||||
"data" long NOT NULL,
|
||||
PRIMARY KEY ("user_id", "cache_key")
|
||||
);
|
||||
|
||||
CREATE INDEX "cache_expires_idx" ON "cache" ("expires");
|
||||
|
||||
|
||||
CREATE TABLE "cache_shared" (
|
||||
"cache_key" varchar(255) NOT NULL,
|
||||
"expires" timestamp with time zone DEFAULT NULL,
|
||||
"data" long NOT NULL,
|
||||
PRIMARY KEY ("cache_key")
|
||||
);
|
||||
|
||||
CREATE INDEX "cache_shared_expires_idx" ON "cache_shared" ("expires");
|
||||
|
||||
|
||||
CREATE TABLE "cache_index" (
|
||||
"user_id" integer NOT NULL
|
||||
REFERENCES "users" ("user_id") ON DELETE CASCADE,
|
||||
"mailbox" varchar(255) NOT NULL,
|
||||
"expires" timestamp with time zone DEFAULT NULL,
|
||||
"valid" smallint DEFAULT 0 NOT NULL,
|
||||
"data" long NOT NULL,
|
||||
PRIMARY KEY ("user_id", "mailbox")
|
||||
);
|
||||
|
||||
CREATE INDEX "cache_index_expires_idx" ON "cache_index" ("expires");
|
||||
|
||||
|
||||
CREATE TABLE "cache_thread" (
|
||||
"user_id" integer NOT NULL
|
||||
REFERENCES "users" ("user_id") ON DELETE CASCADE,
|
||||
"mailbox" varchar(255) NOT NULL,
|
||||
"expires" timestamp with time zone DEFAULT NULL,
|
||||
"data" long NOT NULL,
|
||||
PRIMARY KEY ("user_id", "mailbox")
|
||||
);
|
||||
|
||||
CREATE INDEX "cache_thread_expires_idx" ON "cache_thread" ("expires");
|
||||
|
||||
|
||||
CREATE TABLE "cache_messages" (
|
||||
"user_id" integer NOT NULL
|
||||
REFERENCES "users" ("user_id") ON DELETE CASCADE,
|
||||
"mailbox" varchar(255) NOT NULL,
|
||||
"uid" integer NOT NULL,
|
||||
"expires" timestamp with time zone DEFAULT NULL,
|
||||
"data" long NOT NULL,
|
||||
"flags" integer DEFAULT 0 NOT NULL,
|
||||
PRIMARY KEY ("user_id", "mailbox", "uid")
|
||||
);
|
||||
|
||||
CREATE INDEX "cache_messages_expires_idx" ON "cache_messages" ("expires");
|
||||
|
||||
|
||||
CREATE TABLE "dictionary" (
|
||||
"user_id" integer DEFAULT NULL
|
||||
REFERENCES "users" ("user_id") ON DELETE CASCADE,
|
||||
"language" varchar(16) NOT NULL,
|
||||
"data" long DEFAULT NULL,
|
||||
CONSTRAINT "dictionary_user_id_lang_key" UNIQUE ("user_id", "language")
|
||||
);
|
||||
|
||||
|
||||
CREATE TABLE "searches" (
|
||||
"search_id" integer PRIMARY KEY,
|
||||
"user_id" integer NOT NULL
|
||||
REFERENCES "users" ("user_id") ON DELETE CASCADE,
|
||||
"type" smallint DEFAULT 0 NOT NULL,
|
||||
"name" varchar(128) NOT NULL,
|
||||
"data" long NOT NULL,
|
||||
CONSTRAINT "searches_user_id_key" UNIQUE ("user_id", "type", "name")
|
||||
);
|
||||
|
||||
CREATE SEQUENCE "searches_seq"
|
||||
START WITH 1 INCREMENT BY 1 NOMAXVALUE;
|
||||
|
||||
CREATE TRIGGER "searches_seq_trig"
|
||||
BEFORE INSERT ON "searches" FOR EACH ROW
|
||||
BEGIN
|
||||
:NEW."search_id" := "searches_seq".nextval;
|
||||
END;
|
||||
/
|
||||
|
||||
CREATE TABLE "filestore" (
|
||||
"file_id" integer PRIMARY KEY,
|
||||
"user_id" integer NOT NULL
|
||||
REFERENCES "users" ("user_id") ON DELETE CASCADE ON UPDATE CASCADE,
|
||||
"context" varchar(32) NOT NULL,
|
||||
"filename" varchar(128) NOT NULL,
|
||||
"mtime" integer NOT NULL,
|
||||
"data" long,
|
||||
CONSTRAINT "filestore_user_id_key" UNIQUE ("user_id", "context", "filename")
|
||||
);
|
||||
|
||||
CREATE SEQUENCE "filestore_seq"
|
||||
START WITH 1 INCREMENT BY 1 NOMAXVALUE;
|
||||
|
||||
CREATE TRIGGER "filestore_seq_trig"
|
||||
BEFORE INSERT ON "filestore" FOR EACH ROW
|
||||
BEGIN
|
||||
:NEW."user_id" := "filestore_seq".nextval;
|
||||
END;
|
||||
/
|
||||
|
||||
CREATE TABLE "system" (
|
||||
"name" varchar(64) NOT NULL PRIMARY KEY,
|
||||
"value" long
|
||||
);
|
||||
|
||||
INSERT INTO "system" ("name", "value") VALUES ('roundcube-version', '2020020101');
|
@ -1 +0,0 @@
|
||||
-- empty
|
@ -1,2 +0,0 @@
|
||||
ALTER TABLE "users" ADD "failed_login" timestamp with time zone DEFAULT NULL;
|
||||
ALTER TABLE "users" ADD "failed_login_counter" integer DEFAULT NULL;
|
@ -1 +0,0 @@
|
||||
ALTER TABLE "session" DROP COLUMN "created";
|
@ -1 +0,0 @@
|
||||
ALTER TABLE "session" MODIFY "ip" varchar(41) NOT NULL;
|
@ -1,23 +0,0 @@
|
||||
DROP TABLE "cache";
|
||||
DROP TABLE "cache_shared";
|
||||
|
||||
CREATE TABLE "cache" (
|
||||
"user_id" integer NOT NULL
|
||||
REFERENCES "users" ("user_id") ON DELETE CASCADE,
|
||||
"cache_key" varchar(128) NOT NULL,
|
||||
"expires" timestamp with time zone DEFAULT NULL,
|
||||
"data" long NOT NULL,
|
||||
PRIMARY KEY ("user_id", "cache_key")
|
||||
);
|
||||
|
||||
CREATE INDEX "cache_expires_idx" ON "cache" ("expires");
|
||||
|
||||
|
||||
CREATE TABLE "cache_shared" (
|
||||
"cache_key" varchar(255) NOT NULL,
|
||||
"expires" timestamp with time zone DEFAULT NULL,
|
||||
"data" long NOT NULL,
|
||||
PRIMARY KEY ("cache_key")
|
||||
);
|
||||
|
||||
CREATE INDEX "cache_shared_expires_idx" ON "cache_shared" ("expires");
|
@ -1,19 +0,0 @@
|
||||
CREATE TABLE "filestore" (
|
||||
"file_id" integer PRIMARY KEY,
|
||||
"user_id" integer NOT NULL
|
||||
REFERENCES "users" ("user_id") ON DELETE CASCADE ON UPDATE CASCADE,
|
||||
"filename" varchar(128) NOT NULL,
|
||||
"mtime" integer NOT NULL,
|
||||
"data" long,
|
||||
CONSTRAINT "filestore_user_id_key" UNIQUE ("user_id", "filename")
|
||||
);
|
||||
|
||||
CREATE SEQUENCE "filestore_seq"
|
||||
START WITH 1 INCREMENT BY 1 NOMAXVALUE;
|
||||
|
||||
CREATE TRIGGER "filestore_seq_trig"
|
||||
BEFORE INSERT ON "filestore" FOR EACH ROW
|
||||
BEGIN
|
||||
:NEW."user_id" := "filestore_seq".nextval;
|
||||
END;
|
||||
/
|
@ -1,4 +0,0 @@
|
||||
ALTER TABLE "filestore" ADD COLUMN "context" varchar(32) NOT NULL;
|
||||
UPDATE "filestore" SET "context" = 'enigma';
|
||||
ALTER TABLE "filestore" DROP CONSTRAINT "filestore_user_id_key";
|
||||
ALTER TABLE "filestore" ADD CONSTRAINT "filestore_user_id_key" UNIQUE ("user_id", "context", "filename");
|
@ -1 +0,0 @@
|
||||
-- empty
|
@ -1,2 +0,0 @@
|
||||
ALTER TABLE "users" MODIFY "language" varchar(16) NOT NULL;
|
||||
ALTER TABLE "dictionary" MODIFY "language" varchar(16);
|
@ -1 +0,0 @@
|
||||
-- empty
|
@ -1 +0,0 @@
|
||||
-- empty
|
@ -1,2 +0,0 @@
|
||||
ALTER TABLE "users" ADD failed_login timestamp with time zone DEFAULT NULL;
|
||||
ALTER TABLE "users" ADD failed_login_counter integer DEFAULT NULL;
|
@ -1 +0,0 @@
|
||||
ALTER TABLE "session" DROP COLUMN created;
|
@ -1 +0,0 @@
|
||||
ALTER TABLE session ALTER COLUMN ip TYPE character varying(41);
|
@ -1,21 +0,0 @@
|
||||
DROP TABLE "cache";
|
||||
DROP TABLE "cache_shared";
|
||||
|
||||
CREATE TABLE "cache" (
|
||||
user_id integer NOT NULL
|
||||
REFERENCES users (user_id) ON DELETE CASCADE ON UPDATE CASCADE,
|
||||
cache_key varchar(128) DEFAULT '' NOT NULL,
|
||||
expires timestamp with time zone DEFAULT NULL,
|
||||
data text NOT NULL,
|
||||
PRIMARY KEY (user_id, cache_key)
|
||||
);
|
||||
|
||||
CREATE INDEX cache_expires_idx ON "cache" (expires);
|
||||
|
||||
CREATE TABLE "cache_shared" (
|
||||
cache_key varchar(255) NOT NULL PRIMARY KEY,
|
||||
expires timestamp with time zone DEFAULT NULL,
|
||||
data text NOT NULL
|
||||
);
|
||||
|
||||
CREATE INDEX cache_shared_expires_idx ON "cache_shared" (expires);
|
@ -1,15 +0,0 @@
|
||||
CREATE SEQUENCE "filestore_seq"
|
||||
INCREMENT BY 1
|
||||
NO MAXVALUE
|
||||
NO MINVALUE
|
||||
CACHE 1;
|
||||
|
||||
CREATE TABLE "filestore" (
|
||||
file_id integer DEFAULT nextval('filestore_seq'::text) PRIMARY KEY,
|
||||
user_id integer NOT NULL
|
||||
REFERENCES users (user_id) ON DELETE CASCADE ON UPDATE CASCADE,
|
||||
filename varchar(128) NOT NULL,
|
||||
mtime integer NOT NULL,
|
||||
data text NOT NULL,
|
||||
CONSTRAINT filestore_user_id_filename UNIQUE (user_id, filename)
|
||||
);
|
@ -1,4 +0,0 @@
|
||||
ALTER TABLE "filestore" ADD COLUMN context varchar(32) NOT NULL;
|
||||
UPDATE "filestore" SET context = 'enigma';
|
||||
ALTER TABLE "filestore" DROP CONSTRAINT "filestore_user_id_filename";
|
||||
ALTER TABLE "filestore" ADD CONSTRAINT "filestore_user_id_context_filename" UNIQUE (user_id, context, filename);
|
@ -1 +0,0 @@
|
||||
-- empty
|
@ -1,2 +0,0 @@
|
||||
ALTER TABLE "dictionary" ALTER COLUMN "language" TYPE varchar(16);
|
||||
ALTER TABLE "users" ALTER COLUMN "language" TYPE varchar(16);
|
@ -1 +0,0 @@
|
||||
-- empty
|
@ -1 +0,0 @@
|
||||
-- empty
|
@ -1,35 +0,0 @@
|
||||
CREATE TABLE tmp_users (
|
||||
user_id integer NOT NULL PRIMARY KEY,
|
||||
username varchar(128) NOT NULL default '',
|
||||
mail_host varchar(128) NOT NULL default '',
|
||||
created datetime NOT NULL default '0000-00-00 00:00:00',
|
||||
last_login datetime DEFAULT NULL,
|
||||
failed_login datetime DEFAULT NULL,
|
||||
failed_login_counter integer DEFAULT NULL,
|
||||
language varchar(5),
|
||||
preferences text NOT NULL default ''
|
||||
);
|
||||
|
||||
INSERT INTO tmp_users (user_id, username, mail_host, created, last_login, language, preferences)
|
||||
SELECT user_id, username, mail_host, created, last_login, language, preferences FROM users;
|
||||
|
||||
DROP TABLE users;
|
||||
|
||||
CREATE TABLE users (
|
||||
user_id integer NOT NULL PRIMARY KEY,
|
||||
username varchar(128) NOT NULL default '',
|
||||
mail_host varchar(128) NOT NULL default '',
|
||||
created datetime NOT NULL default '0000-00-00 00:00:00',
|
||||
last_login datetime DEFAULT NULL,
|
||||
failed_login datetime DEFAULT NULL,
|
||||
failed_login_counter integer DEFAULT NULL,
|
||||
language varchar(5),
|
||||
preferences text NOT NULL default ''
|
||||
);
|
||||
|
||||
INSERT INTO users (user_id, username, mail_host, created, last_login, language, preferences)
|
||||
SELECT user_id, username, mail_host, created, last_login, language, preferences FROM tmp_users;
|
||||
|
||||
CREATE UNIQUE INDEX ix_users_username ON users(username, mail_host);
|
||||
|
||||
DROP TABLE tmp_users;
|
@ -1,9 +0,0 @@
|
||||
DROP TABLE session;
|
||||
CREATE TABLE session (
|
||||
sess_id varchar(128) NOT NULL PRIMARY KEY,
|
||||
changed datetime NOT NULL default '0000-00-00 00:00:00',
|
||||
ip varchar(40) NOT NULL default '',
|
||||
vars text NOT NULL
|
||||
);
|
||||
|
||||
CREATE INDEX ix_session_changed ON session (changed);
|
@ -1,21 +0,0 @@
|
||||
DROP TABLE cache;
|
||||
DROP TABLE cache_shared;
|
||||
|
||||
CREATE TABLE cache (
|
||||
user_id integer NOT NULL default 0,
|
||||
cache_key varchar(128) NOT NULL default '',
|
||||
expires datetime DEFAULT NULL,
|
||||
data text NOT NULL,
|
||||
PRIMARY KEY (user_id, cache_key)
|
||||
);
|
||||
|
||||
CREATE INDEX ix_cache_expires ON cache(expires);
|
||||
|
||||
CREATE TABLE cache_shared (
|
||||
cache_key varchar(255) NOT NULL,
|
||||
expires datetime DEFAULT NULL,
|
||||
data text NOT NULL,
|
||||
PRIMARY KEY (cache_key)
|
||||
);
|
||||
|
||||
CREATE INDEX ix_cache_shared_expires ON cache_shared(expires);
|
@ -1,9 +0,0 @@
|
||||
CREATE TABLE filestore (
|
||||
file_id integer PRIMARY KEY,
|
||||
user_id integer NOT NULL,
|
||||
filename varchar(128) NOT NULL,
|
||||
mtime integer NOT NULL,
|
||||
data text NOT NULL
|
||||
);
|
||||
|
||||
CREATE UNIQUE INDEX ix_filestore_user_id ON filestore(user_id, filename);
|
@ -1,29 +0,0 @@
|
||||
CREATE TABLE tmp_filestore (
|
||||
file_id integer PRIMARY KEY,
|
||||
user_id integer NOT NULL,
|
||||
filename varchar(128) NOT NULL,
|
||||
mtime integer NOT NULL,
|
||||
data text NOT NULL
|
||||
);
|
||||
|
||||
INSERT INTO tmp_filestore (file_id, user_id, filename, mtime, data)
|
||||
SELECT file_id, user_id, filename, mtime, data FROM filestore;
|
||||
|
||||
DROP TABLE filestore;
|
||||
|
||||
CREATE TABLE filestore (
|
||||
file_id integer NOT NULL PRIMARY KEY,
|
||||
user_id integer NOT NULL,
|
||||
context varchar(32) NOT NULL,
|
||||
filename varchar(128) NOT NULL,
|
||||
mtime integer NOT NULL,
|
||||
data text NOT NULL
|
||||
);
|
||||
|
||||
INSERT INTO filestore (file_id, user_id, filename, mtime, data, context)
|
||||
SELECT file_id, user_id, filename, mtime, data, 'enigma' FROM tmp_filestore;
|
||||
|
||||
CREATE UNIQUE INDEX ix_filestore_user_id ON filestore(user_id, context, filename);
|
||||
|
||||
DROP TABLE tmp_filestore;
|
||||
|
@ -1 +0,0 @@
|
||||
-- empty
|
@ -1,57 +0,0 @@
|
||||
CREATE TABLE tmp_users (
|
||||
user_id integer NOT NULL PRIMARY KEY,
|
||||
username varchar(128) NOT NULL default '',
|
||||
mail_host varchar(128) NOT NULL default '',
|
||||
created datetime NOT NULL default '0000-00-00 00:00:00',
|
||||
last_login datetime DEFAULT NULL,
|
||||
failed_login datetime DEFAULT NULL,
|
||||
failed_login_counter integer DEFAULT NULL,
|
||||
language varchar(16),
|
||||
preferences text NOT NULL default ''
|
||||
);
|
||||
|
||||
INSERT INTO tmp_users (user_id, username, mail_host, created, last_login, failed_login, failed_login_counter, language, preferences)
|
||||
SELECT user_id, username, mail_host, created, last_login, failed_login, failed_login_counter, language, preferences FROM users;
|
||||
|
||||
DROP TABLE users;
|
||||
|
||||
CREATE TABLE users (
|
||||
user_id integer NOT NULL PRIMARY KEY,
|
||||
username varchar(128) NOT NULL default '',
|
||||
mail_host varchar(128) NOT NULL default '',
|
||||
created datetime NOT NULL default '0000-00-00 00:00:00',
|
||||
last_login datetime DEFAULT NULL,
|
||||
failed_login datetime DEFAULT NULL,
|
||||
failed_login_counter integer DEFAULT NULL,
|
||||
language varchar(16),
|
||||
preferences text NOT NULL default ''
|
||||
);
|
||||
|
||||
INSERT INTO users (user_id, username, mail_host, created, last_login, failed_login, failed_login_counter, language, preferences)
|
||||
SELECT user_id, username, mail_host, created, last_login, failed_login, failed_login_counter, language, preferences FROM tmp_users;
|
||||
|
||||
CREATE UNIQUE INDEX ix_users_username ON users(username, mail_host);
|
||||
|
||||
DROP TABLE tmp_users;
|
||||
|
||||
DROP TABLE users;
|
||||
|
||||
CREATE TABLE tmp_dictionary (
|
||||
user_id integer DEFAULT NULL,
|
||||
language varchar(16) NOT NULL,
|
||||
data text NOT NULL
|
||||
);
|
||||
|
||||
INSERT INTO tmp_dictionary (user_id, language, data) SELECT user_id, language, data FROM dictionary;
|
||||
|
||||
CREATE TABLE dictionary (
|
||||
user_id integer DEFAULT NULL,
|
||||
language varchar(16) NOT NULL,
|
||||
data text NOT NULL
|
||||
);
|
||||
|
||||
INSERT INTO dictionary (user_id, language, data) SELECT user_id, language, data FROM tmp_dictionary;
|
||||
|
||||
CREATE UNIQUE INDEX ix_dictionary_user_language ON dictionary (user_id, language);
|
||||
|
||||
DROP TABLE tmp_dictionary;
|
@ -1 +0,0 @@
|
||||
-- empty
|
@ -1,144 +0,0 @@
|
||||
#!/usr/bin/env php
|
||||
<?php
|
||||
|
||||
/*
|
||||
+-----------------------------------------------------------------------+
|
||||
| This file is part of the Roundcube Webmail client |
|
||||
| |
|
||||
| Copyright (C) The Roundcube Dev Team |
|
||||
| |
|
||||
| Licensed under the GNU General Public License version 3 or |
|
||||
| any later version with exceptions for skins & plugins. |
|
||||
| See the README file for a full license statement. |
|
||||
| |
|
||||
| PURPOSE: |
|
||||
| Utility script to remove all data related to a certain user |
|
||||
| from the local database. |
|
||||
+-----------------------------------------------------------------------+
|
||||
| Author: Thomas Bruederli <thomas@roundcube.net> |
|
||||
+-----------------------------------------------------------------------+
|
||||
*/
|
||||
|
||||
define('INSTALL_PATH', realpath(__DIR__ . '/..') . '/' );
|
||||
|
||||
require_once INSTALL_PATH . 'program/include/clisetup.php';
|
||||
|
||||
function print_usage()
|
||||
{
|
||||
print "Usage: deluser.sh [--host=HOST][--age=DAYS][--dry-run] [username]\n";
|
||||
print "--host=HOST The IMAP hostname or IP the given user is related to\n";
|
||||
print "--age=DAYS Delete all users who have not logged in for more than X days\n";
|
||||
print "--dry-run List users but do not delete them (for use with --age)\n";
|
||||
}
|
||||
|
||||
function _die($msg, $usage=false)
|
||||
{
|
||||
fwrite(STDERR, $msg . "\n");
|
||||
if ($usage) print_usage();
|
||||
exit(1);
|
||||
}
|
||||
|
||||
$rcmail = rcube::get_instance();
|
||||
|
||||
// get arguments
|
||||
$args = rcube_utils::get_opt(array('h' => 'host', 'a' => 'age', 'd' => 'dry-run:bool'));
|
||||
|
||||
if (!empty($args['age']) && ($age = intval($args['age']))) {
|
||||
$db = $rcmail->get_dbh();
|
||||
$db->db_connect('r');
|
||||
|
||||
$query = $db->query("SELECT `username`, `mail_host` FROM " . $db->table_name('users', true)
|
||||
. " WHERE `last_login` < " . $db->now($age * -1 * 86400)
|
||||
. ($args['host'] ? " AND `mail_host` = " . $db->quote($args['host']) : '')
|
||||
);
|
||||
|
||||
while ($user = $db->fetch_assoc($query)) {
|
||||
if (!empty($args['dry-run'])) {
|
||||
printf("%s (%s)\n", $user['username'], $user['mail_host']);
|
||||
continue;
|
||||
}
|
||||
system(sprintf("php %s/deluser.sh --host=%s %s", INSTALL_PATH . 'bin', $user['mail_host'], $user['username']));
|
||||
}
|
||||
exit(1);
|
||||
}
|
||||
|
||||
$username = trim($args[0]);
|
||||
if (empty($username)) {
|
||||
_die("Missing required parameters", true);
|
||||
}
|
||||
|
||||
if (empty($args['host'])) {
|
||||
$hosts = $rcmail->config->get('default_host', '');
|
||||
if (is_string($hosts)) {
|
||||
$args['host'] = $hosts;
|
||||
}
|
||||
else if (is_array($hosts) && count($hosts) == 1) {
|
||||
$args['host'] = reset($hosts);
|
||||
}
|
||||
else {
|
||||
_die("Specify a host name", true);
|
||||
}
|
||||
|
||||
// host can be a URL like tls://192.168.12.44
|
||||
$host_url = parse_url($args['host']);
|
||||
if ($host_url['host']) {
|
||||
$args['host'] = $host_url['host'];
|
||||
}
|
||||
}
|
||||
|
||||
// connect to DB
|
||||
$db = $rcmail->get_dbh();
|
||||
$db->db_connect('w');
|
||||
$transaction = false;
|
||||
|
||||
if (!$db->is_connected() || $db->is_error()) {
|
||||
_die("No DB connection\n" . $db->is_error());
|
||||
}
|
||||
|
||||
// find user in local database
|
||||
$user = rcube_user::query($username, $args['host']);
|
||||
|
||||
if (!$user) {
|
||||
die("User not found.\n");
|
||||
}
|
||||
|
||||
// inform plugins about approaching user deletion
|
||||
$plugin = $rcmail->plugins->exec_hook('user_delete_prepare', array('user' => $user, 'username' => $username, 'host' => $args['host']));
|
||||
|
||||
// let plugins cleanup their own user-related data
|
||||
if (!$plugin['abort']) {
|
||||
$transaction = $db->startTransaction();
|
||||
$plugin = $rcmail->plugins->exec_hook('user_delete', $plugin);
|
||||
}
|
||||
|
||||
if ($plugin['abort']) {
|
||||
if ($transaction) {
|
||||
$db->rollbackTransaction();
|
||||
}
|
||||
_die("User deletion aborted by plugin");
|
||||
}
|
||||
|
||||
// deleting the user record should be sufficient due to ON DELETE CASCADE foreign key references
|
||||
// but not all database backends actually support this so let's do it by hand
|
||||
foreach (array('identities','contacts','contactgroups','dictionary','cache','cache_index','cache_messages','cache_thread','searches','users') as $table) {
|
||||
$db->query('DELETE FROM ' . $db->table_name($table, true) . ' WHERE `user_id` = ?', $user->ID);
|
||||
}
|
||||
|
||||
if ($db->is_error()) {
|
||||
$rcmail->plugins->exec_hook('user_delete_rollback', $plugin);
|
||||
_die("DB error occurred: " . $db->is_error());
|
||||
}
|
||||
else {
|
||||
// inform plugins about executed user deletion
|
||||
$plugin = $rcmail->plugins->exec_hook('user_delete_commit', $plugin);
|
||||
|
||||
if ($plugin['abort']) {
|
||||
unset($plugin['abort']);
|
||||
$db->rollbackTransaction();
|
||||
$rcmail->plugins->exec_hook('user_delete_rollback', $plugin);
|
||||
}
|
||||
else {
|
||||
$db->endTransaction();
|
||||
echo "Successfully deleted user $user->ID\n";
|
||||
}
|
||||
}
|
@ -0,0 +1,233 @@
|
||||
#!/usr/bin/env php
|
||||
<?php
|
||||
/*
|
||||
+-----------------------------------------------------------------------+
|
||||
| bin/exportgettext.sh |
|
||||
| |
|
||||
| This file is part of the Roundcube Webmail client |
|
||||
| Copyright (C) 2011, The Roundcube Dev Team |
|
||||
| Licensed under the GNU General Public License |
|
||||
| |
|
||||
| PURPOSE: |
|
||||
| Export PHP-based localization files to PO files for gettext |
|
||||
+-----------------------------------------------------------------------+
|
||||
| Author: Thomas Bruederli <roundcube@gmail.com> |
|
||||
+-----------------------------------------------------------------------+
|
||||
*/
|
||||
|
||||
define('INSTALL_PATH', realpath(dirname(__FILE__) . '/..') . '/' );
|
||||
require INSTALL_PATH.'program/include/clisetup.php';
|
||||
|
||||
if ($argc < 2) {
|
||||
die("Usage: " . basename($argv[0]) . " SRCDIR DESTDIR\n");
|
||||
}
|
||||
|
||||
$srcdir = unslashify(realpath($argv[1]));
|
||||
$destdir = unslashify($argv[2]);
|
||||
$layout = 'launchpad'; # or 'narro';
|
||||
$langcode_map = array(
|
||||
'hy_AM' => 'hy',
|
||||
'ar_SA' => 'ar',
|
||||
'az_AZ' => 'az',
|
||||
'bg_BG' => 'bg',
|
||||
'bs_BA' => 'bs',
|
||||
'ca_ES' => 'ca',
|
||||
'cs_CZ' => 'cs',
|
||||
'cy_GB' => 'cy',
|
||||
'da_DK' => 'da',
|
||||
'et_EE' => 'et',
|
||||
'el_GR' => 'el',
|
||||
'eu_ES' => 'eu',
|
||||
'fa_IR' => 'fa',
|
||||
'ga_IE' => 'ga',
|
||||
'ka_GE' => 'ka',
|
||||
'gl_ES' => 'gl',
|
||||
'he_IL' => 'he',
|
||||
'hi_IN' => 'hi',
|
||||
'hr_HR' => 'hr',
|
||||
'ja_JP' => 'ja',
|
||||
'ko_KR' => 'ko',
|
||||
'km_KH' => 'km',
|
||||
'ms_MY' => 'ms',
|
||||
'mr_IN' => 'mr',
|
||||
'ml_IN' => 'ml',
|
||||
'pl_PL' => 'pl',
|
||||
'si_LK' => 'si',
|
||||
'sl_SI' => 'sl',
|
||||
'sq_AL' => 'sq',
|
||||
'sr_CS' => 'sr',
|
||||
'sv_SE' => 'sv',
|
||||
'uk_UA' => 'uk',
|
||||
'vi_VN' => 'vi',
|
||||
);
|
||||
|
||||
|
||||
// converting roundcube localization dir
|
||||
if (is_dir($srcdir.'/en_US')) {
|
||||
load_en_US($srcdir.'/en_US');
|
||||
|
||||
foreach (glob($srcdir.'/*') as $locdir) {
|
||||
if (is_dir($locdir)) {
|
||||
$lang = basename($locdir);
|
||||
//echo "$locdir => $destdir$lang\n";
|
||||
convert_dir($locdir, $destdir . ($layout != 'launchpad' ? $lang : ''));
|
||||
}
|
||||
}
|
||||
}
|
||||
// converting single localization directory
|
||||
else if (is_dir($srcdir)) {
|
||||
if (is_file($srcdir.'/en_US.inc')) // plugin localization
|
||||
load_en_US($srcdir.'/en_US.inc');
|
||||
else
|
||||
load_en_US(realpath($srcdir.'/../en_US')); // single language
|
||||
convert_dir($srcdir, $destdir);
|
||||
}
|
||||
// converting a single file
|
||||
else if (is_file($srcdir)) {
|
||||
//load_en_US();
|
||||
convert_file($srcdir, $destdir);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Load en_US localization which is used to build msgids
|
||||
*/
|
||||
function load_en_US($fn)
|
||||
{
|
||||
$texts = array();
|
||||
|
||||
if (is_dir($fn)) {
|
||||
foreach (glob($fn.'/*.inc') as $ifn) {
|
||||
include($ifn);
|
||||
$texts = array_merge($texts, (array)$labels, (array)$messages);
|
||||
}
|
||||
}
|
||||
else if (is_file($fn)) {
|
||||
include($fn);
|
||||
$texts = array_merge($texts, (array)$labels, (array)$messages);
|
||||
}
|
||||
|
||||
$GLOBALS['en_US'] = $texts;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert all .inc files in the given src directory
|
||||
*/
|
||||
function convert_dir($indir, $outdir)
|
||||
{
|
||||
global $layout;
|
||||
|
||||
if (!is_dir($outdir)) // attempt to create destination dir
|
||||
mkdir($outdir, 0777, true);
|
||||
|
||||
foreach (glob($indir.'/*.inc') as $fn) {
|
||||
$filename = basename($fn);
|
||||
|
||||
// create subdir for each template (launchpad rules)
|
||||
if ($layout == 'launchpad' && preg_match('/^(labels|messages)/', $filename, $m)) {
|
||||
$lang = end(explode('/', $indir));
|
||||
$destdir = $outdir . '/' . $m[1];
|
||||
if (!is_dir($destdir))
|
||||
mkdir($destdir, 0777, true);
|
||||
$outfn = $destdir . '/' . $lang . '.po';
|
||||
}
|
||||
else {
|
||||
$outfn = $outdir . '/' . preg_replace('/\.[a-z0-9]+$/i', '', basename($fn)) . '.po';
|
||||
}
|
||||
|
||||
convert_file($fn, $outfn);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert the given Roundcube localization file into a gettext .po file
|
||||
*/
|
||||
function convert_file($fn, $outfn)
|
||||
{
|
||||
global $layout, $langcode_map;
|
||||
|
||||
$basename = basename($fn);
|
||||
$srcname = str_replace(INSTALL_PATH, '', $fn);
|
||||
$product = preg_match('!plugins/(\w+)!', $srcname, $m) ? 'roundcube-plugin-' . $m[1] : 'roundcubemail';
|
||||
$lang = preg_match('!/([a-z]{2}(_[A-Z]{2})?)[./]!', $outfn, $m) ? $m[1] : '';
|
||||
$labels = $messages = $seen = array();
|
||||
|
||||
if (is_dir($outfn))
|
||||
$outfn .= '/' . $basename . '.po';
|
||||
|
||||
// launchpad requires the template file to have the same name as the directory
|
||||
if (strstr($outfn, '/en_US') && $layout == 'launchpad') {
|
||||
$a = explode('/', $outfn);
|
||||
array_pop($a);
|
||||
$templ = end($a);
|
||||
$a[] = $templ . '.pot';
|
||||
$outfn = join('/', $a);
|
||||
$is_pot = true;
|
||||
}
|
||||
// launchpad is very picky about file names
|
||||
else if ($layout == 'launchpad' && preg_match($regex = '!/([a-z]{2})_([A-Z]{2})!', $outfn, $m)) {
|
||||
if ($shortlang = $langcode_map[$lang])
|
||||
$outfn = preg_replace($regex, '/'.$shortlang, $outfn);
|
||||
else if ($m[1] == strtolower($m[2]))
|
||||
$outfn = preg_replace($regex, '/\1', $outfn);
|
||||
}
|
||||
|
||||
include($fn);
|
||||
$texts = array_merge($labels, $messages);
|
||||
|
||||
// write header
|
||||
$header = <<<EOF
|
||||
# Converted from Roundcube PHP localization files
|
||||
# Copyright (C) 2011 The Roundcube Dev Team
|
||||
# This file is distributed under the same license as the Roundcube package.
|
||||
#
|
||||
#: %s
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: %s\\n"
|
||||
"Report-Msgid-Bugs-To: \\n"
|
||||
"%s: %s\\n"
|
||||
"Last-Translator: \\n"
|
||||
"Language-Team: Translations <hello@roundcube.net>\\n"
|
||||
"Language: %s\\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\\n"
|
||||
"Content-Transfer-Encoding: 8bit\\n"
|
||||
EOF;
|
||||
|
||||
$out = sprintf($header, $srcname, $product, $is_pot ? "POT-Creation-Date" : "PO-Revision-Date", date('c'), $shortlang ? $shortlang : $lang);
|
||||
$out .= "\n";
|
||||
|
||||
$messages = array();
|
||||
foreach ((array)$texts as $label => $msgstr) {
|
||||
$msgid = $is_pot ? $msgstr : ($GLOBALS['en_US'][$label] ?: $label);
|
||||
$messages[$msgid][] = $label;
|
||||
}
|
||||
|
||||
foreach ($messages as $msgid => $labels) {
|
||||
$out .= "\n";
|
||||
foreach ($labels as $label)
|
||||
$out .= "#: $srcname:$label\n";
|
||||
$msgstr = $texts[$label];
|
||||
$out .= 'msgid ' . gettext_quote($msgid) . "\n";
|
||||
$out .= 'msgstr ' . gettext_quote(!$is_pot ? $msgstr : '') . "\n";
|
||||
}
|
||||
|
||||
if ($outfn == '-')
|
||||
echo $out;
|
||||
else {
|
||||
echo "$fn\t=>\t$outfn\n";
|
||||
file_put_contents($outfn, $out);
|
||||
}
|
||||
}
|
||||
|
||||
function gettext_quote($str)
|
||||
{
|
||||
$out = "";
|
||||
$lines = explode("\n", wordwrap(stripslashes($str)));
|
||||
$last = count($lines) - 1;
|
||||
foreach ($lines as $i => $line)
|
||||
$out .= '"' . addcslashes($line, '"') . ($i < $last ? ' ' : '') . "\"\n";
|
||||
return rtrim($out);
|
||||
}
|
||||
|
||||
?>
|
@ -0,0 +1,196 @@
|
||||
#!/usr/bin/env php
|
||||
<?php
|
||||
/*
|
||||
+-----------------------------------------------------------------------+
|
||||
| bin/importgettext.sh |
|
||||
| |
|
||||
| This file is part of the Roundcube Webmail client |
|
||||
| Copyright (C) 2011, The Roundcube Dev Team |
|
||||
| Licensed under the GNU General Public License |
|
||||
| |
|
||||
| PURPOSE: |
|
||||
| Import localizations from gettext PO format |
|
||||
+-----------------------------------------------------------------------+
|
||||
| Author: Thomas Bruederli <roundcube@gmail.com> |
|
||||
+-----------------------------------------------------------------------+
|
||||
*/
|
||||
|
||||
define('INSTALL_PATH', realpath(dirname(__FILE__) . '/..') . '/' );
|
||||
require INSTALL_PATH.'program/include/clisetup.php';
|
||||
|
||||
if ($argc < 2) {
|
||||
die("Usage: " . basename($argv[0]) . " SRCDIR\n");
|
||||
}
|
||||
|
||||
$srcdir = unslashify(realpath($argv[1]));
|
||||
|
||||
if (is_dir($srcdir)) {
|
||||
$out = import_dir($srcdir);
|
||||
}
|
||||
else if (is_file($srcdir)) {
|
||||
$out = import_file($srcdir);
|
||||
}
|
||||
|
||||
// write output files
|
||||
foreach ($out as $outfn => $texts) {
|
||||
$lang = preg_match('!/([a-z]{2}(_[A-Z]{2})?)[./]!', $outfn, $m) ? $m[1] : '';
|
||||
$varname = strpos($outfn, 'messages.inc') !== false ? 'messages' : 'labels';
|
||||
|
||||
$header = <<<EOF
|
||||
<?php
|
||||
|
||||
/*
|
||||
+-----------------------------------------------------------------------+
|
||||
| localization/%s/%-51s|
|
||||
| |
|
||||
| Language file of the Roundcube Webmail client |
|
||||
| Copyright (C) %s, The Roundcube Dev Team |
|
||||
| Licensed under the GNU General Public License |
|
||||
| |
|
||||
+-----------------------------------------------------------------------+
|
||||
| Author: %-62s|
|
||||
+-----------------------------------------------------------------------+
|
||||
*/
|
||||
|
||||
$%s = array();
|
||||
|
||||
EOF;
|
||||
|
||||
$author = preg_replace('/\s*<Unknown>/i', '', $texts['_translator']);
|
||||
$output = sprintf($header, $lang, $varname.'.inc', date('Y'), $author, $varname);
|
||||
|
||||
foreach ($texts as $label => $value) {
|
||||
if (is_array($value)) { var_dump($outfn, $label, $value); exit; }
|
||||
if ($label[0] != '_' && strlen($value))
|
||||
$output .= sprintf("\$%s['%s'] = '%s';\n", $varname, $label, strtr(addcslashes($value, "'"), array("\r" => '', "\n" => '\n')));
|
||||
}
|
||||
|
||||
$output .= "\n";
|
||||
$dir = dirname($outfn);
|
||||
@mkdir($dir, 0755, true);
|
||||
if (file_put_contents($outfn, $output))
|
||||
echo "-> $outfn\n";
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Convert all .po files in the given src directory
|
||||
*/
|
||||
function import_dir($indir)
|
||||
{
|
||||
$out = array();
|
||||
foreach (glob($indir.'/*.po') as $fn) {
|
||||
$out = array_merge_recursive($out, import_file($fn));
|
||||
}
|
||||
return $out;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert the given .po file into a Roundcube localization array
|
||||
*/
|
||||
function import_file($fn)
|
||||
{
|
||||
$out = array();
|
||||
$lines = file($fn);
|
||||
$language = '';
|
||||
$translator = '';
|
||||
|
||||
// get language code from file name
|
||||
if (preg_match('/-([a-z_]+).po$/i', $fn, $m))
|
||||
$language = expand_langcode($m[1]);
|
||||
|
||||
$is_header = true;
|
||||
$msgid = null;
|
||||
$msgstr = '';
|
||||
$dests = array();
|
||||
foreach ($lines as $i => $line) {
|
||||
$line = trim($line);
|
||||
|
||||
// parse header
|
||||
if ($is_header && $line[0] == '"') {
|
||||
list($key, $val) = explode(": ", preg_replace('/\\\n$/', '', trim($line, '"')), 2);
|
||||
switch (strtolower($key)) {
|
||||
case 'language':
|
||||
$language = expand_langcode($val);
|
||||
break;
|
||||
case 'last-translator':
|
||||
$translator = $val;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// empty line
|
||||
if ($line == '') {
|
||||
if ($msgid && $dests) {
|
||||
foreach ($dests as $dest) {
|
||||
list($file, $label) = explode(':', $dest);
|
||||
$out[$file][$label] = $msgstr;
|
||||
$out[$file]['_translator'] = $translator;
|
||||
}
|
||||
}
|
||||
|
||||
$msgid = null;
|
||||
$msgstr = '';
|
||||
$dests = array();
|
||||
}
|
||||
|
||||
// meta line
|
||||
if ($line[0] == '#') {
|
||||
$value = trim(substr($line, 2));
|
||||
if ($line[1] == ':')
|
||||
$dests[] = str_replace('en_US', $language, $value);
|
||||
}
|
||||
else if (strpos($line, 'msgid') === 0) {
|
||||
$msgid = gettext_decode(substr($line, 6));
|
||||
|
||||
if (!empty($msgid))
|
||||
$is_header = false;
|
||||
}
|
||||
else if (strpos($line, 'msgstr') === 0) {
|
||||
$msgstr = gettext_decode(substr($line, 7));
|
||||
}
|
||||
else if ($msgid && $line[0] == '"') {
|
||||
$msgstr .= gettext_decode($line);
|
||||
}
|
||||
else if ($msgid !== null && $line[0] == '"') {
|
||||
$msgid .= gettext_decode($line);
|
||||
}
|
||||
}
|
||||
|
||||
if ($msgid && $dests) {
|
||||
foreach ($dests as $dest) {
|
||||
list($file, $label) = explode(':', $dest);
|
||||
$out[$file][$label] = $msgstr;
|
||||
$out[$file]['_translator'] = $translator;
|
||||
}
|
||||
}
|
||||
|
||||
return $language ? $out : array();
|
||||
}
|
||||
|
||||
|
||||
function gettext_decode($str)
|
||||
{
|
||||
return stripslashes(trim($str, '"'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Translate two-chars language codes to our internally used language identifiers
|
||||
*/
|
||||
function expand_langcode($lang)
|
||||
{
|
||||
static $rcube_language_aliases, $rcube_languages;
|
||||
|
||||
if (!$rcube_language_aliases)
|
||||
include(INSTALL_PATH . 'program/localization/index.inc');
|
||||
|
||||
if ($rcube_language_aliases[$lang])
|
||||
return $rcube_language_aliases[$lang];
|
||||
else if (strlen($lang) == 2 && !isset($rcube_languages[$lang]))
|
||||
return strtolower($lang) . '_' . strtoupper($lang);
|
||||
else
|
||||
return $lang;
|
||||
}
|
||||
|
||||
|
||||
?>
|
@ -1,39 +0,0 @@
|
||||
#!/usr/bin/env php
|
||||
<?php
|
||||
/*
|
||||
+-----------------------------------------------------------------------+
|
||||
| This file is part of the Roundcube Webmail client |
|
||||
| |
|
||||
| Copyright (C) The Roundcube Dev Team |
|
||||
| Copyright (C) Kolab Systems AG |
|
||||
| |
|
||||
| Licensed under the GNU General Public License version 3 or |
|
||||
| any later version with exceptions for skins & plugins. |
|
||||
| See the README file for a full license statement. |
|
||||
| |
|
||||
| PURPOSE: |
|
||||
| Create database schema |
|
||||
+-----------------------------------------------------------------------+
|
||||
| Author: Aleksander Machniak <alec@alec.pl> |
|
||||
+-----------------------------------------------------------------------+
|
||||
*/
|
||||
|
||||
define('INSTALL_PATH', realpath(__DIR__ . '/..') . '/' );
|
||||
|
||||
require_once INSTALL_PATH . 'program/include/clisetup.php';
|
||||
|
||||
// get arguments
|
||||
$opts = rcube_utils::get_opt(array(
|
||||
'd' => 'dir',
|
||||
));
|
||||
|
||||
if (empty($opts['dir'])) {
|
||||
rcube::raise_error("Database schema directory not specified (--dir).", false, true);
|
||||
}
|
||||
|
||||
// Check if directory exists
|
||||
if (!file_exists($opts['dir'])) {
|
||||
rcube::raise_error("Specified database schema directory doesn't exist.", false, true);
|
||||
}
|
||||
|
||||
rcmail_utils::db_init($opts['dir']);
|
@ -1,385 +0,0 @@
|
||||
#!/usr/bin/env php
|
||||
<?php
|
||||
/*
|
||||
+-----------------------------------------------------------------------+
|
||||
| This file is part of the Roundcube Webmail client |
|
||||
| |
|
||||
| Copyright (C) The Roundcube Dev Team |
|
||||
| |
|
||||
| Licensed under the GNU General Public License version 3 or |
|
||||
| any later version with exceptions for skins & plugins. |
|
||||
| See the README file for a full license statement. |
|
||||
| |
|
||||
| PURPOSE: |
|
||||
| Utility script to fetch and install all 3rd party javascript |
|
||||
| libraries used in Roundcube from source. |
|
||||
+-----------------------------------------------------------------------+
|
||||
| Author: Thomas Bruederli <thomas@roundcube.net> |
|
||||
+-----------------------------------------------------------------------+
|
||||
*/
|
||||
|
||||
define('INSTALL_PATH', realpath(__DIR__ . '/..') . '/' );
|
||||
|
||||
require_once INSTALL_PATH . 'program/include/clisetup.php';
|
||||
|
||||
if (!function_exists('exec')) {
|
||||
rcube::raise_error("PHP exec() function is required. Check disable_functions in php.ini.", false, true);
|
||||
}
|
||||
|
||||
$cfgfile = INSTALL_PATH . 'jsdeps.json';
|
||||
$SOURCES = json_decode(file_get_contents($cfgfile), true);
|
||||
|
||||
if (empty($SOURCES['dependencies'])) {
|
||||
rcube::raise_error("Failed to read dependencies list from $cfgfile", false, true);
|
||||
}
|
||||
|
||||
$CURL = trim(`which curl`);
|
||||
$WGET = trim(`which wget`);
|
||||
$UNZIP = trim(`which unzip`);
|
||||
|
||||
if (($CACHEDIR = getenv("CACHEDIR")) && is_writeable($CACHEDIR)) {
|
||||
// use $CACHEDIR
|
||||
}
|
||||
else if (is_writeable(INSTALL_PATH . 'temp/js_cache') || @mkdir(INSTALL_PATH . 'temp/js_cache', 0774, true)) {
|
||||
$CACHEDIR = INSTALL_PATH . 'temp/js_cache';
|
||||
}
|
||||
else {
|
||||
$CACHEDIR = sys_get_temp_dir();
|
||||
}
|
||||
|
||||
|
||||
//////////////// License definitions
|
||||
|
||||
$LICENSES = array();
|
||||
$LICENSES['MIT'] = <<<EOM
|
||||
* Licensed under the MIT licenses
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
EOM;
|
||||
|
||||
$LICENSES['GPLv3'] = <<<EOG
|
||||
* The JavaScript code in this page is free software: you can
|
||||
* redistribute it and/or modify it under the terms of the GNU
|
||||
* General Public License (GNU GPL) as published by the Free Software
|
||||
* Foundation, either version 3 of the License, or (at your option)
|
||||
* any later version. The code is distributed WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
* FOR A PARTICULAR PURPOSE. See the GNU GPL for more details.
|
||||
*
|
||||
* As additional permission under GNU GPL version 3 section 7, you
|
||||
* may distribute non-source (e.g., minimized or compacted) forms of
|
||||
* that code without the copy of the GNU GPL normally required by
|
||||
* section 4, provided you include this license notice and a URL
|
||||
* through which recipients can access the Corresponding Source.
|
||||
|
||||
EOG;
|
||||
|
||||
$LICENSES['LGPL'] = <<<EOL
|
||||
* The JavaScript code in this page is free software: you can
|
||||
* redistribute it and/or modify it under the terms of the GNU
|
||||
* Lesser General Public License as published by the Free Software
|
||||
* Foundation, either version 3 of the License, or (at your option)
|
||||
* any later version.
|
||||
|
||||
EOL;
|
||||
|
||||
|
||||
//////////////// Functions
|
||||
|
||||
/**
|
||||
* Fetch package file from source
|
||||
*/
|
||||
function fetch_from_source($package, $useCache = true, &$filetype = null)
|
||||
{
|
||||
global $CURL, $WGET;
|
||||
|
||||
$cache_file = extract_filetype($package, $filetype);
|
||||
|
||||
if (!is_readable($cache_file) || !$useCache) {
|
||||
if (empty($CURL) && empty($WGET)) {
|
||||
rcube::raise_error("Required 'wget' or 'curl' program not found.", false, true);
|
||||
}
|
||||
|
||||
$url = str_replace('$v', $package['version'], $package['url']);
|
||||
|
||||
echo "Fetching $url\n";
|
||||
|
||||
if ($CURL)
|
||||
exec(sprintf('%s -L -s %s -o %s', $CURL, escapeshellarg($url), $cache_file), $out, $retval);
|
||||
else
|
||||
exec(sprintf('%s -q %s -O %s', $WGET, escapeshellarg($url), $cache_file), $out, $retval);
|
||||
|
||||
// Try Github API as a fallback (#6248)
|
||||
if ($retval !== 0 && $package['api_url']) {
|
||||
$url = str_replace('$v', $package['version'], $package['api_url']);
|
||||
$header = 'Accept:application/vnd.github.v3.raw';
|
||||
|
||||
rcube::raise_error("Fetching failed. Using Github API on $url");
|
||||
|
||||
if ($CURL)
|
||||
exec(sprintf('%s -L -H %s -s %s -o %s', $CURL, escapeshellarg($header), escapeshellarg($url), $cache_file), $out, $retval);
|
||||
else
|
||||
exec(sprintf('%s --header %s -q %s -O %s', $WGET, escapeshellarg($header), escapeshellarg($url), $cache_file), $out, $retval);
|
||||
}
|
||||
|
||||
if ($retval !== 0) {
|
||||
rcube::raise_error("Failed to download source file from $url", false, true);
|
||||
}
|
||||
}
|
||||
|
||||
return $cache_file;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns package source file location and type
|
||||
*/
|
||||
function extract_filetype($package, &$filetype = null)
|
||||
{
|
||||
global $CACHEDIR;
|
||||
|
||||
$filetype = pathinfo($package['url'], PATHINFO_EXTENSION) ?: 'tmp';
|
||||
$cache_file = $CACHEDIR . '/' . $package['lib'] . '-' . $package['version'] . '.' . $filetype;
|
||||
|
||||
// Make sure it is a zip file
|
||||
if (file_exists($cache_file)) {
|
||||
$magic = file_get_contents($cache_file, false, null, 0, 4);
|
||||
if ($magic === "PK\003\004") {
|
||||
$filetype = 'zip';
|
||||
}
|
||||
}
|
||||
|
||||
return $cache_file;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a destination javascript file with copyright and license header
|
||||
*/
|
||||
function compose_destfile($package, $srcfile)
|
||||
{
|
||||
global $LICENSES;
|
||||
|
||||
$header = sprintf("/**\n * %s - v%s\n *\n", $package['name'], $package['version']);
|
||||
|
||||
if (!empty($package['source'])) {
|
||||
$header .= " * @source " . str_replace('$v', $package['version'], $package['source']) . "\n";
|
||||
$header .= " *\n";
|
||||
}
|
||||
|
||||
if (!empty($package['license']) && isset($LICENSES[$package['license']])) {
|
||||
$header .= " * @licstart The following is the entire license notice for the\n";
|
||||
$header .= " * JavaScript code in this file.\n";
|
||||
$header .= " *\n";
|
||||
if (!empty($package['copyright'])) {
|
||||
$header .= " * " . $package['copyright'] . "\n";
|
||||
$header .= " *\n";
|
||||
}
|
||||
|
||||
$header .= $LICENSES[$package['license']];
|
||||
$header .= " *\n";
|
||||
$header .= " * @licend The above is the entire license notice\n";
|
||||
$header .= " * for the JavaScript code in this file.\n";
|
||||
}
|
||||
|
||||
$header .= " */\n";
|
||||
|
||||
if (file_put_contents(INSTALL_PATH . $package['dest'], $header . file_get_contents($srcfile))) {
|
||||
echo "Wrote file " . INSTALL_PATH . $package['dest'] . "\n";
|
||||
}
|
||||
else {
|
||||
rcube::raise_error("Failed to write destination file " . INSTALL_PATH . $package['dest'], false, true);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Extract a Zip archive into the destination specified by the package config
|
||||
*/
|
||||
function extract_zipfile($package, $srcfile)
|
||||
{
|
||||
global $UNZIP, $CACHEDIR;
|
||||
|
||||
if (empty($UNZIP)) {
|
||||
rcube::raise_error("Required 'unzip' program not found.", false, true);
|
||||
}
|
||||
|
||||
$destdir = INSTALL_PATH . $package['dest'];
|
||||
if (!is_dir($destdir)) {
|
||||
mkdir($destdir, 0775, true);
|
||||
}
|
||||
|
||||
if (!is_writeable($destdir)) {
|
||||
rcube::raise_error("Cannot write to destination directory: $destdir", false, true);
|
||||
}
|
||||
|
||||
// pick files from zip archive
|
||||
if (!empty($package['pick'])) {
|
||||
foreach ($package['pick'] as $pattern) {
|
||||
echo "Extracting files $pattern into $destdir\n";
|
||||
exec(sprintf('%s -o %s %s -d %s', $UNZIP, escapeshellarg($srcfile), escapeshellarg($pattern), $destdir), $out, $retval);
|
||||
if ($retval !== 0) {
|
||||
rcube::raise_error("Failed to unpack $pattern; " . implode('; ' . $out));
|
||||
}
|
||||
}
|
||||
}
|
||||
// unzip the archive and map source to dest files/directories
|
||||
else if (!empty($package['map'])) {
|
||||
$extract = $CACHEDIR . '/' . $package['lib'] . '-extract';
|
||||
if (!is_dir($extract)) {
|
||||
mkdir($extract, 0774, true);
|
||||
}
|
||||
|
||||
$zip_command = '%s -' . ($package['flat'] ? 'j' : 'o') . ' %s -d %s';
|
||||
exec(sprintf($zip_command, $UNZIP, escapeshellarg($srcfile), $extract), $out, $retval);
|
||||
|
||||
// get the root folder of the extracted package
|
||||
$extract_tree = glob("$extract/*", GLOB_ONLYDIR);
|
||||
$sourcedir = count($extract_tree) ? $extract_tree[0] : $extract;
|
||||
|
||||
foreach ($package['map'] as $src => $dest) {
|
||||
echo "Installing $sourcedir/$src into $destdir/$dest\n";
|
||||
|
||||
$dest_file = $destdir . '/' . $dest;
|
||||
$src_file = $sourcedir . '/' . $src;
|
||||
|
||||
// make sure the destination's parent directory exists
|
||||
if (strpos($dest, '/') !== false) {
|
||||
$parentdir = dirname($dest_file);
|
||||
if (!is_dir($parentdir)) {
|
||||
mkdir($parentdir, 0775, true);
|
||||
}
|
||||
}
|
||||
|
||||
// avoid copying source directory as a child into destination
|
||||
if (is_dir($src_file) && is_dir($dest_file)) {
|
||||
exec(sprintf('rm -rf %s', $dest_file));
|
||||
}
|
||||
|
||||
exec(sprintf('mv -f %s %s', $src_file, $dest_file), $out, $retval);
|
||||
if ($retval !== 0) {
|
||||
rcube::raise_error("Failed to move $src into $dest_file; " . implode('; ' . $out));
|
||||
}
|
||||
// Remove sourceMappingURL
|
||||
else if (isset($package['sourcemap']) && $package['sourcemap'] === false) {
|
||||
if ($content = file($dest_file)) {
|
||||
$index = count($content);
|
||||
if (preg_match('|sourceMappingURL=|', $content[$index-1])) {
|
||||
array_pop($content);
|
||||
file_put_contents($dest_file, implode('', $content));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// remove temp extraction dir
|
||||
exec('rm -rf ' . $extract);
|
||||
}
|
||||
// extract the archive into the destination directory
|
||||
else {
|
||||
echo "Extracting zip archive into $destdir\n";
|
||||
exec(sprintf('%s -o %s -d %s', $UNZIP, escapeshellarg($srcfile), $destdir), $out, $retval);
|
||||
if ($retval !== 0) {
|
||||
rcube::raise_error("Failed to unzip $srcfile; " . implode('; ' . $out));
|
||||
}
|
||||
}
|
||||
|
||||
// remove some files from the destination
|
||||
if (!empty($package['omit'])) {
|
||||
foreach ((array)$package['omit'] as $glob) {
|
||||
exec(sprintf('rm -rf %s/%s', $destdir, escapeshellarg($glob)));
|
||||
}
|
||||
}
|
||||
|
||||
// prepend license header to extracted files
|
||||
if (!empty($package['addlicense'])) {
|
||||
foreach ((array)$package['addlicense'] as $filename) {
|
||||
$pkg = $package;
|
||||
$pkg['dest'] = $package['dest'] . '/' . $filename;
|
||||
compose_destfile($pkg, $destdir . '/' . $filename);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete the package destination file/dir
|
||||
*/
|
||||
function delete_destfile($package)
|
||||
{
|
||||
$destdir = INSTALL_PATH . ($package['rm'] ?: $package['dest']);
|
||||
|
||||
if (file_exists($destdir)) {
|
||||
if (PHP_OS === 'Windows') {
|
||||
exec(sprintf("rd /s /q %s", escapeshellarg($destdir)));
|
||||
}
|
||||
else {
|
||||
exec(sprintf("rm -rf %s", escapeshellarg($destdir)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//////////////// Execution
|
||||
|
||||
$args = rcube_utils::get_opt(array('f' => 'force:bool', 'd' => 'delete:bool', 'g' => 'get:bool', 'e' => 'extract:bool'))
|
||||
+ array('force' => false, 'delete' => false, 'get' => false, 'extract' => false);
|
||||
$WHAT = $args[0];
|
||||
$useCache = !$args['force'] && !$args['get'];
|
||||
|
||||
if (!$args['get'] && !$args['extract'] && !$args['delete']) {
|
||||
$args['get'] = $args['extract'] = 1;
|
||||
}
|
||||
|
||||
foreach ($SOURCES['dependencies'] as $package) {
|
||||
if (!isset($package['name'])) {
|
||||
$package['name'] = $package['lib'];
|
||||
}
|
||||
|
||||
if ($WHAT && $package['lib'] !== $WHAT) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ($args['delete']) {
|
||||
delete_destfile($package);
|
||||
continue;
|
||||
}
|
||||
|
||||
if ($args['get']) {
|
||||
$srcfile = fetch_from_source($package, $useCache, $filetype);
|
||||
}
|
||||
else {
|
||||
$srcfile = extract_filetype($package, $filetype);
|
||||
}
|
||||
|
||||
if (!empty($package['sha1']) && ($sum = sha1_file($srcfile)) !== $package['sha1']) {
|
||||
rcube::raise_error("Incorrect sha1 sum of $srcfile. Expected: {$package['sha1']}, got: $sum", false, true);
|
||||
}
|
||||
|
||||
if ($args['extract']) {
|
||||
echo "Installing {$package['name']}...\n";
|
||||
|
||||
if ($filetype === 'zip') {
|
||||
extract_zipfile($package, $srcfile);
|
||||
}
|
||||
else {
|
||||
compose_destfile($package, $srcfile);
|
||||
}
|
||||
|
||||
echo "Done.\n";
|
||||
}
|
||||
}
|
@ -1,23 +0,0 @@
|
||||
#!/bin/sh
|
||||
|
||||
TITLE="Roundcube Webmail"
|
||||
PACKAGES="Webmail"
|
||||
|
||||
INSTALL_PATH="`dirname $0`/.."
|
||||
PATH_PROJECT=$INSTALL_PATH/program/include
|
||||
PATH_FRAMEWORK=$INSTALL_PATH/program/lib/Roundcube
|
||||
PATH_DOCS=$INSTALL_PATH/doc/phpdoc
|
||||
BIN_PHPDOC="`/usr/bin/which phpdoc`"
|
||||
|
||||
if [ ! -x "$BIN_PHPDOC" ]
|
||||
then
|
||||
echo "phpdoc not found: $BIN_PHPDOC"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
OUTPUTFORMAT=HTML
|
||||
TEMPLATE=responsive-twig
|
||||
|
||||
# make documentation
|
||||
$BIN_PHPDOC -d $PATH_PROJECT,$PATH_FRAMEWORK -t $PATH_DOCS --title "$TITLE" \
|
||||
--defaultpackagename $PACKAGES --template=$TEMPLATE
|
@ -1,7 +0,0 @@
|
||||
# deny webserver access to this directory
|
||||
<ifModule mod_authz_core.c>
|
||||
Require all denied
|
||||
</ifModule>
|
||||
<ifModule !mod_authz_core.c>
|
||||
Deny from all
|
||||
</ifModule>
|
Before Width: | Height: | Size: 653 B After Width: | Height: | Size: 733 B |
Before Width: | Height: | Size: 637 B After Width: | Height: | Size: 715 B |
Before Width: | Height: | Size: 565 B After Width: | Height: | Size: 666 B |
Before Width: | Height: | Size: 3.7 KiB After Width: | Height: | Size: 7.8 KiB |