Compare commits

...

575 Commits
master ... dist

Author SHA1 Message Date
FreeScout
f92cb048fe Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2026-10-03 03:20:09 -07:00
FreeScout
628e3ae5b5 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2026-10-02 21:29:55 -07:00
FreeScout
684f81409a Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2026-09-27 03:41:36 -07:00
FreeScout
77175143d9 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2026-09-25 23:03:17 -07:00
FreeScout
88734eec10 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2026-09-18 21:16:11 -07:00
FreeScout
fe7d4711c0 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2026-09-11 22:58:18 -07:00
FreeScout
3b471b17cf Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2026-09-03 22:13:26 -07:00
FreeScout
4080415870 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2026-08-30 22:48:38 -07:00
FreeScout
4b17e534a7 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2026-08-29 03:00:55 -07:00
FreeScout
a9572ca50a Add vendor files to dist 2026-08-23 22:28:51 -07:00
FreeScout
63b008c6d2 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2026-08-23 22:28:24 -07:00
FreeScout
ab27725368 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2026-08-15 02:35:45 -07:00
FreeScout
ec0faecf7f Add vendor files to dist 2026-08-14 02:04:13 -07:00
FreeScout
71e77d7b5a Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2026-08-14 02:03:40 -07:00
FreeScout
9492779dfc Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2026-08-06 21:22:21 -07:00
FreeScout
e081807436 Add vendor files to dist 2026-07-31 01:11:56 -07:00
FreeScout
49f52f7fd9 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2026-07-31 01:06:11 -07:00
FreeScout
196f3663d5 Add vendor files to dist 2026-07-25 03:29:27 -07:00
FreeScout
e08cdd5288 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2026-07-25 03:26:17 -07:00
FreeScout
5ce756de00 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2026-07-18 09:25:32 -07:00
FreeScout
8cf431fc0f Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2026-07-04 07:46:42 -07:00
FreeScout
3e577e82ca Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2026-07-04 07:30:23 -07:00
FreeScout
bf6d0abf5c Add vendor files to dist 2026-07-04 02:55:38 -07:00
FreeScout
e02b943b3f Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2026-07-04 02:54:41 -07:00
FreeScout
779adccea0 Add vendor files to dist 2026-06-27 02:42:32 -07:00
FreeScout
62465bce79 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2026-06-27 02:41:41 -07:00
FreeScout
74fa4b7d4f Add vendor files to dist 2026-06-12 21:52:34 -07:00
FreeScout
899548fafa Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2026-06-12 21:52:01 -07:00
FreeScout
11a542e3be Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2026-06-05 22:13:29 -07:00
FreeScout
7cb9f8c713 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2026-05-30 04:33:40 -07:00
FreeScout
72525cce6c Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2026-05-25 01:39:16 -07:00
FreeScout
25ea3d9388 Add vendor files to dist 2026-05-22 22:36:20 -07:00
FreeScout
a43239d8f0 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2026-05-22 22:35:57 -07:00
FreeScout
f3190f03c7 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2026-05-16 21:48:33 -07:00
FreeScout
49a9a4de64 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2026-05-08 10:32:36 -07:00
FreeScout
518058aacf Add vendor files to dist 2026-04-24 21:55:55 -07:00
FreeScout
9fa67358ae Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2026-04-24 21:55:23 -07:00
FreeScout
c4e4220ae3 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2026-04-19 07:20:04 -07:00
FreeScout
e6fe63e71f Add vendor files to dist 2026-04-16 03:19:11 -07:00
FreeScout
34677264d5 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2026-04-16 03:18:42 -07:00
FreeScout
9a691124c6 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2026-04-14 07:44:53 -07:00
FreeScout
abf82ecc3e Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2026-04-12 08:57:41 -07:00
FreeScout
acf57a7a4b Add vendor files to dist 2026-04-09 10:30:34 -07:00
FreeScout
0425b26bc9 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2026-04-09 10:29:55 -07:00
FreeScout
561eba496a Add vendor files to dist 2026-04-03 21:56:38 -07:00
FreeScout
00de71168b Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2026-04-03 21:53:38 -07:00
FreeScout
d8708d55e9 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2026-03-27 22:51:06 -07:00
FreeScout
33e8c60d89 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2026-03-22 21:55:28 -07:00
FreeScout
9272158c98 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2026-03-13 21:59:20 -07:00
FreeScout
024c122758 Add vendor files to dist 2026-03-05 20:42:08 -08:00
FreeScout
c9d6ba4f68 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2026-03-05 20:41:00 -08:00
FreeScout
2f9a824ece Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2026-02-27 00:38:01 -08:00
FreeScout
152e60f672 Add vendor files to dist 2026-02-26 22:15:24 -08:00
FreeScout
8c0e161f8d Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2026-02-26 22:14:32 -08:00
FreeScout
63b225e380 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2026-02-21 00:59:14 -08:00
FreeScout
11b98a109a Add vendor files to dist 2026-02-14 00:27:45 -08:00
FreeScout
446e75e969 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2026-02-14 00:24:05 -08:00
FreeScout
d0d7f01924 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2026-02-07 20:57:32 -08:00
FreeScout
6fa9cd20f1 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2026-02-07 20:51:45 -08:00
FreeScout
661f7093f7 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2026-01-24 22:09:46 -08:00
FreeScout
34d5973579 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2026-01-15 20:42:46 -08:00
FreeScout
1a4abad9c4 Add vendor files to dist 2026-01-05 02:42:40 -08:00
FreeScout
ec40bc80a0 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2026-01-05 02:41:41 -08:00
FreeScout
64cebaed0d Add vendor files to dist 2025-12-19 03:33:43 -08:00
FreeScout
28b73fe679 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2025-12-19 03:33:01 -08:00
FreeScout
d8826584bc Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2025-12-10 20:29:09 -08:00
FreeScout
694a89b757 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2025-12-05 21:51:10 -08:00
FreeScout
ab2aa141ce Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2025-11-21 09:51:26 -08:00
FreeScout
b0c32f9166 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2025-11-21 09:37:29 -08:00
FreeScout
3a70c8b491 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2025-10-31 21:36:58 -07:00
FreeScout
0f47d93c8b Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2025-10-17 09:42:42 -07:00
FreeScout
0870d9e94b Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2025-10-06 21:45:40 -07:00
FreeScout
b0d589c3a4 Add vendor files to dist 2025-08-30 22:55:04 -07:00
FreeScout
f8f9400e06 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2025-08-30 22:53:10 -07:00
FreeScout
1373b3b939 Add vendor files to dist 2025-08-17 21:42:14 -07:00
FreeScout
3ad3cf5ab9 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2025-08-17 21:41:19 -07:00
FreeScout
dc4d2c86ba Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2025-08-01 03:20:49 -07:00
FreeScout
aba50ed13d Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2025-07-25 23:04:55 -07:00
FreeScout
ecb28aef60 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2025-07-21 05:05:04 -07:00
FreeScout
a02cc2878e Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2025-07-21 03:24:07 -07:00
FreeScout
53f6100f2c Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2025-07-19 04:29:38 -07:00
FreeScout
a4e9e89518 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2025-07-05 02:36:31 -07:00
FreeScout
c0ae0ca567 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2025-06-22 05:38:20 -07:00
FreeScout
fb2fd080fe Add vendor files to dist 2025-06-13 23:18:43 -07:00
FreeScout
6a27f13f3c Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2025-06-13 23:17:55 -07:00
FreeScout
ca675b0815 Add vendor files to dist 2025-06-02 23:00:31 -07:00
FreeScout
a3e6826b2f Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2025-06-02 22:59:34 -07:00
FreeScout
fb346f2e2e Add vendor files to dist 2025-05-27 00:01:08 -07:00
FreeScout
b0804c6dca Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2025-05-26 23:59:31 -07:00
FreeScout
9879e29c20 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2025-05-22 19:29:49 -07:00
FreeScout
0a8fe89a92 Add vendor files to dist 2025-05-18 03:44:23 -07:00
FreeScout
d9f96d4e03 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2025-05-18 03:43:34 -07:00
FreeScout
eab9771102 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2025-05-14 23:34:52 -07:00
FreeScout
9070732d2c Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2025-05-13 12:03:41 -07:00
FreeScout
e4b21c9797 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2025-05-13 11:07:45 -07:00
FreeScout
1ced45029e Add vendor files to dist 2025-04-25 23:57:06 -07:00
FreeScout
639c08c1f3 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2025-04-25 23:56:32 -07:00
FreeScout
1839a43359 Add vendor files to dist 2025-04-04 05:38:45 -07:00
FreeScout
64d21bcecf Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2025-04-04 05:37:46 -07:00
FreeScout
31c72b8092 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2025-02-28 00:15:15 -08:00
FreeScout
b8f82a15a9 Add vendor files to dist 2025-02-21 00:49:59 -08:00
FreeScout
792cb95718 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2025-02-21 00:49:02 -08:00
FreeScout
ec4cf9a457 Add vendor files to dist 2025-02-14 03:33:22 -08:00
FreeScout
f7e20304b2 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2025-02-14 03:32:28 -08:00
FreeScout
d9ada9c6ec Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2025-02-07 05:22:47 -08:00
FreeScout
d95ab52c4d Add vendor files to dist 2025-02-06 23:40:39 -08:00
FreeScout
4d889e31e4 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2025-02-06 23:39:40 -08:00
FreeScout
ec83995838 Add vendor files to dist 2025-01-24 05:58:27 -08:00
FreeScout
e71de79923 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2025-01-24 05:57:46 -08:00
FreeScout
e1a493acd8 Add vendor files to dist 2025-01-22 20:16:21 -08:00
FreeScout
c8c0db5cb9 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2025-01-22 20:14:50 -08:00
FreeScout
9b0cec6b2b Add vendor files to dist 2025-01-21 03:27:14 -08:00
FreeScout
736e931529 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2025-01-21 03:25:26 -08:00
FreeScout
ab8309bdab Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2025-01-18 01:53:52 -08:00
FreeScout
3a33fd4628 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2025-01-17 20:45:37 -08:00
FreeScout
33a7d06032 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2025-01-17 02:00:23 -08:00
FreeScout
177e54f1f2 Add vendor files to dist 2025-01-16 23:28:40 -08:00
FreeScout
7efa8f5a1c Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2025-01-16 23:26:40 -08:00
FreeScout
b26fb0e13a Add vendor files to dist 2025-01-13 03:00:56 -08:00
FreeScout
fa46d45662 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2025-01-13 03:00:07 -08:00
FreeScout
178ac6d19b Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2024-12-20 08:28:52 -08:00
FreeScout
b564d20627 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2024-11-29 20:45:28 -08:00
FreeScout
bfbfeb2e66 Add vendor files to dist 2024-11-22 00:37:13 -08:00
FreeScout
a11df91aa4 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2024-11-22 00:34:55 -08:00
FreeScout
009c51e245 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2024-11-14 23:36:24 -08:00
FreeScout
e2360f2146 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2024-11-04 08:24:58 -08:00
FreeScout
b6987ddb90 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2024-11-01 21:45:43 -07:00
FreeScout
30b07a82c7 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2024-10-04 04:34:21 -07:00
FreeScout
5c9ab337ea Add vendor files to dist 2024-09-22 07:01:39 -07:00
FreeScout
f6e18818cd Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2024-09-22 07:00:04 -07:00
FreeScout
f218fe17d0 Add vendor files to dist 2024-08-27 23:15:39 -07:00
FreeScout
a2979a4406 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2024-08-27 23:15:16 -07:00
FreeScout
adc9921108 Add vendor files to dist 2024-08-27 04:52:34 -07:00
FreeScout
f326b14776 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2024-08-27 04:52:00 -07:00
FreeScout
c0ce07a2b9 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2024-08-15 20:10:13 -07:00
FreeScout
223b4d12dc Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2024-08-14 09:51:38 -07:00
FreeScout
c4a6585cc7 Add vendor files to dist 2024-08-08 04:17:10 -07:00
FreeScout
d99d991650 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2024-08-08 04:16:35 -07:00
FreeScout
7383b95864 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2024-07-21 06:19:34 -07:00
FreeScout
2f9d1bf92e Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2024-07-08 01:44:11 -07:00
FreeScout
7c3e57aa57 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2024-06-19 11:39:48 -07:00
FreeScout
755e4f0cd7 Add vendor files to dist 2024-06-17 22:12:38 -07:00
FreeScout
a2a0539316 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2024-06-17 22:11:43 -07:00
FreeScout
3c199f697c Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2024-06-10 10:25:57 -07:00
FreeScout
21a73fa5e6 Add vendor files to dist 2024-06-09 09:37:24 -07:00
FreeScout
c9b2c3cc36 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2024-06-09 09:36:57 -07:00
FreeScout
0ac8685c63 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2024-05-30 04:55:43 -07:00
FreeScout
2d871f2759 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2024-05-15 22:57:28 -07:00
FreeScout
70a7ec54ea Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2024-05-10 22:15:09 -07:00
FreeScout
a50c261f13 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2024-04-26 06:41:18 -07:00
FreeScout
17024f814a Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2024-04-22 09:35:48 -07:00
FreeScout
0ecfa248ee Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2024-04-18 23:35:34 -07:00
FreeScout
7829e9a3ba Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2024-04-12 21:53:28 -07:00
FreeScout
0dbdf401eb Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2024-04-12 11:20:10 -07:00
FreeScout
26756cc687 Add vendor files to dist 2024-04-11 23:17:54 -07:00
FreeScout
171a4e3b48 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2024-04-11 23:17:21 -07:00
FreeScout
ad76e2d3ce Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2024-04-09 03:19:17 -07:00
FreeScout
c15278d3c6 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2024-04-04 22:21:07 -07:00
FreeScout
2c39ba9d9e Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2024-03-29 07:36:35 -07:00
FreeScout
70cc044e57 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2024-03-29 06:36:58 -07:00
FreeScout
67de1109fe Add vendor files to dist 2024-03-22 00:11:37 -07:00
FreeScout
3489567cde Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2024-03-22 00:11:04 -07:00
FreeScout
e88bec86fb Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2024-03-18 00:25:56 -07:00
FreeScout
f6a4581dad Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2024-03-08 06:49:51 -08:00
FreeScout
36f146a71d Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2024-03-08 01:17:16 -08:00
FreeScout
d8a582aaa5 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2024-03-08 00:23:41 -08:00
FreeScout
33639a8955 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2024-03-08 00:09:52 -08:00
FreeScout
49af472617 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2024-02-23 06:52:13 -08:00
FreeScout
079df0d6a6 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2024-02-23 03:26:42 -08:00
FreeScout
e1ff8fb520 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2024-02-01 17:35:42 -08:00
FreeScout
a78f6f5ce3 Add vendor files to dist 2024-01-23 02:01:04 -08:00
FreeScout
2528727d81 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2024-01-23 02:00:40 -08:00
FreeScout
9b9aae4c0e Add vendor files to dist 2024-01-19 23:40:40 -08:00
FreeScout
263569b163 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2024-01-19 23:40:11 -08:00
FreeScout
e5ce253daf Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2024-01-06 04:08:07 -08:00
FreeScout
885001ec97 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2024-01-05 20:47:49 -08:00
FreeScout
7d035f5604 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2024-01-05 08:20:36 -08:00
FreeScout
85954ab7cc Add vendor files to dist 2023-12-26 21:49:22 -08:00
FreeScout
822b2f4ae7 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2023-12-26 21:48:38 -08:00
FreeScout
11fbaa6be8 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2023-12-19 21:59:34 -08:00
FreeScout
1a53871517 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2023-12-14 23:58:28 -08:00
FreeScout
3083738d00 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2023-12-08 02:45:34 -08:00
FreeScout
ea8b7507e4 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2023-12-07 23:35:26 -08:00
FreeScout
606dcf17c9 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2023-12-01 21:20:17 -08:00
FreeScout
c2d599b546 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2023-11-17 21:20:09 -08:00
FreeScout
4c9f247cf6 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2023-11-06 23:50:12 -08:00
FreeScout
c28b663f56 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2023-11-03 23:48:43 -07:00
FreeScout
45a7f9ae65 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2023-10-27 01:22:55 -07:00
FreeScout
d380d5dd0e Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2023-10-22 23:41:30 -07:00
FreeScout
70f11046f1 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2023-10-12 21:54:05 -07:00
FreeScout
33723056ec Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2023-10-08 11:11:13 -07:00
FreeScout
b3f2cddd2d Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2023-10-07 22:02:17 -07:00
FreeScout
fa6bc246de Add vendor files to dist 2023-10-04 22:20:25 -07:00
FreeScout
c9d5f9f7fa Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2023-10-04 22:18:40 -07:00
FreeScout
fbf2f1f063 Add vendor files to dist 2023-09-23 03:18:04 -07:00
FreeScout
66c1ca83d9 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2023-09-23 03:10:53 -07:00
FreeScout
42423bdf61 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2023-09-15 07:52:40 -07:00
FreeScout
dc3e56d44b Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2023-09-15 07:50:28 -07:00
FreeScout
9b5bf06a29 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2023-09-11 09:25:25 -07:00
FreeScout
2de52008a2 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2023-09-08 10:32:38 -07:00
FreeScout
2abe265046 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2023-09-08 04:37:02 -07:00
FreeScout
9be2c1df5a Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2023-09-01 03:11:57 -07:00
FreeScout
e75dcaf282 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2023-08-25 21:58:56 -07:00
FreeScout
30b481597b Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2023-08-20 23:29:39 -07:00
FreeScout
b11ffe9afa Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2023-08-20 22:33:03 -07:00
FreeScout
561f1deb07 Add vendor files to dist 2023-08-18 00:04:44 -07:00
FreeScout
584d84475a Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2023-08-18 00:02:31 -07:00
FreeScout
40fc845461 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2023-08-11 22:03:54 -07:00
FreeScout
624d84be41 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2023-08-05 23:10:33 -07:00
FreeScout
663908d17e Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2023-08-05 11:07:03 -07:00
FreeScout
3570c48420 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2023-08-03 23:22:23 -07:00
FreeScout
cf2f488aaf Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2023-07-17 01:40:15 -07:00
FreeScout
fdea5e302f Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2023-07-14 06:40:55 -07:00
FreeScout
072c3f8be9 Add vendor files to dist 2023-07-07 00:28:42 -07:00
FreeScout
37b158e99b Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2023-07-07 00:26:34 -07:00
FreeScout
c43e41c076 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2023-06-30 20:37:11 -07:00
FreeScout
ff36b2fef1 Add vendor files to dist 2023-06-30 00:40:52 -07:00
FreeScout
b27997db2c Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2023-06-30 00:39:35 -07:00
FreeScout
24dc14c44a Add vendor files to dist 2023-06-22 00:14:37 -07:00
FreeScout
1e291d4180 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2023-06-22 00:11:31 -07:00
FreeScout
b6b1292589 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2023-06-05 10:32:38 -07:00
FreeScout
d3aa94a922 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2023-06-03 02:33:01 -07:00
FreeScout
ee2269fdf1 Add vendor files to dist 2023-05-28 00:09:31 -07:00
FreeScout
adb1e309e3 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2023-05-28 00:07:57 -07:00
FreeScout
84314598d2 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2023-05-14 10:13:00 -07:00
FreeScout
a54b6a4195 Add vendor files to dist 2023-05-09 22:29:56 -07:00
FreeScout
14e03bf903 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2023-05-09 22:27:17 -07:00
FreeScout
550ca6f7dd Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2023-05-05 21:57:58 -07:00
FreeScout
2fe0f518be Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2023-05-02 01:35:30 -07:00
FreeScout
309b832f6c Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2023-04-23 07:52:10 -07:00
FreeScout
67e73fcbc3 Add vendor files to dist 2023-04-20 22:52:00 -07:00
FreeScout
e2f51b074e Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2023-04-20 22:50:44 -07:00
FreeScout
a3fa817a37 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2023-04-12 06:23:47 -07:00
FreeScout
71301ad1fe Add vendor files to dist 2023-04-04 03:07:24 -07:00
FreeScout
ae67a1375c Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2023-04-04 03:03:03 -07:00
FreeScout
788a793292 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2023-03-17 22:01:57 -07:00
FreeScout
8f809a53d9 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2023-03-16 23:53:32 -07:00
FreeScout
8c0afd34c1 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2023-03-09 00:25:23 -08:00
FreeScout
bde0b18824 Add vendor files to dist 2023-03-03 22:06:52 -08:00
FreeScout
44084b4f1d Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2023-03-03 22:05:26 -08:00
FreeScout
7b5572f5de Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2023-02-26 23:28:39 -08:00
FreeScout
996758f6d1 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2023-02-26 23:24:18 -08:00
FreeScout
313cd61975 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2023-02-26 22:28:05 -08:00
FreeScout
48736ea1d0 Add vendor files to dist 2023-02-25 21:14:43 -08:00
FreeScout
4ace088465 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2023-02-25 21:10:58 -08:00
FreeScout
2a52506a2c Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2023-02-19 23:43:35 -08:00
FreeScout
8efe05e524 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2023-02-14 01:03:14 -08:00
FreeScout
e6ae2e6f43 Add vendor files to dist 2023-02-13 23:02:02 -08:00
FreeScout
69bb79ebe8 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2023-02-13 22:59:48 -08:00
FreeScout
961cadb566 Add vendor files to dist 2023-02-09 22:28:11 -08:00
FreeScout
c65f1b9295 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2023-02-09 22:26:03 -08:00
FreeScout
6102bda402 Add vendor files to dist 2023-02-03 00:02:49 -08:00
FreeScout
a3bbc66718 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2023-02-03 00:01:05 -08:00
FreeScout
709c65563b Add vendor files to dist 2023-02-01 00:26:07 -08:00
FreeScout
f5f88f01a7 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2023-02-01 00:23:40 -08:00
FreeScout
fe03177a80 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2023-01-30 00:44:13 -08:00
FreeScout
b0ffdfb268 Add vendor files to dist 2023-01-26 04:31:52 -08:00
FreeScout
1a75b85e9a Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2023-01-26 04:29:46 -08:00
FreeScout
5ca4f39da4 Add vendor files to dist 2023-01-25 21:52:59 -08:00
FreeScout
475561cbf5 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2023-01-25 21:51:46 -08:00
FreeScout
1a52f6e7c0 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2023-01-25 21:29:27 -08:00
FreeScout
706e3fea74 Add vendor files to dist 2023-01-19 05:32:05 -08:00
FreeScout
b504bf0ecd Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2023-01-19 05:28:54 -08:00
FreeScout
6ab04ba685 Add vendor files to dist 2023-01-18 03:37:09 -08:00
FreeScout
57f768e8ef Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2023-01-18 03:34:13 -08:00
FreeScout
6fba4d334b Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2023-01-13 21:47:46 -08:00
FreeScout
609400b98f Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2023-01-11 23:07:44 -08:00
FreeScout
4f52aed496 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2023-01-10 00:36:52 -08:00
FreeScout
8a4649ceae Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2023-01-07 22:00:27 -08:00
FreeScout
15f1534197 Add vendor files to dist 2023-01-02 22:47:05 -08:00
FreeScout
a04537d4ef Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2023-01-02 22:45:51 -08:00
FreeScout
121953dc2e Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2022-12-25 22:22:52 -08:00
FreeScout
4e027c715f Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2022-12-21 03:15:07 -08:00
FreeScout
216ca83c22 Add vendor files to dist 2022-12-20 03:22:40 -08:00
FreeScout
256fefac59 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2022-12-20 03:20:15 -08:00
FreeScout
b39cbe7402 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2022-12-19 02:31:16 -08:00
FreeScout
aa7ff00380 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2022-12-18 21:52:57 -08:00
FreeScout
4894f115e0 Add vendor files to dist 2022-12-14 23:19:43 -08:00
FreeScout
f3f77c9ab5 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2022-12-14 23:18:32 -08:00
FreeScout
47d988aa97 Add vendor files to dist 2022-12-12 23:22:21 -08:00
FreeScout
9ee76235fa Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2022-12-12 23:20:18 -08:00
FreeScout
2f79060158 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2022-12-09 21:52:14 -08:00
FreeScout
1d57be2fa0 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2022-12-07 06:04:53 -08:00
FreeScout
440177eaa5 Add vendor files to dist 2022-11-27 05:51:52 -08:00
FreeScout
ce09e3e287 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2022-11-27 05:48:58 -08:00
FreeScout
7813210078 Add vendor files to dist 2022-11-16 23:30:17 -08:00
FreeScout
c51ee20010 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2022-11-16 23:27:22 -08:00
FreeScout
481970fd65 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2022-11-16 08:56:07 -08:00
FreeScout
a7489e8679 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2022-11-16 04:04:38 -08:00
FreeScout
9570399ab9 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2022-11-09 02:18:31 -08:00
FreeScout
e2a5e5c021 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2022-10-25 00:27:33 -07:00
FreeScout
25c43247cf Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2022-10-13 04:27:46 -07:00
FreeScout
098b830a08 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2022-09-28 22:17:00 -07:00
FreeScout
e93bf6a121 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2022-09-27 07:06:39 -07:00
FreeScout
ae6fa8e7b2 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2022-09-22 05:21:21 -07:00
FreeScout
168c61e4b0 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2022-09-21 04:18:20 -07:00
FreeScout
350b09a77c Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2022-09-17 02:42:27 -07:00
FreeScout
cc8f94fcff Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2022-09-14 04:19:42 -07:00
FreeScout
b850065299 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2022-09-09 00:40:31 -07:00
FreeScout
9e71085823 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2022-09-02 22:25:19 -07:00
FreeScout
87dfcb8ed0 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2022-08-01 04:41:01 -07:00
FreeScout
4c4db724a5 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2022-07-06 10:57:59 -07:00
FreeScout
fe4c69e3a9 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2022-06-20 00:13:22 -07:00
FreeScout
abfbf9959a Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2022-06-14 23:43:31 -07:00
FreeScout
f5bf5afe14 Add vendor files to dist 2022-06-06 22:44:49 -07:00
FreeScout
4f65bbc723 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2022-06-06 22:43:19 -07:00
FreeScout
403a160917 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2022-05-24 02:43:01 -07:00
FreeScout
c1a2b819ec Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2022-05-16 21:44:37 -07:00
FreeScout
826418d5e4 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2022-05-13 00:08:55 -07:00
FreeScout
32a6c46e8a Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2022-05-01 04:51:25 -07:00
FreeScout
415b20020a Add vendor files to dist 2022-04-14 06:13:12 -07:00
FreeScout
29b36472c9 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2022-04-14 06:10:41 -07:00
FreeScout
147926bcf1 Add vendor files to dist 2022-04-06 00:03:46 -07:00
FreeScout
3c904fc048 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2022-04-06 00:00:26 -07:00
FreeScout
a64cfa6307 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2022-04-05 23:52:57 -07:00
FreeScout
8053591031 Add vendor files to dist 2022-03-29 06:13:20 -07:00
FreeScout
3d2fcd020d Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2022-03-29 06:11:56 -07:00
FreeScout
6014509dd2 Add vendor files to dist 2022-03-13 01:03:57 -08:00
FreeScout
4e856ea783 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2022-03-13 01:01:34 -08:00
FreeScout
dcb7e7715f Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2022-03-04 09:22:48 -08:00
FreeScout
8e9bcc6040 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2022-02-22 08:49:20 -08:00
FreeScout
c56b9a0573 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2022-02-17 21:51:11 -08:00
FreeScout
1f6a95c4a7 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2022-02-15 05:35:30 -08:00
FreeScout
595eaa7a20 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2022-02-07 02:30:35 -08:00
FreeScout
7c663cacf8 Add vendor files to dist 2022-02-04 23:53:37 -08:00
FreeScout
1bedf8394d Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2022-02-04 23:49:49 -08:00
FreeScout
cbddefcda2 Add vendor files to dist 2022-02-04 00:26:30 -08:00
FreeScout
a06d2f4c81 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2022-02-04 00:24:16 -08:00
FreeScout
3f1ec34dea Add vendor files to dist 2022-02-03 23:40:05 -08:00
FreeScout
ddc4f9d452 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2022-02-03 23:36:54 -08:00
FreeScout
9cca472d29 Add vendor files to dist 2022-02-03 04:03:34 -08:00
FreeScout
44390a6280 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2022-02-03 03:57:32 -08:00
FreeScout
3d477f6296 Add vendor files to dist 2022-02-02 22:49:30 -08:00
FreeScout
b0469ed5bc Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2022-02-02 22:48:17 -08:00
FreeScout
a5d03df940 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2022-02-02 22:26:06 -08:00
FreeScout
fb1ac61d64 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2022-01-24 01:14:00 -08:00
FreeScout
323e9d7a20 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2022-01-23 22:44:39 -08:00
FreeScout
1afb66ce0b Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2022-01-22 01:24:55 -08:00
FreeScout
f4924c3140 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2022-01-05 02:36:04 -08:00
FreeScout
17a157eb60 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2021-12-31 04:16:16 -08:00
FreeScout
94af31c686 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2021-12-25 22:02:18 -08:00
FreeScout
f9b517c849 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2021-12-13 06:41:47 -08:00
FreeScout
97fb5678bc Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2021-12-03 04:58:12 -08:00
FreeScout
62ea562f26 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2021-11-30 04:12:54 -08:00
FreeScout
79db2920ca Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2021-11-14 23:13:11 -08:00
FreeScout
5eeed269b6 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2021-10-21 05:54:00 -07:00
FreeScout
c4a4f33633 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2021-10-20 07:45:16 -07:00
FreeScout
170c282f3e Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2021-10-14 03:26:29 -07:00
FreeScout
2a6c5faa79 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2021-09-23 03:06:15 -07:00
FreeScout
1816aa2761 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2021-08-25 05:53:54 -07:00
FreeScout
7828df20fc Add vendor files to dist 2021-08-10 22:19:57 -07:00
FreeScout
a72f6b964f Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2021-08-10 22:18:39 -07:00
FreeScout
7f6bda6c76 Add vendor files to dist 2021-08-03 07:47:45 -07:00
FreeScout
b3b5063b50 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2021-08-03 07:45:49 -07:00
FreeScout
3ef5c28bac Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2021-07-18 01:37:49 -07:00
FreeScout
2369c9b3be v1.7.12 2021-07-10 22:37:56 -07:00
FreeScout
8ee0699b3e v1.7.12 2021-07-10 22:35:58 -07:00
FreeScout
cc58b6739b Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2021-06-23 07:32:51 -07:00
FreeScout
deaec751b0 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2021-06-23 07:31:32 -07:00
FreeScout
2a077ecf81 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2021-06-16 05:06:41 -07:00
FreeScout
4018604028 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2021-05-21 07:55:19 -07:00
FreeScout
078e098b28 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2021-05-21 05:55:25 -07:00
FreeScout
dddf4d12df Add vendor files to dist 2021-05-18 23:27:40 -07:00
FreeScout
96033cbc78 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2021-05-18 23:26:08 -07:00
FreeScout
3e5900b1e0 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2021-05-14 11:20:54 -07:00
FreeScout
ce02ba86db Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2021-05-11 02:46:23 -07:00
FreeScout
abc01538f9 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2021-04-23 00:13:23 -07:00
FreeScout
728959332b Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2021-04-23 00:11:58 -07:00
FreeScout
d58a0981c4 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2021-04-22 22:47:21 -07:00
FreeScout
955681886f Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2021-04-15 05:40:55 -07:00
FreeScout
a5db2a49a8 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2021-04-15 00:59:45 -07:00
FreeScout
208bdb28fe Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2021-04-14 00:10:38 -07:00
FreeScout
91a0cecffa Add vendor files to dist 2021-03-31 00:51:49 -07:00
FreeScout
a59204cd99 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2021-03-31 00:37:55 -07:00
FreeScout
f3aa63aa13 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2021-03-17 01:33:23 -07:00
FreeScout
920690e504 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2021-03-13 22:21:03 -08:00
FreeScout
f88f805f28 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2021-03-07 09:07:55 -08:00
FreeScout
bfe4ec2818 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2021-03-07 09:01:40 -08:00
FreeScout
b029070d94 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2021-03-03 03:41:42 -08:00
FreeScout
b28330ed56 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2021-02-25 07:05:44 -08:00
FreeScout
cd2b36e5c7 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2021-02-12 21:18:56 -08:00
FreeScout
03ff3f7257 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2021-02-10 04:02:01 -08:00
FreeScout
4d6b740f30 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2021-01-16 04:50:17 -08:00
FreeScout
90180b890d Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2020-12-31 00:32:56 -08:00
FreeScout
b7a2312994 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2020-12-23 23:42:30 -08:00
FreeScout
3598d5efdf Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2020-12-16 23:40:59 -08:00
FreeScout
62bc3dd614 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2020-12-03 03:18:52 -08:00
FreeScout
490f850834 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2020-11-26 01:47:12 -08:00
FreeScout
aebf33c2f0 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2020-11-07 04:09:16 -08:00
FreeScout
76ab984e0b Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2020-10-31 00:07:11 -07:00
FreeScout
b3ee050eb3 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2020-10-27 23:49:58 -07:00
FreeScout
8a5fa4f158 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2020-10-27 02:39:06 -07:00
FreeScout
e982a8a799 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2020-10-26 02:18:10 -07:00
FreeScout
fbf88be324 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2020-10-06 01:46:01 -07:00
FreeScout
ac3255efb5 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2020-10-02 00:08:30 -07:00
FreeScout
1d2e0fed0e Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2020-09-22 02:01:52 -07:00
FreeScout
4b44f3c718 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2020-09-16 10:32:29 -07:00
FreeScout
1c687f84b7 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2020-09-11 04:42:33 -07:00
FreeScout
f30adeb613 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2020-09-08 23:07:34 -07:00
FreeScout
ce029693cf Add vendor files to dist 2020-08-24 02:56:40 -07:00
FreeScout
497af1fe00 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2020-08-24 02:54:46 -07:00
FreeScout
ed82534030 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2020-07-26 04:16:38 -07:00
FreeScout
83f14010b1 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2020-07-23 00:31:01 -07:00
FreeScout
badcdf78c1 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2020-07-17 07:20:59 -07:00
FreeScout
4262a1b639 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2020-06-15 21:27:57 -07:00
FreeScout
ef033e477c Add vendor files to dist 2020-05-28 03:35:33 -07:00
FreeScout
35b2cbc490 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2020-05-28 03:28:03 -07:00
FreeScout
8dd630b43b Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2020-05-16 03:45:30 -07:00
FreeScout
c46e0d9811 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2020-05-08 20:48:25 -07:00
FreeScout
b4229070e6 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2020-04-26 03:11:24 -07:00
FreeScout
341f4c006f Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2020-03-29 02:10:41 -07:00
FreeScout
b7a3719815 Add vendor files to dist 2020-03-12 23:05:28 -07:00
FreeScout
2b7a5c31d4 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2020-03-12 23:03:14 -07:00
FreeScout
d4c69004cc Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2020-03-12 01:57:14 -07:00
FreeScout
3bdee559e6 Add vendor files to dist 2020-03-07 20:08:44 -08:00
FreeScout
de67e11704 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2020-03-07 20:07:04 -08:00
FreeScout
9583a2a9e9 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2020-03-05 02:55:59 -08:00
FreeScout
ca1b010529 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2020-02-18 00:52:07 -08:00
FreeScout
fae1253df6 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2020-02-15 22:01:55 -08:00
FreeScout
695ca73817 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2020-02-09 00:12:04 -08:00
FreeScout
918e31483b Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2020-02-02 06:37:30 -08:00
FreeScout
74a56142f6 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2020-01-28 22:42:29 -08:00
FreeScout
7be3266543 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2020-01-25 05:35:32 -08:00
FreeScout
d8f36cd716 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2020-01-25 05:30:36 -08:00
FreeScout
b29db2c76c Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2020-01-24 05:47:48 -08:00
FreeScout
8842a097ab Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2020-01-19 08:50:08 -08:00
FreeScout
4b48841caa Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2020-01-17 04:38:40 -08:00
FreeScout
6a85c9588f Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2020-01-14 00:52:58 -08:00
FreeScout
a0d251eb9a Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2020-01-07 02:12:00 -08:00
FreeScout
2df4c024f4 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2019-12-28 04:00:17 -08:00
FreeScout
a2efc65226 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2019-12-22 01:38:20 -08:00
FreeScout
19edef364f Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2019-12-21 05:02:02 -08:00
FreeScout
a3a1e0d621 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2019-12-18 09:58:42 -08:00
FreeScout
ebd34d0d0a Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2019-12-16 23:44:21 -08:00
FreeScout
c822777ed3 Add vendor files to dist 2019-12-09 05:50:48 -08:00
FreeScout
29ebb5ad72 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2019-12-09 05:49:42 -08:00
FreeScout
b5dd14758b Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2019-12-08 09:01:36 -08:00
FreeScout
5e928270bb Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2019-11-25 09:24:25 -08:00
FreeScout
3e732ddbe6 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2019-11-17 05:20:02 -08:00
FreeScout
fda982c7d1 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2019-11-08 23:23:22 -08:00
FreeScout
e78d935a54 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2019-11-01 00:35:04 -07:00
FreeScout
47608f26d5 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2019-10-14 00:01:27 -07:00
FreeScout
53102be531 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2019-10-05 23:18:00 -07:00
FreeScout
2c4e415a66 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2019-09-06 05:23:52 -07:00
FreeScout
5397175314 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2019-08-07 11:34:44 -07:00
FreeScout
9d697647c3 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2019-08-03 04:56:49 -07:00
FreeScout
2b9e94b596 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2019-08-03 04:39:40 -07:00
FreeScout
7e590b2179 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2019-07-30 06:51:57 -07:00
FreeScout
53a97f07b8 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2019-07-27 09:07:20 -07:00
FreeScout
533a482d2c Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2019-07-24 22:14:01 -07:00
FreeScout
0888a08c12 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2019-07-24 05:46:07 -07:00
FreeScout
ba12b17e94 Add vendor files to dist 2019-07-22 07:01:56 -07:00
FreeScout
911d18ed31 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2019-07-22 06:59:51 -07:00
FreeScout
9e2e10f7fb Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2019-07-13 22:12:37 -07:00
FreeScout
a7fd5288a1 Add vendor files to dist 2019-07-09 02:30:13 -07:00
FreeScout
3c0c61cb97 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2019-07-09 02:26:43 -07:00
FreeScout
8a92c6c44e Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2019-07-05 03:20:40 -07:00
FreeScout
61fdf8150b Add vendor files to dist 2019-07-04 07:35:30 -07:00
FreeScout
09ffb53bed Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2019-07-04 07:32:57 -07:00
FreeScout
5f048f67bb Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2019-07-04 07:03:43 -07:00
FreeScout
d6aad6f97e Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2019-07-04 06:53:39 -07:00
FreeScout
57ae95616f Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2019-07-01 09:30:28 -07:00
FreeScout
93810fa81a Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2019-07-01 09:27:21 -07:00
FreeScout
1c8c1a0ba9 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2019-06-27 06:12:44 -07:00
FreeScout
b9f3d8736e Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2019-06-27 01:57:34 -07:00
FreeScout
b87892dc9b Add vendor files to dist 2019-06-24 22:00:06 -07:00
FreeScout
5a640831e2 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2019-06-24 21:57:49 -07:00
FreeScout
48e16a54d3 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2019-06-19 23:20:19 -07:00
FreeScout
fee5e94239 Add vendor files to dist 2019-06-16 04:17:41 -07:00
FreeScout
57d89b371d Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2019-06-16 04:15:47 -07:00
FreeScout
bb7c6db8fb Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2019-06-05 20:39:46 -07:00
FreeScout
34e3c8d6d9 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2019-04-25 22:05:36 -07:00
FreeScout
0ec8a2a942 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2019-01-01 23:01:47 -08:00
FreeScout
cc78c0e560 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2018-12-28 22:32:17 -08:00
FreeScout
b91e1924e0 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2018-12-21 21:02:22 -08:00
FreeScout
49cced03c2 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2018-12-15 20:55:50 -08:00
FreeScout
574d6bbf8c Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2018-12-12 21:14:10 -08:00
FreeScout
53fc5969db Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2018-12-12 20:53:50 -08:00
FreeScout
8713e19d78 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2018-12-12 06:39:48 -08:00
FreeScout
ab707bd365 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2018-12-12 06:07:40 -08:00
FreeScout
84006b6923 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2018-12-08 05:05:51 -08:00
FreeScout
c73ff62369 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2018-12-05 00:26:53 -08:00
FreeScout
e08476b3f8 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2018-12-03 05:06:28 -08:00
FreeScout
bcdf977753 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2018-12-03 05:04:52 -08:00
FreeScout
700fa91850 Add vendor files to dist 2018-12-01 00:36:56 -08:00
FreeScout
6ba2f882e7 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2018-12-01 00:35:46 -08:00
FreeScout
332b95965c Add vendor files to dist 2018-11-24 02:27:05 -08:00
FreeScout
463a9e059d Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2018-11-24 02:25:57 -08:00
FreeScout
99e6711b44 Add vendor files to dist 2018-11-17 06:06:07 -08:00
FreeScout
237c2e2c32 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2018-11-17 06:04:21 -08:00
FreeScout
ec2a3d116f Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2018-11-16 04:51:07 -08:00
FreeScout
c62a87af43 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2018-11-16 02:25:40 -08:00
FreeScout
fa902b3dec Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2018-11-16 01:41:43 -08:00
FreeScout
913a521c77 Disable phpunit testing as dist vendor is cleared by removing unneeded files 2018-11-16 01:15:26 -08:00
FreeScout
fbe7c28b26 Add vendor files to dist 2018-11-16 01:03:16 -08:00
FreeScout
10e9172d9d Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2018-11-16 01:01:31 -08:00
FreeScout
46a36fe444 Add vendor files to dist 2018-11-15 23:16:39 -08:00
FreeScout
65eb9bda98 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2018-11-15 23:15:43 -08:00
FreeScout
b323086c09 Add vendor files to dist 2018-11-13 22:08:27 -08:00
FreeScout
b09d957b12 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2018-11-13 22:06:15 -08:00
FreeScout
06cdae9a87 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2018-11-13 09:32:29 -08:00
FreeScout
adab9fc7a8 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2018-11-12 06:04:51 -08:00
FreeScout
5b94ae8aa4 Add vendor files to dist 2018-11-12 05:42:30 -08:00
FreeScout
116c826262 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2018-11-12 05:40:12 -08:00
FreeScout
6ae200368b Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2018-11-10 02:02:07 -08:00
FreeScout
184b7f6ddd Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2018-11-10 00:56:35 -08:00
FreeScout
a4d3bb8791 Add git info 2018-11-09 22:41:59 -08:00
FreeScout
28e2d659db Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2018-11-09 22:41:47 -08:00
FreeScout
3714a59ede Add git info 2018-11-09 22:30:48 -08:00
FreeScout
6fcba5e6d7 Add vendor files to dist 2018-11-09 22:30:47 -08:00
FreeScout
d21d5d8b35 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2018-11-09 22:29:43 -08:00
FreeScout
f591a1a629 Add git info 2018-11-07 05:45:22 -08:00
FreeScout
f44392e109 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2018-11-07 05:44:30 -08:00
FreeScout
d41777b031 Add git info 2018-11-07 03:24:39 -08:00
FreeScout
18e4afce98 Add vendor files to dist 2018-11-07 03:24:38 -08:00
FreeScout
196a7a3de2 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2018-11-07 03:24:06 -08:00
FreeScout
0336e46643 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2018-11-07 02:36:18 -08:00
FreeScout
e43e371ac4 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2018-11-07 02:27:23 -08:00
FreeScout
0ae9757c8c Add git info 2018-11-04 00:19:43 -07:00
FreeScout
669b68f107 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2018-11-04 00:18:21 -07:00
FreeScout
31dec60fcf Add git info 2018-11-01 04:33:18 -07:00
FreeScout
d21dca0d57 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2018-11-01 04:32:08 -07:00
FreeScout
40c1317fb9 Add git info 2018-10-31 00:18:53 -07:00
FreeScout
ccfc4e41e6 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2018-10-31 00:18:45 -07:00
FreeScout
d2978ffc93 Add git info 2018-10-30 23:21:16 -07:00
FreeScout
daf4dc33c1 Add vendor files to dist 2018-10-30 23:21:16 -07:00
FreeScout
cb655167d0 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2018-10-30 23:20:23 -07:00
FreeScout
ffdb7b770c Add git info 2018-10-24 10:30:12 -07:00
FreeScout
5d81dee3b0 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2018-10-24 10:28:43 -07:00
FreeScout
7a105da1b6 Add git info 2018-10-24 07:22:07 -07:00
FreeScout
47637c7bf1 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2018-10-24 07:21:32 -07:00
FreeScout
5ecd684b01 Add git info 2018-10-24 03:51:18 -07:00
FreeScout
0fe4f07094 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2018-10-24 03:50:48 -07:00
FreeScout
720a602adf Add git info 2018-10-24 01:32:55 -07:00
FreeScout
4f6bcbe787 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2018-10-24 01:32:09 -07:00
FreeScout
9f7abd708a Add git info 2018-10-23 05:56:58 -07:00
FreeScout
7fd1b7227d Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2018-10-23 05:56:32 -07:00
FreeScout
ca66a9752e Add git info 2018-10-22 06:51:25 -07:00
FreeScout
1cb78809b7 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2018-10-22 06:51:08 -07:00
FreeScout
1e9fb5e7c0 Add git info 2018-10-22 06:04:51 -07:00
FreeScout
c296a1e2dd Add vendor files to dist 2018-10-22 06:04:49 -07:00
FreeScout
20c15d3dd2 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2018-10-22 06:03:22 -07:00
FreeScout
2ee645a661 Add git info 2018-10-20 00:40:51 -07:00
FreeScout
2090a7e1e2 Add vendor files to dist 2018-10-20 00:40:46 -07:00
FreeScout
c2c9566a4a Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2018-10-20 00:38:44 -07:00
FreeScout
42cc6d80f8 Add git info 2018-10-14 23:13:43 -07:00
FreeScout
bce3a7dce9 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2018-10-14 23:12:42 -07:00
FreeScout
8fc19930ac Add git info 2018-10-12 00:24:42 -07:00
FreeScout
f5badbed06 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2018-10-12 00:24:16 -07:00
FreeScout
7a58cc69b7 Add git info 2018-09-30 23:21:51 -07:00
FreeScout
7887a68e5a Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2018-09-30 23:21:14 -07:00
FreeScout
6ebbfbf27a Add git info 2018-09-30 10:40:37 -07:00
FreeScout
9fb0750918 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2018-09-30 10:40:07 -07:00
FreeScout
28ee15ed41 Add git info 2018-09-26 23:19:15 -07:00
FreeScout
79c4807674 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2018-09-26 23:18:53 -07:00
FreeScout
7573699cee Add git info 2018-09-26 10:36:44 -07:00
FreeScout
ceeaff60ce Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2018-09-26 10:35:47 -07:00
FreeScout
6262bff5f9 Remove .gitbranch 2018-09-26 05:50:50 -07:00
FreeScout
6604710da5 Add git info 2018-09-26 03:28:05 -07:00
FreeScout
84344abf47 Add vendor files to dist 2018-09-26 03:28:05 -07:00
FreeScout
3f275ce126 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2018-09-26 03:19:15 -07:00
FreeScout
00c2456286 Add vendor files to dist 2018-09-25 07:08:30 -07:00
FreeScout
444f4382d0 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2018-09-25 07:07:16 -07:00
FreeScout
b402bf723e Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2018-09-25 03:13:31 -07:00
FreeScout
ff7d608a57 Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2018-09-24 22:57:57 -07:00
FreeScout
1578a124f8 Add vendor to dist 2018-09-24 07:56:11 -07:00
FreeScout
8b416f31dc Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2018-09-24 07:55:01 -07:00
FreeScout
d573e7a17b Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2018-09-23 10:41:33 -07:00
FreeScout
fb5af0884f Merge branch 'master' of github.com:freescout-helpdesk/freescout into dist 2018-09-23 01:59:51 -07:00
FreeScout
c976851afc Merge branch 'master' into dist 2018-09-22 22:06:15 -07:00
FreeScout
97600004c5 Remove Travis composer install from dist 2018-09-21 02:34:19 -07:00
FreeScout
780632229a Merge branch 'master' into dist 2018-09-21 02:33:29 -07:00
FreeScout
8851882824 Travis composer install 2018-09-21 02:22:58 -07:00
FreeScout
87524623c2 Merge branch 'master' into dist 2018-09-21 02:20:15 -07:00
FreeScout
52c763849e Commit vendor 2018-09-21 01:54:30 -07:00
4180 changed files with 471023 additions and 7 deletions

1
.gitcommit Normal file
View File

@@ -0,0 +1 @@
28e2d659db742540723b7d6cea7f0261cfe34bf1

4
.gitignore vendored
View File

@@ -5,8 +5,8 @@
# We are committing /vendor directory to make installation process super easy, even on a shared hosting:
# - https://www.codeenigma.com/build/blog/do-you-really-need-composer-production
# - https://getcomposer.org/doc/faqs/should-i-commit-the-dependencies-in-my-vendor-directory.md
#/vendor/**/.git
/vendor
/vendor/**/.git
#/vendor
/.idea
/.vagrant
Homestead.json

View File

@@ -6,12 +6,10 @@ php:
- 7.4
- 8.0
install:
- composer install
before_script:
- cp .env.travis .env
- mysql -e 'create database homestead_test;'
script:
- vendor/bin/phpunit
# phpunit testing is disabled as dist vendor is cleared by removing unneeded files
#script:
# - vendor/bin/phpunit

View File

@@ -0,0 +1,29 @@
# Use Docker environment
sudo: false
# Setup build matrix
language: php
php:
- 5.4
- 5.5
- 5.6
- 7.0
- hhvm
env:
matrix:
- PREFER_LOWEST="--prefer-lowest"
- PREFER_LOWEST=""
# Dependencies
install:
- composer self-update
- travis_retry composer update --no-interaction --prefer-source --dev $PREFER_LOWEST
script: phpunit
# Cache dependencies
cache:
directories:
- vendor
- $HOME/.composer/cache

View File

@@ -0,0 +1,16 @@
<?php
return [
// The alias Underscore will be mapped to
'alias' => 'Underscore',
// Various aliases for methods, you can specify your own
'aliases' => [
'contains' => 'find',
'getLast' => 'last',
'select' => 'filter',
'sortBy' => 'sort',
],
];

View File

@@ -0,0 +1,27 @@
<?php
/**
* Shortcut alias to creating an Underscore object
*
* @param mixed $type A scalar type to wrap
*
* @return \Underscore\Underscore
*/
if ( ! function_exists('underscore')) {
function underscore($type) {
return new Underscore\Underscore($type);
}
}
/**
* Shortcut alias for underscore()
*
* @param mixed $type
*
* @return \Underscore\Underscore
*/
if (!function_exists('__')) {
function __($type) {
return underscore($type);
}
}

View File

@@ -0,0 +1,96 @@
<?php
namespace Underscore;
use Closure;
use InvalidArgumentException;
/**
* Dispatches methods and classes to various places.
*/
class Dispatch
{
/**
* The namespace containing the Type classes.
*/
const TYPES = 'Underscore\Types\\';
/**
* An array of PHP types and what classes they map to.
*
* @type array
*/
protected static $classmap = [
'array' => 'Arrays',
'double' => 'Number',
'closure' => 'Functions',
'float' => 'Number',
'integer' => 'Number',
'NULL' => 'Strings',
'object' => 'Object',
'real' => 'Number',
'string' => 'Strings',
];
/**
* Compute the right class to call according to something's type.
*
* @param mixed $subject The subject of a class
*
* @return string Its fully qualified corresponding class
*/
public static function toClass($subject)
{
$subjectType = gettype($subject);
if ($subject instanceof Closure) {
$subjectType = 'closure';
}
// Return correct class
if (array_key_exists($subjectType, static::$classmap)) {
return static::TYPES.static::$classmap[$subjectType];
}
throw new InvalidArgumentException('The type '.$subjectType.' is not supported');
}
/**
* Defer a method to native PHP.
*
* @param string $class The class
* @param string $method The method
*
* @return string The correct function to call
*/
public static function toNative($class, $method)
{
// Aliased native function
$native = Method::getNative($method);
if ($native) {
return $native;
}
// Transform class to php function prefix
switch ($class) {
case static::TYPES.'Arrays':
$prefix = 'array_';
break;
case static::TYPES.'Strings':
$prefix = 'str_';
break;
}
// If no function prefix found, return false
if (!isset($prefix)) {
return false;
}
// Native function
$function = $prefix.$method;
if (function_exists($function)) {
return $function;
}
return false;
}
}

View File

@@ -0,0 +1,178 @@
<?php
namespace Underscore;
/**
* Various helpers relatives to methods.
*/
class Method
{
/**
* A list of methods to automatically defer to PHP.
*
* @type array
*/
public static $defer = [
'trim',
'count',
'round',
'ceil',
'floor',
'substr',
'str_pad' => 'pad',
'ucfirst',
'lcfirst',
'ucwords',
'strtolower',
'strtoupper',
];
/**
* A list of methods where the subject
* isn't to be added to the arguments.
*
* @type array
*/
protected static $subjectless = [
'fill',
];
/**
* A list of methods that are allowed
* to break the chain.
*
* @type array
*/
protected static $breakers = [
'get',
'sum',
'count',
'fromJSON',
'toJSON',
'fromXML',
'fromCSV',
'toCSV',
];
/**
* Unchainable methods.
*
* @type array
*/
protected static $unchainable = [
'Arrays::range',
'Arrays::repeat',
];
/**
* A cache for better findInClasses performances.
*
* @type array
*/
protected static $findCache = [];
////////////////////////////////////////////////////////////////////
////////////////////////////// HELPERS /////////////////////////////
////////////////////////////////////////////////////////////////////
/**
* Get the Methods class from the Type class.
*
* @param string $class The Type class
*
* @return string The Methods class
*/
public static function getMethodsFromType($class)
{
return str_replace('Types', 'Methods', $class.'Methods');
}
/**
* Whether a native method requires a subject or not.
*
* @param string $method The function
*
* @return bool
*/
public static function isSubjectless($method)
{
return in_array($method, static::$subjectless, true);
}
/**
* Whether a method should not be chained.
*
* @param string $class The class
* @param string $method The method
*
* @return bool
*/
public static function isUnchainable($class, $method)
{
$class = str_replace('Underscore\Types\\', null, $class);
return in_array($class.'::'.$method, static::$unchainable, true);
}
/**
* Whether a method is a breaker.
*
* @param string $method The method
*
* @return bool
*/
public static function isBreaker($method)
{
return in_array($method, static::$breakers, true);
}
/**
* Get a method name by its alias.
*
* @param string $method The method
*
* @return string The real method name
*/
public static function getAliasOf($method)
{
return Underscore::option('aliases.'.$method);
}
/**
* Get the native function corresponding to a method.
*
* @param string $method The method to look for
*
* @return string The native function
*/
public static function getNative($method)
{
// If a defered method exist
if (in_array($method, static::$defer, true)) {
$native = array_search($method, static::$defer, true);
return is_int($native) ? $method : $native;
}
return false;
}
/**
* Find a method in the type classes.
*
* @param string $originalClass The class calling the method
* @param string $method The method
*
* @return string The class name
*/
public static function findInClasses($originalClass, $method)
{
$classes = ['Arrays', 'Collection', 'Functions', 'Number', 'Object', 'Strings'];
foreach ($classes as $class) {
if (method_exists('\Underscore\Methods\\'.$class.'Methods', $method)) {
return '\Underscore\Types\\'.$class;
}
}
return $originalClass;
}
}

View File

@@ -0,0 +1,558 @@
<?php
namespace Underscore\Methods;
use Closure;
/**
* Methods to manage arrays.
*/
class ArraysMethods extends CollectionMethods
{
////////////////////////////////////////////////////////////////////
///////////////////////////// GENERATE /////////////////////////////
////////////////////////////////////////////////////////////////////
/**
* Generate an array from a range.
*
* @param int $_base The base number
* @param int $stop The stopping point
* @param int $step How many to increment of
*
* @return array
*/
public static function range($_base, $stop = null, $step = 1)
{
// Dynamic arguments
if (!is_null($stop)) {
$start = $_base;
} else {
$start = 1;
$stop = $_base;
}
return range($start, $stop, $step);
}
/**
* Fill an array with $times times some $data.
*
* @param mixed $data
* @param int $times
*
* @return array
*/
public static function repeat($data, $times)
{
$times = abs($times);
if ($times === 0) {
return [];
}
return array_fill(0, $times, $data);
}
////////////////////////////////////////////////////////////////////
///////////////////////////// ANALYZE //////////////////////////////
////////////////////////////////////////////////////////////////////
/**
* Search for the index of a value in an array.
*
* @param array $array
* @param string $value
*
* @return mixed
*/
public static function search($array, $value)
{
return array_search($value, $array, true);
}
/**
* Check if all items in an array match a truth test.
*
* @param array $array
* @param callable $closure
*
* @return bool
*/
public static function matches($array, Closure $closure)
{
// Reduce the array to only booleans
$array = (array) static::each($array, $closure);
// Check the results
if (count($array) === 0) {
return true;
}
$array = array_search(false, $array, false);
return is_bool($array);
}
/**
* Check if any item in an array matches a truth test.
*
* @param array $array
* @param callable $closure
*
* @return bool
*/
public static function matchesAny($array, Closure $closure)
{
// Reduce the array to only booleans
$array = (array) static::each($array, $closure);
// Check the results
if (count($array) === 0) {
return true;
}
$array = array_search(true, $array, false);
return is_int($array);
}
/**
* Check if an item is in an array.
*/
public static function contains($array, $value)
{
return in_array($value, $array, true);
}
/**
* Returns the average value of an array.
*
* @param array $array The source array
* @param int $decimals The number of decimals to return
*
* @return int The average value
*/
public static function average($array, $decimals = 0)
{
return round((array_sum($array) / count($array)), $decimals);
}
/**
* Get the size of an array.
*/
public static function size($array)
{
return count($array);
}
/**
* Get the max value from an array.
*
* @param array $array
* @param Closure|null $closure
*
* @return mixed
*/
public static function max($array, $closure = null)
{
// If we have a closure, apply it to the array
if ($closure) {
$array = static::each($array, $closure);
}
return max($array);
}
/**
* Get the min value from an array.
*
* @param array $array
* @param Closure|null $closure
*
* @return mixed
*/
public static function min($array, $closure = null)
{
// If we have a closure, apply it to the array
if ($closure) {
$array = static::each($array, $closure);
}
return min($array);
}
////////////////////////////////////////////////////////////////////
//////////////////////////// FETCH FROM ////////////////////////////
////////////////////////////////////////////////////////////////////
/**
* Find the first item in an array that passes the truth test.
*/
public static function find($array, Closure $closure)
{
foreach ($array as $key => $value) {
if ($closure($value, $key)) {
return $value;
}
}
return;
}
/**
* Clean all falsy values from an array.
*/
public static function clean($array)
{
return static::filter($array, function ($value) {
return (bool) $value;
});
}
/**
* Get a random string from an array.
*/
public static function random($array, $take = null)
{
if (!$take) {
return $array[array_rand($array)];
}
shuffle($array);
return static::first($array, $take);
}
/**
* Return an array without all instances of certain values.
*/
public static function without()
{
$arguments = func_get_args();
$array = array_shift($arguments);
// if singular argument and is an array treat this AS the array to run without agains
if (is_array($arguments[0]) && count($arguments) === 1) {
$arguments = $arguments[0];
}
return static::filter($array, function ($value) use ($arguments) {
return !in_array($value, $arguments, true);
});
}
/**
* Return an array with all elements found in both input arrays.
*/
public static function intersection($a, $b)
{
$a = (array) $a;
$b = (array) $b;
return array_values(array_intersect($a, $b));
}
/**
* Return a boolean flag which indicates whether the two input arrays have any common elements.
*/
public static function intersects($a, $b)
{
$a = (array) $a;
$b = (array) $b;
return count(self::intersection($a, $b)) > 0;
}
////////////////////////////////////////////////////////////////////
///////////////////////////// SLICERS //////////////////////////////
////////////////////////////////////////////////////////////////////
/**
* Get the first value from an array.
*/
public static function first($array, $take = null)
{
if (!$take) {
return array_shift($array);
}
return array_splice($array, 0, $take, true);
}
/**
* Get the last value from an array.
*/
public static function last($array, $take = null)
{
if (!$take) {
return array_pop($array);
}
return static::rest($array, -$take);
}
/**
* Get everything but the last $to items.
*/
public static function initial($array, $to = 1)
{
$slice = count($array) - $to;
return static::first($array, $slice);
}
/**
* Get the last elements from index $from.
*/
public static function rest($array, $from = 1)
{
return array_splice($array, $from);
}
////////////////////////////////////////////////////////////////////
///////////////////////////// ACT UPON /////////////////////////////
////////////////////////////////////////////////////////////////////
/**
* Iterate over an array and execute a callback for each loop.
*/
public static function at($array, Closure $closure)
{
foreach ($array as $key => $value) {
$closure($value, $key);
}
return $array;
}
////////////////////////////////////////////////////////////////////
////////////////////////////// ALTER ///////////////////////////////
////////////////////////////////////////////////////////////////////
/**
* Replace a value in an array.
*
* @param array $array The array
* @param string $replace The string to replace
* @param string $with What to replace it with
*
* @return array
*/
public static function replaceValue($array, $replace, $with)
{
return static::each($array, function ($value) use ($replace, $with) {
return str_replace($replace, $with, $value);
});
}
/**
* Replace the keys in an array with another set.
*
* @param array $array The array
* @param array $keys An array of keys matching the array's size
*
* @return array
*/
public static function replaceKeys($array, $keys)
{
$values = array_values($array);
return array_combine($keys, $values);
}
/**
* Iterate over an array and modify the array's value.
*/
public static function each($array, Closure $closure)
{
foreach ($array as $key => $value) {
$array[$key] = $closure($value, $key);
}
return $array;
}
/**
* Shuffle an array.
*/
public static function shuffle($array)
{
shuffle($array);
return $array;
}
/**
* Sort an array by key.
*/
public static function sortKeys($array, $direction = 'ASC')
{
$direction = (strtolower($direction) === 'desc') ? SORT_DESC : SORT_ASC;
if ($direction === SORT_ASC) {
ksort($array);
} else {
krsort($array);
}
return $array;
}
/**
* Implodes an array.
*
* @param array $array The array
* @param string $with What to implode it with
*
* @return String
*/
public static function implode($array, $with = '')
{
return implode($with, $array);
}
/**
* Find all items in an array that pass the truth test.
*/
public static function filter($array, $closure = null)
{
if (!$closure) {
return static::clean($array);
}
return array_filter($array, $closure);
}
/**
* Flattens an array to dot notation.
*
* @param array $array An array
* @param string $separator The characater to flatten with
* @param string $parent The parent passed to the child (private)
*
* @return array Flattened array to one level
*/
public static function flatten($array, $separator = '.', $parent = null)
{
if (!is_array($array)) {
return $array;
}
$_flattened = [];
// Rewrite keys
foreach ($array as $key => $value) {
if ($parent) {
$key = $parent.$separator.$key;
}
$_flattened[$key] = static::flatten($value, $separator, $key);
}
// Flatten
$flattened = [];
foreach ($_flattened as $key => $value) {
if (is_array($value)) {
$flattened = array_merge($flattened, $value);
} else {
$flattened[$key] = $value;
}
}
return $flattened;
}
/**
* Invoke a function on all of an array's values.
*/
public static function invoke($array, $callable, $arguments = [])
{
// If one argument given for each iteration, create an array for it
if (!is_array($arguments)) {
$arguments = static::repeat($arguments, count($array));
}
// If the callable has arguments, pass them
if ($arguments) {
return array_map($callable, $array, $arguments);
}
return array_map($callable, $array);
}
/**
* Return all items that fail the truth test.
*/
public static function reject($array, Closure $closure)
{
$filtered = [];
foreach ($array as $key => $value) {
if (!$closure($value, $key)) {
$filtered[$key] = $value;
}
}
return $filtered;
}
/**
* Remove the first value from an array.
*/
public static function removeFirst($array)
{
array_shift($array);
return $array;
}
/**
* Remove the last value from an array.
*/
public static function removeLast($array)
{
array_pop($array);
return $array;
}
/**
* Removes a particular value from an array (numeric or associative).
*
* @param string $array
* @param string $value
*
* @return array
*/
public static function removeValue($array, $value)
{
$isNumericArray = true;
foreach ($array as $key => $item) {
if ($item === $value) {
if (!is_int($key)) {
$isNumericArray = false;
}
unset($array[$key]);
}
}
if ($isNumericArray) {
$array = array_values($array);
}
return $array;
}
/**
* Prepend a value to an array.
*/
public static function prepend($array, $value)
{
array_unshift($array, $value);
return $array;
}
/**
* Append a value to an array.
*/
public static function append($array, $value)
{
array_push($array, $value);
return $array;
}
}

View File

@@ -0,0 +1,375 @@
<?php
namespace Underscore\Methods;
use Closure;
/**
* Abstract Collection type
* Methods that apply to both objects and arrays.
*/
abstract class CollectionMethods
{
////////////////////////////////////////////////////////////////////
///////////////////////////// ANALYZE //////////////////////////////
////////////////////////////////////////////////////////////////////
/**
* Check if an array has a given key.
*/
public static function has($array, $key)
{
// Generate unique string to use as marker
$unfound = StringsMethods::random(5);
return static::get($array, $key, $unfound) !== $unfound;
}
////////////////////////////////////////////////////////////////////
//////////////////////////// FETCH FROM ////////////////////////////
////////////////////////////////////////////////////////////////////
/**
* Get a value from an collection using dot-notation.
*
* @param array $collection The collection to get from
* @param string $key The key to look for
* @param mixed $default Default value to fallback to
*
* @return mixed
*/
public static function get($collection, $key, $default = null)
{
if (is_null($key)) {
return $collection;
}
if (!is_object($collection) && isset($collection[$key])) {
return $collection[$key];
}
// Crawl through collection, get key according to object or not
foreach (explode('.', $key) as $segment) {
// If object
if (is_object($collection)) {
if (!isset($collection->{$segment})) {
return $default instanceof Closure ? $default() : $default;
} else {
$collection = $collection->$segment;
}
// If array
} else {
if (!isset($collection[$segment])) {
return $default instanceof Closure ? $default() : $default;
} else {
$collection = $collection[$segment];
}
}
}
return $collection;
}
/**
* Set a value in a collection using dot notation.
*
* @param mixed $collection The collection
* @param string $key The key to set
* @param mixed $value Its value
*
* @return mixed
*/
public static function set($collection, $key, $value)
{
static::internalSet($collection, $key, $value);
return $collection;
}
/**
* Get a value from a collection and set it if it wasn't.
*
* @param mixed $collection The collection
* @param string $key The key
* @param mixed $default The default value to set if it isn't
*
* @return mixed
*/
public static function setAndGet(&$collection, $key, $default = null)
{
// If the key doesn't exist, set it
if (!static::has($collection, $key)) {
$collection = static::set($collection, $key, $default);
}
return static::get($collection, $key);
}
/**
* Remove a value from an array using dot notation.
*/
public static function remove($collection, $key)
{
// Recursive call
if (is_array($key)) {
foreach ($key as $k) {
static::internalRemove($collection, $k);
}
return $collection;
}
static::internalRemove($collection, $key);
return $collection;
}
/**
* Fetches all columns $property from a multimensionnal array.
*/
public static function pluck($collection, $property)
{
$plucked = array_map(function ($value) use ($property) {
return ArraysMethods::get($value, $property);
}, (array) $collection);
// Convert back to object if necessary
if (is_object($collection)) {
$plucked = (object) $plucked;
}
return $plucked;
}
/**
* Filters an array of objects (or a numeric array of associative arrays) based on the value of a particular property within that.
*
* @param string $property
* @param string $value
* @param string $comparisonOp
*/
public static function filterBy($collection, $property, $value, $comparisonOp = null)
{
if (!$comparisonOp) {
$comparisonOp = is_array($value) ? 'contains' : 'eq';
}
$ops = [
'eq' => function ($item, $prop, $value) {
return $item[$prop] === $value;
},
'gt' => function ($item, $prop, $value) {
return $item[$prop] > $value;
},
'gte' => function ($item, $prop, $value) {
return $item[$prop] >= $value;
},
'lt' => function ($item, $prop, $value) {
return $item[$prop] < $value;
},
'lte' => function ($item, $prop, $value) {
return $item[$prop] <= $value;
},
'ne' => function ($item, $prop, $value) {
return $item[$prop] !== $value;
},
'contains' => function ($item, $prop, $value) {
return in_array($item[$prop], (array) $value, true);
},
'notContains' => function ($item, $prop, $value) {
return !in_array($item[$prop], (array) $value, true);
},
'newer' => function ($item, $prop, $value) {
return strtotime($item[$prop]) > strtotime($value);
},
'older' => function ($item, $prop, $value) {
return strtotime($item[$prop]) < strtotime($value);
},
];
$result = array_values(array_filter((array) $collection, function ($item) use (
$property,
$value,
$ops,
$comparisonOp
) {
$item = (array) $item;
if (!isset($item[$property])) {
$item[$property] = null;
}
return $ops[$comparisonOp]($item, $property, $value);
}));
if (is_object($collection)) {
$result = (object) $result;
}
return $result;
}
public static function findBy($collection, $property, $value, $comparisonOp = 'eq')
{
$filtered = static::filterBy($collection, $property, $value, $comparisonOp);
return ArraysMethods::first($filtered);
}
////////////////////////////////////////////////////////////////////
///////////////////////////// ANALYZE //////////////////////////////
////////////////////////////////////////////////////////////////////
/**
* Get all keys from a collection.
*/
public static function keys($collection)
{
return array_keys((array) $collection);
}
/**
* Get all values from a collection.
*/
public static function values($collection)
{
return array_values((array) $collection);
}
////////////////////////////////////////////////////////////////////
////////////////////////////// ALTER ///////////////////////////////
////////////////////////////////////////////////////////////////////
/**
* Replace a key with a new key/value pair.
*/
public static function replace($collection, $replace, $key, $value)
{
$collection = static::remove($collection, $replace);
$collection = static::set($collection, $key, $value);
return $collection;
}
/**
* Sort a collection by value, by a closure or by a property
* If the sorter is null, the collection is sorted naturally.
*/
public static function sort($collection, $sorter = null, $direction = 'asc')
{
$collection = (array) $collection;
// Get correct PHP constant for direction
$direction = (strtolower($direction) === 'desc') ? SORT_DESC : SORT_ASC;
// Transform all values into their results
if ($sorter) {
$results = ArraysMethods::each($collection, function ($value) use ($sorter) {
return is_callable($sorter) ? $sorter($value) : ArraysMethods::get($value, $sorter);
});
} else {
$results = $collection;
}
// Sort by the results and replace by original values
array_multisort($results, $direction, SORT_REGULAR, $collection);
return $collection;
}
/**
* Group values from a collection according to the results of a closure.
*/
public static function group($collection, $grouper)
{
$collection = (array) $collection;
$result = [];
// Iterate over values, group by property/results from closure
foreach ($collection as $key => $value) {
$key = is_callable($grouper) ? $grouper($value, $key) : ArraysMethods::get($value, $grouper);
if (!isset($result[$key])) {
$result[$key] = [];
}
// Add to results
$result[$key][] = $value;
}
return $result;
}
////////////////////////////////////////////////////////////////////
////////////////////////////// HELPERS /////////////////////////////
////////////////////////////////////////////////////////////////////
/**
* Internal mechanic of set method.
*/
protected static function internalSet(&$collection, $key, $value)
{
if (is_null($key)) {
return $collection = $value;
}
// Explode the keys
$keys = explode('.', $key);
// Crawl through the keys
while (count($keys) > 1) {
$key = array_shift($keys);
// If we're dealing with an object
if (is_object($collection)) {
if (!isset($collection->$key) or !is_array($collection->$key)) {
$collection->$key = [];
}
$collection = &$collection->$key;
// If we're dealing with an array
} else {
if (!isset($collection[$key]) or !is_array($collection[$key])) {
$collection[$key] = [];
}
$collection = &$collection[$key];
}
}
// Bind final tree on the collection
$key = array_shift($keys);
if (is_array($collection)) {
$collection[$key] = $value;
} else {
$collection->$key = $value;
}
}
/**
* Internal mechanics of remove method.
*/
protected static function internalRemove(&$collection, $key)
{
// Explode keys
$keys = explode('.', $key);
// Crawl though the keys
while (count($keys) > 1) {
$key = array_shift($keys);
// If we're dealing with an object
if (is_object($collection)) {
if (!isset($collection->$key)) {
return false;
}
$collection = &$collection->$key;
// If we're dealing with an array
} else {
if (!isset($collection[$key])) {
return false;
}
$collection = &$collection[$key];
}
}
$key = array_shift($keys);
if (is_object($collection)) {
unset($collection->$key);
} else {
unset($collection[$key]);
}
}
}

View File

@@ -0,0 +1,243 @@
<?php
namespace Underscore\Methods;
/**
* Methods to manage functions.
*/
class FunctionsMethods
{
/**
* An array of functions to be called X times.
*
* @type array
*/
public static $canBeCalledTimes = [];
/**
* An array of cached function results.
*
* @type array
*/
public static $cached = [];
/**
* An array tracking the last time a function was called.
*
* @type array
*/
public static $throttle = [];
////////////////////////////////////////////////////////////////////
////////////////////////////// LIMITERS ////////////////////////////
////////////////////////////////////////////////////////////////////
/**
* Create a function that can only be called once.
*
* @param Callable $function The function
*
* @return Closure
*/
public static function once($function)
{
return static::only($function, 1);
}
/**
* Create a function that can only be called $times times.
*
* @param Callable $function
* @param int $times The number of times
*
* @return Closure
*/
public static function only($function, $canBeCalledTimes)
{
$unique = mt_rand();
// Create a closure that check if the function was already called
return function () use ($function, $canBeCalledTimes, $unique) {
// Generate unique hash of the function
$arguments = func_get_args();
$signature = FunctionsMethods::getSignature($unique, $function, $arguments);
// Get counter
$numberOfTimesCalled = FunctionsMethods::hasBeenCalledTimes($signature);
// If the function has been called too many times, cancel
// Else, increment the count
if ($numberOfTimesCalled >= $canBeCalledTimes) {
return false;
} else {
FunctionsMethods::$canBeCalledTimes[$signature]++;
}
return call_user_func_array($function, $arguments);
};
}
/**
* Create a function that can only be called after $times times.
*
* @param Callable $function
* @param int $times
*
* @return Closure
*/
public static function after($function, $times)
{
$unique = mt_rand();
// Create a closure that check if the function was already called
return function () use ($function, $times, $unique) {
// Generate unique hash of the function
$arguments = func_get_args();
$signature = FunctionsMethods::getSignature($unique, $function, $arguments);
// Get counter
$called = FunctionsMethods::hasBeenCalledTimes($signature);
// Prevent calling before a certain number
if ($called < $times) {
FunctionsMethods::$canBeCalledTimes[$signature] += 1;
return false;
}
return call_user_func_array($function, $arguments);
};
}
/**
* Caches the result of a function and refer to it ever after.
*
* @param Callable $function
*
* @return Closure
*/
public static function cache($function)
{
$unique = mt_rand();
return function () use ($function, $unique) {
// Generate unique hash of the function
$arguments = func_get_args();
$signature = FunctionsMethods::getSignature($unique, $function, $arguments);
if (isset(FunctionsMethods::$cached[$signature])) {
return FunctionsMethods::$cached[$signature];
}
$result = call_user_func_array($function, $arguments);
FunctionsMethods::$cached[$signature] = $result;
return $result;
};
}
/**
* Only allow a function to be called every X ms.
*
* @param Callable $function
* @param int $ms
*
* @return Closure
*/
public static function throttle($function, $ms)
{
$unique = mt_rand();
return function () use ($function, $ms, $unique) {
// Generate unique hash of the function
$arguments = func_get_args();
$signature = FunctionsMethods::getSignature($unique, $function, $arguments);
// Check last called time and update it if necessary
$last = FunctionsMethods::getLastCalledTime($signature);
$difference = time() - $last;
// Execute the function if the conditions are here
if ($last === time() or $difference > $ms) {
FunctionsMethods::$throttle[$signature] = time();
return call_user_func_array($function, $arguments);
}
return false;
};
}
/**
* Prefill function arguments.
*
* @param Callable $func
*
* @return Closure
*
* @author Jeremy Ashkenas
*/
public static function partial(callable $func)
{
$boundArgs = array_slice(func_get_args(), 1);
return function () use ($boundArgs, $func) {
$args = [];
$calledArgs = func_get_args();
$position = 0;
for ($i = 0, $len = count($boundArgs); $i < $len; $i++) {
$args[] = $boundArgs[$i] === null ? $calledArgs[$position++] : $boundArgs[$i];
}
return call_user_func_array($func, array_merge($args, array_slice($calledArgs, $position)));
};
}
////////////////////////////////////////////////////////////////////
////////////////////////////// HELPERS /////////////////////////////
////////////////////////////////////////////////////////////////////
/**
* Get the last time a function was called.
*
* @param string $unique The function unique ID
*
* @return int
*/
public static function getLastCalledTime($unique)
{
return ArraysMethods::setAndGet(static::$canBeCalledTimes, $unique, time());
}
/**
* Get the number of times a function has been called.
*
* @param string $unique The function unique ID
*
* @return int
*/
public static function hasBeenCalledTimes($unique)
{
return ArraysMethods::setAndGet(static::$canBeCalledTimes, $unique, 0);
}
/**
* Get a function's signature.
*
* @param Closure $function The function
* @param array $arguments Its arguments
*
* @return string The unique id
*/
public static function getSignature($unique, $function, $arguments)
{
$function = var_export($function, true);
$arguments = var_export($arguments, true);
return md5($unique.'_'.$function.'_'.$arguments);
}
}

View File

@@ -0,0 +1,32 @@
<?php
namespace Underscore\Methods;
/**
* Methods to manage numbers.
*/
class NumberMethods
{
/**
* Add 0 padding to an integer.
*/
public static function padding($number, $padding = 1, $direction = STR_PAD_BOTH)
{
return str_pad($number, $padding, 0, $direction);
}
/**
* Add 0 padding on the left of an integer.
*/
public static function paddingLeft($number, $padding = 1)
{
return static::padding($number, $padding, STR_PAD_LEFT);
}
/**
* Add 0 padding on the right of an integer.
*/
public static function paddingRight($number, $padding = 1)
{
return static::padding($number, $padding, STR_PAD_RIGHT);
}
}

View File

@@ -0,0 +1,29 @@
<?php
namespace Underscore\Methods;
/**
* Methods to manage objects.
*/
class ObjectMethods extends CollectionMethods
{
/**
* Get all methods from an object.
*/
public static function methods($object)
{
return get_class_methods(get_class($object));
}
/**
* Unpack an object's properties.
*/
public static function unpack($object, $attribute = null)
{
$object = (array) $object;
$object = $attribute
? ArraysMethods::get($object, $attribute)
: ArraysMethods::first($object);
return (object) $object;
}
}

View File

@@ -0,0 +1,543 @@
<?php
namespace Underscore\Methods;
use Doctrine\Common\Inflector\Inflector;
use Patchwork\Utf8;
use RuntimeException;
use Underscore\Types\Strings;
/**
* Methods to manage strings.
*/
class StringsMethods
{
////////////////////////////////////////////////////////////////////
////////////////////////////// CREATE /////////////////////////////
////////////////////////////////////////////////////////////////////
/**
* Create a string from a number.
*
* @param int $count A number
* @param string $many If many
* @param string $one If one
* @param string $zero If one
*
* @return string A string
*/
public static function accord($count, $many, $one, $zero = null)
{
if ($count === 1) {
$output = $one;
} else {
if ($count === 0 and !empty($zero)) {
$output = $zero;
} else {
$output = $many;
}
}
return sprintf($output, $count);
}
/**
* Generate a more truly "random" alpha-numeric string.
*
* @param int $length
*
* @throws \RuntimeException
* @return string
*
*
* @author Taylor Otwell
*/
public static function random($length = 16)
{
if (function_exists('openssl_random_pseudo_bytes')) {
$bytes = openssl_random_pseudo_bytes($length * 2);
if ($bytes === false) {
throw new RuntimeException('Unable to generate random string.');
}
return substr(str_replace(['/', '+', '='], '', base64_encode($bytes)), 0, $length);
}
return static::quickRandom($length);
}
/**
* Generate a "random" alpha-numeric string.
*
* Should not be considered sufficient for cryptography, etc.
*
* @param int $length
*
* @return string
*
* @author Taylor Otwell
*/
public static function quickRandom($length = 16)
{
$pool = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
return substr(str_shuffle(str_repeat($pool, $length)), 0, $length);
}
/**
* Generates a random suite of words.
*
* @param int $words The number of words
* @param int $length The length of each word
*
* @return string
*/
public static function randomStrings($words, $length = 10)
{
return Strings::from('0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ')
->shuffle()
->split($length)
->slice(0, $words)
->implode(' ')
->obtain();
}
////////////////////////////////////////////////////////////////////
////////////////////////////// ANALYZE /////////////////////////////
////////////////////////////////////////////////////////////////////
/**
* Determine if a given string ends with a given substring.
*
* @param string $haystack
* @param string|array $needles
*
* @return bool
*
* @author Taylor Otwell
*/
public static function endsWith($haystack, $needles)
{
foreach ((array) $needles as $needle) {
if ((string) $needle === substr($haystack, -strlen($needle))) {
return true;
}
}
return false;
}
/**
* Check if a string is an IP.
*
* @return bool
*/
public static function isIp($string)
{
return filter_var($string, FILTER_VALIDATE_IP) !== false;
}
/**
* Check if a string is an email.
*
* @return bool
*/
public static function isEmail($string)
{
return filter_var($string, FILTER_VALIDATE_EMAIL) !== false;
}
/**
* Check if a string is an url.
*
* @return bool
*/
public static function isUrl($string)
{
return filter_var($string, FILTER_VALIDATE_URL) !== false;
}
/**
* Determine if a given string starts with a given substring.
*
* @param string $haystack
* @param string|array $needles
*
* @return bool
*
* @author Taylor Otwell
*/
public static function startsWith($haystack, $needles)
{
foreach ((array) $needles as $needle) {
if ($needle !== '' && strpos($haystack, $needle) === 0) {
return true;
}
}
return false;
}
////////////////////////////////////////////////////////////////////
///////////////////////////// FETCH FROM ///////////////////////////
////////////////////////////////////////////////////////////////////
/**
* Find one or more needles in one or more haystacks.
*
* @param array|string $string The haystack(s) to search in
* @param array|string $needle The needle(s) to search for
* @param bool $caseSensitive Whether the function is case sensitive or not
* @param bool $absolute Whether all needle need to be found or whether one is enough
*
* @return bool Found or not
*/
public static function find($string, $needle, $caseSensitive = false, $absolute = false)
{
// If several needles
if (is_array($needle) or is_array($string)) {
if (is_array($needle)) {
$sliceFrom = $needle;
$sliceTo = $string;
} else {
$sliceFrom = $string;
$sliceTo = $needle;
}
$found = 0;
foreach ($sliceFrom as $need) {
if (static::find($sliceTo, $need, $absolute, $caseSensitive)) {
$found++;
}
}
return ($absolute) ? count($sliceFrom) === $found : $found > 0;
}
// If not case sensitive
if (!$caseSensitive) {
$string = strtolower($string);
$needle = strtolower($needle);
}
// If string found
$pos = strpos($string, $needle);
return !($pos === false);
}
/**
* Slice a string with another string.
*/
public static function slice($string, $slice)
{
$sliceTo = static::sliceTo($string, $slice);
$sliceFrom = static::sliceFrom($string, $slice);
return [$sliceTo, $sliceFrom];
}
/**
* Slice a string from a certain point.
*/
public static function sliceFrom($string, $slice)
{
$slice = strpos($string, $slice);
return substr($string, $slice);
}
/**
* Slice a string up to a certain point.
*/
public static function sliceTo($string, $slice)
{
$slice = strpos($string, $slice);
return substr($string, 0, $slice);
}
/**
* Get the base class in a namespace.
*
* @param string $string
*
* @return string
*/
public static function baseClass($string)
{
$string = static::replace($string, '\\', '/');
return basename($string);
}
////////////////////////////////////////////////////////////////////
/////////////////////////////// ALTER //////////////////////////////
////////////////////////////////////////////////////////////////////
/**
* Prepend a string with another.
*
* @param string $string The string
* @param string $with What to prepend with
*
* @return string
*/
public static function prepend($string, $with)
{
return $with.$string;
}
/**
* Append a string to another.
*
* @param string $string The string
* @param string $with What to append with
*
* @return string
*/
public static function append($string, $with)
{
return $string.$with;
}
/**
* Limit the number of characters in a string.
*
* @param string $value
* @param int $limit
* @param string $end
*
* @return string
*
* @author Taylor Otwell
*/
public static function limit($value, $limit = 100, $end = '...')
{
if (mb_strlen($value) <= $limit) {
return $value;
}
return rtrim(mb_substr($value, 0, $limit, 'UTF-8')).$end;
}
/**
* Remove part of a string.
*/
public static function remove($string, $remove)
{
// If we only have one string to remove
if (!is_array($remove)) {
$string = str_replace($remove, null, $string);
} // Else, use Regex
else {
$string = preg_replace('#('.implode('|', $remove).')#', null, $string);
}
// Trim and return
return trim($string);
}
/**
* Correct arguments order for str_replace.
*/
public static function replace($string, $replace, $with)
{
return str_replace($replace, $with, $string);
}
/**
* Toggles a string between two states.
*
* @param string $string The string to toggle
* @param string $first First value
* @param string $second Second value
* @param bool $loose Whether a string neither matching 1 or 2 should be changed
*
* @return string The toggled string
*/
public static function toggle($string, $first, $second, $loose = false)
{
// If the string given match none of the other two, and we're in strict mode, return it
if (!$loose and !in_array($string, [$first, $second], true)) {
return $string;
}
return $string === $first ? $second : $first;
}
/**
* Generate a URL friendly "slug" from a given string.
*
* @param string $title
* @param string $separator
*
* @return string
*
* @author Taylor Otwell
*/
protected static function slug($title, $separator = '-')
{
$title = Utf8::toAscii($title);
// Convert all dashes/underscores into separator
$flip = $separator === '-' ? '_' : '-';
$title = preg_replace('!['.preg_quote($flip).']+!u', $separator, $title);
// Remove all characters that are not the separator, letters, numbers, or whitespace.
$title = preg_replace('![^'.preg_quote($separator).'\pL\pN\s]+!u', '', mb_strtolower($title));
// Replace all separator characters and whitespace by a single separator
$title = preg_replace('!['.preg_quote($separator).'\s]+!u', $separator, $title);
return trim($title, $separator);
}
/**
* Slugifies a string.
*/
public static function slugify($string, $separator = '-')
{
$string = str_replace('_', ' ', $string);
return static::slug($string, $separator);
}
/**
* Explode a string into an array.
*/
public static function explode($string, $with, $limit = null)
{
if (!$limit) {
return explode($with, $string);
}
return explode($with, $string, $limit);
}
/**
* Lowercase a string.
*
* @param string $string
*
* @return string
*/
public static function lower($string)
{
return mb_strtolower($string, 'UTF-8');
}
/**
* Get the plural form of an English word.
*
* @param string $value
* @param int $count
*
* @return string
*/
public static function plural($value)
{
return Inflector::pluralize($value);
}
/**
* Get the singular form of an English word.
*
* @param string $value
*
* @return string
*/
public static function singular($value)
{
return Inflector::singularize($value);
}
/**
* Lowercase a string.
*
* @param string $string
*
* @return string
*/
public static function upper($string)
{
return mb_strtoupper($string, 'UTF-8');
}
/**
* Convert a string to title case.
*
* @param string $string
*
* @return string
*/
public static function title($string)
{
return mb_convert_case($string, MB_CASE_TITLE, 'UTF-8');
}
/**
* Limit the number of words in a string.
*
* @param string $value
* @param int $words
* @param string $end
*
* @return string
*
* @author Taylor Otwell
*/
public static function words($value, $words = 100, $end = '...')
{
preg_match('/^\s*+(?:\S++\s*+){1,'.$words.'}/u', $value, $matches);
if (!isset($matches[0]) || strlen($value) === strlen($matches[0])) {
return $value;
}
return rtrim($matches[0]).$end;
}
////////////////////////////////////////////////////////////////////
/////////////////////////// CASE SWITCHERS /////////////////////////
////////////////////////////////////////////////////////////////////
/**
* Convert a string to PascalCase.
*
* @param string $string
*
* @return string
*/
public static function toPascalCase($string)
{
return Inflector::classify($string);
}
/**
* Convert a string to snake_case.
*
* @param string $string
*
* @return string
*/
public static function toSnakeCase($string)
{
return preg_replace_callback('/([A-Z])/', function ($match) {
return '_'.strtolower($match[1]);
}, $string);
}
/**
* Convert a string to camelCase.
*
* @param string $string
*
* @return string
*/
public static function toCamelCase($string)
{
return Inflector::camelize($string);
}
}

View File

@@ -0,0 +1,257 @@
<?php
namespace Underscore;
use Underscore\Methods\ArraysMethods;
/**
* Parse from various formats to various formats.
*/
class Parse
{
////////////////////////////////////////////////////////////////////
/////////////////////////////// JSON ///////////////////////////////
////////////////////////////////////////////////////////////////////
/**
* Converts data from JSON.
*
* @param string $data The data to parse
*
* @return mixed
*/
public static function fromJSON($data)
{
return json_decode($data, true);
}
/**
* Converts data to JSON.
*
* @param array|object $data The data to convert
*
* @return string Converted data
*/
public static function toJSON($data)
{
return json_encode($data);
}
////////////////////////////////////////////////////////////////////
//////////////////////////////// XML ///////////////////////////////
////////////////////////////////////////////////////////////////////
/**
* Converts data from XML.
*
* @param string $xml The data to parse
*
* @return array
*/
public static function fromXML($xml)
{
$xml = simplexml_load_string($xml);
$xml = json_encode($xml);
$xml = json_decode($xml, true);
return $xml;
}
////////////////////////////////////////////////////////////////////
//////////////////////////////// CSV ///////////////////////////////
////////////////////////////////////////////////////////////////////
/**
* Converts data from CSV.
*
* @param string $data The data to parse
* @param bool $hasHeaders Whether the CSV has headers
*
* @return mixed
*/
public static function fromCSV($data, $hasHeaders = false)
{
$data = trim($data);
// Explodes rows
$data = static::explodeWith($data, [PHP_EOL, "\r", "\n"]);
$data = array_map(function ($row) {
return Parse::explodeWith($row, [';', "\t", ',']);
}, $data);
// Get headers
$headers = $hasHeaders ? $data[0] : array_keys($data[0]);
if ($hasHeaders) {
array_shift($data);
}
// Parse the columns in each row
$array = [];
foreach ($data as $row => $columns) {
foreach ($columns as $columnNumber => $column) {
$array[$row][$headers[$columnNumber]] = $column;
}
}
return $array;
}
/**
* Converts data to CSV.
*
* @param mixed $data The data to convert
* @param string $delimiter
* @param bool $exportHeaders
*
* @return string Converted data
*/
public static function toCSV($data, $delimiter = ';', $exportHeaders = false)
{
$csv = [];
// Convert objects to arrays
if (is_object($data)) {
$data = (array) $data;
}
// Don't convert if it's not an array
if (!is_array($data)) {
return $data;
}
// Fetch headers if requested
if ($exportHeaders) {
$headers = array_keys(ArraysMethods::first($data));
$csv[] = implode($delimiter, $headers);
}
// Quote values and create row
foreach ($data as $header => $row) {
// If single column
if (!is_array($row)) {
$csv[] = '"'.$header.'"'.$delimiter.'"'.$row.'"';
continue;
}
// Else add values
foreach ($row as $key => $value) {
$row[$key] = '"'.stripslashes($value).'"';
}
$csv[] = implode($delimiter, $row);
}
return implode(PHP_EOL, $csv);
}
////////////////////////////////////////////////////////////////////
///////////////////////// TYPES SWITCHERS //////////////////////////
////////////////////////////////////////////////////////////////////
/**
* Converts data to an array.
*
* @param string|object $data
*
* @return array
*/
public static function toArray($data)
{
// Look for common array conversion patterns in objects
if (is_object($data) and method_exists($data, 'toArray')) {
$data = $data->toArray();
}
return (array) $data;
}
/**
* Converts data to a string.
*
* @param array|object $data
*
* @return string
*/
public static function toString($data)
{
// Avoid Array to Strings conversion exception
if (is_array($data)) {
return static::toJSON($data);
}
return (string) $data;
}
/**
* Converts data to an integer.
*
* @param array|string|object $data
*
* @return int
*/
public static function toInteger($data)
{
// Returns size of arrays
if (is_array($data)) {
return count($data);
}
// Returns size of strings
if (is_string($data) and !preg_match('/[0-9. ,]+/', $data)) {
return strlen($data);
}
return (int) $data;
}
/**
* Converts data to a boolean.
*
* @param array|sring|object $data
*
* @return bool
*/
public static function toBoolean($data)
{
return (bool) $data;
}
/**
* Converts data to an object.
*
* @param array|string $data
*
* @return object
*/
public static function toObject($data)
{
return (object) $data;
}
////////////////////////////////////////////////////////////////////
///////////////////////////// HELPERS //////////////////////////////
////////////////////////////////////////////////////////////////////
/**
* Tries to explode a string with an array of delimiters.
*
* @param string $string The string
* @param array $delimiters An array of delimiters
*
* @return array
*/
public static function explodeWith($string, array $delimiters)
{
$array = $string;
foreach ($delimiters as $delimiter) {
$array = explode($delimiter, $string);
if (count($array) === 1) {
continue;
} else {
return $array;
}
}
return $array;
}
}

View File

@@ -0,0 +1,275 @@
<?php
namespace Underscore\Traits;
use BadMethodCallException;
use Underscore\Dispatch;
use Underscore\Method;
use Underscore\Methods\ArraysMethods;
use Underscore\Methods\StringsMethods;
use Underscore\Parse;
/**
* Base abstract class for repositories.
*/
abstract class Repository
{
/**
* The subject of the repository.
*
* @type mixed
*/
protected $subject;
/**
* Custom functions.
*
* @type array
*/
protected static $macros = [];
/**
* The method used to convert new subjects.
*
* @type string
*/
protected $typecaster;
////////////////////////////////////////////////////////////////////
/////////////////////////// PUBLIC METHODS /////////////////////////
////////////////////////////////////////////////////////////////////
/**
* Create a new instance of the repository.
*
* @param mixed $subject The repository subject
*/
public function __construct($subject = null)
{
// Assign subject
$this->subject = $subject ?: $this->getDefault();
// Convert it if necessary
$typecaster = $this->typecaster;
if ($typecaster) {
$this->$typecaster();
}
return $this;
}
/**
* Transform subject to Strings on toString.
*
* @return string
*/
public function __toString()
{
return Parse::toString($this->subject);
}
/**
* Create a new Repository.
*/
public static function create()
{
return new static();
}
/**
* Create a new Repository from a subject.
*/
public static function from($subject)
{
return new static($subject);
}
/**
* Get a key from the subject.
*/
public function __get($key)
{
return ArraysMethods::get($this->subject, $key);
}
/**
* Set a value on the subject.
*/
public function __set($key, $value)
{
$this->subject = ArraysMethods::set($this->subject, $key, $value);
}
/**
* Check if the subject is empty.
*
* @return bool
*/
public function isEmpty()
{
return empty($this->subject);
}
/**
* Replace the Subject while maintaining chain.
*
* @param mixed $value
*/
public function setSubject($value)
{
$this->subject = $value;
return $this;
}
/**
* Get the subject from the object.
*
* @return mixed
*/
public function obtain()
{
return $this->subject;
}
/**
* Extend the class with a custom function.
*
* @param string $method The macro's name
* @param Callable $closure The macro
*/
public static function extend($method, $closure)
{
static::$macros[get_called_class()][$method] = $closure;
}
////////////////////////////////////////////////////////////////////
//////////////////////// METHODS DISPATCHING ///////////////////////
////////////////////////////////////////////////////////////////////
/**
* Catch aliases and reroute them to the right methods.
*/
public static function __callStatic($method, $parameters)
{
// Get base class and methods class
$callingClass = static::computeClassToCall(get_called_class(), $method, $parameters);
$methodsClass = Method::getMethodsFromType($callingClass);
// Defer to Methods class
if (method_exists($methodsClass, $method)) {
return self::callMethod($methodsClass, $method, $parameters);
}
// Check for an alias
if ($alias = Method::getAliasOf($method)) {
return self::callMethod($methodsClass, $alias, $parameters);
}
// Check for parsers
if (method_exists('Underscore\Parse', $method)) {
return self::callMethod('Underscore\Parse', $method, $parameters);
}
// Defered methods
if ($defered = Dispatch::toNative($callingClass, $method)) {
return call_user_func_array($defered, $parameters);
}
// Look in the macros
if ($macro = ArraysMethods::get(static::$macros, $callingClass.'.'.$method)) {
return call_user_func_array($macro, $parameters);
}
throw new BadMethodCallException('The method '.$callingClass.'::'.$method.' does not exist');
}
/**
* Allow the chained calling of methods.
*/
public function __call($method, $arguments)
{
// Get correct class
$class = Dispatch::toClass($this->subject);
// Check for unchainable methods
if (Method::isUnchainable($class, $method)) {
throw new BadMethodCallException('The method '.$class.'::'.$method.' can\'t be chained');
}
// Prepend subject to arguments and call the method
if (!Method::isSubjectless($method)) {
array_unshift($arguments, $this->subject);
}
$result = $class::__callStatic($method, $arguments);
// If the method is a breaker, return just the result
if (Method::isBreaker($method)) {
return $result;
} else {
$this->subject = $result;
}
return $this;
}
////////////////////////////////////////////////////////////////////
///////////////////////////// HELPERS //////////////////////////////
////////////////////////////////////////////////////////////////////
/**
* Tries to find the right class to call.
*
* @param string $callingClass The original class
* @param string $method The method
* @param array $arguments The arguments
*
* @return string The correct class
*/
protected static function computeClassToCall($callingClass, $method, $arguments)
{
if (!StringsMethods::find($callingClass, 'Underscore\Types')) {
if (isset($arguments[0])) {
$callingClass = Dispatch::toClass($arguments[0]);
} else {
$callingClass = Method::findInClasses($callingClass, $method);
}
}
return $callingClass;
}
/**
* Simpler version of call_user_func_array (for performances).
*
* @param string $class The class
* @param string $method The method
* @param array $parameters The arguments
*/
protected static function callMethod($class, $method, $parameters)
{
switch (count($parameters)) {
case 0:
return $class::$method();
case 1:
return $class::$method($parameters[0]);
case 2:
return $class::$method($parameters[0], $parameters[1]);
case 3:
return $class::$method($parameters[0], $parameters[1], $parameters[2]);
case 4:
return $class::$method($parameters[0], $parameters[1], $parameters[2], $parameters[3]);
case 5:
return $class::$method($parameters[0], $parameters[1], $parameters[2], $parameters[3], $parameters[4]);
}
}
/**
* Get a default value for a new repository.
*
* @return mixed
*/
protected function getDefault()
{
return '';
}
}

View File

@@ -0,0 +1,30 @@
<?php
namespace Underscore\Types;
use Underscore\Methods\ArraysMethods;
use Underscore\Traits\Repository;
/**
* Arrays repository.
*
* @mixin ArraysMethods
*/
class Arrays extends Repository
{
/**
* The method used to convert new subjects.
*
* @type string
*/
protected $typecaster = 'toArray';
/**
* Get a default value for a new repository.
*
* @return mixed
*/
protected function getDefault()
{
return [];
}
}

View File

@@ -0,0 +1,14 @@
<?php
namespace Underscore\Types;
use Underscore\Methods\FunctionsMethods;
use Underscore\Traits\Repository;
/**
* Functions repository.
*
* @mixin FunctionsMethods
*/
class Functions extends Repository
{
}

View File

@@ -0,0 +1,30 @@
<?php
namespace Underscore\Types;
use Underscore\Methods\NumberMethods;
use Underscore\Traits\Repository;
/**
* Number repository.
*
* @mixin NumberMethods
*/
class Number extends Repository
{
/**
* The method used to convert new subjects.
*
* @type string
*/
protected $typecaster = 'toInteger';
/**
* Get a default value for a new repository.
*
* @return mixed
*/
protected function getDefault()
{
return 0;
}
}

View File

@@ -0,0 +1,31 @@
<?php
namespace Underscore\Types;
use stdClass;
use Underscore\Methods\ObjectMethods;
use Underscore\Traits\Repository;
/**
* Object repository.
*
* @mixin ObjectMethods
*/
class Object extends Repository
{
/**
* The method used to convert new subjects.
*
* @type string
*/
protected $typecaster = 'toObject';
/**
* Get a default value for a new repository.
*
* @return mixed
*/
protected function getDefault()
{
return new stdClass();
}
}

View File

@@ -0,0 +1,21 @@
<?php
namespace Underscore\Types;
use Underscore\Methods\StringsMethods;
use Underscore\Traits\Repository;
/**
* Strings repository.
*
*@mixin StringsMethods
*/
class Strings extends Repository
{
/**
* The method used to convert new subjects.
*
* @type string
*/
protected $typecaster = 'toString';
}

View File

@@ -0,0 +1,57 @@
<?php
namespace Underscore;
use Underscore\Methods\ArraysMethods;
use Underscore\Traits\Repository;
/**
* The base class and wrapper around all other classes.
*/
class Underscore extends Repository
{
/**
* The current config.
*
* @type array
*/
protected static $options;
////////////////////////////////////////////////////////////////////
//////////////////////////// INTERFACE /////////////////////////////
////////////////////////////////////////////////////////////////////
/**
* Dispatch to the correct Repository class.
*
* @param mixed $subject The subject
*
* @return Repository
*/
public static function from($subject)
{
$class = Dispatch::toClass($subject);
return $class::from($subject);
}
////////////////////////////////////////////////////////////////////
///////////////////////////// HELPERS //////////////////////////////
////////////////////////////////////////////////////////////////////
/**
* Get an option from the config file.
*
* @param string $option The key of the option
*
* @return mixed Its value
*/
public static function option($option)
{
// Get config file
if (!static::$options) {
static::$options = include __DIR__.'/../config/config.php';
}
return ArraysMethods::get(static::$options, $option);
}
}

25
vendor/autoload.php vendored Normal file
View File

@@ -0,0 +1,25 @@
<?php
// autoload.php @generated by Composer
if (PHP_VERSION_ID < 50600) {
if (!headers_sent()) {
header('HTTP/1.1 500 Internal Server Error');
}
$err = 'Composer 2.3.0 dropped support for autoloading on PHP <5.6 and you are running '.PHP_VERSION.', please upgrade PHP or use Composer 2.2 LTS via "composer self-update --2.2". Aborting.'.PHP_EOL;
if (!ini_get('display_errors')) {
if (PHP_SAPI === 'cli' || PHP_SAPI === 'phpdbg') {
fwrite(STDERR, $err);
} elseif (!headers_sent()) {
echo $err;
}
}
trigger_error(
$err,
E_USER_ERROR
);
}
require_once __DIR__ . '/composer/autoload_real.php';
return ComposerAutoloaderInitbf8dc242a640d7c740f283f226d0bdb4::getLoader();

View File

@@ -0,0 +1,28 @@
<?php
namespace Axn\Laroute;
use Lord\Laroute\LarouteServiceProvider;
use Lord\Laroute\Console\Commands\LarouteGeneratorCommand;
use Axn\Laroute\Routes\Collection as Routes;
class ServiceProvider extends LarouteServiceProvider
{
/**
* Register the command.
*
* @return void
*/
protected function registerCommand()
{
$this->app->singleton('command.laroute.generate', function($app) {
$config = $app['config'];
$routes = new Routes($app['router']->getRoutes(), $config->get('laroute.filter', 'all'), $config->get('laroute.action_namespace', ''));
$generator = $app->make('Lord\Laroute\Generators\GeneratorInterface');
return new LarouteGeneratorCommand($config, $routes, $generator);
});
$this->commands('command.laroute.generate');
}
}

View File

@@ -0,0 +1,69 @@
<?php
return [
/*
|--------------------------------------------------------------------------
| Routes group config
|--------------------------------------------------------------------------
|
| The default group settings for the elFinder routes.
|
*/
'route' => [
'prefix' => 'translations',
'middleware' => 'auth',
],
/**
* Enable deletion of translations
*
* @type boolean
*/
'delete_enabled' => true,
/**
* Exclude specific groups from Laravel Translation Manager.
* This is useful if, for example, you want to avoid editing the official Laravel language files.
*
* @type array
*
* array(
* 'pagination',
* 'reminders',
* 'validation',
* )
*/
'exclude_groups' => [],
/**
* Exclude specific languages from Laravel Translation Manager.
*
* @type array
*
* array(
* 'fr',
* 'de',
* )
*/
'exclude_langs' => [],
/**
* Export translations with keys output alphabetically.
*/
'sort_keys ' => false,
'trans_functions' => [
'trans',
'trans_choice',
'Lang::get',
'Lang::choice',
'Lang::trans',
'Lang::transChoice',
'@lang',
'@choice',
'__',
'$trans.get',
],
];

View File

@@ -0,0 +1,37 @@
<?php
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class CreateTranslationsTable extends Migration {
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('ltm_translations', function(Blueprint $table)
{
$table->increments('id');
$table->integer('status')->default(0);
$table->string('locale');
$table->string('group');
$table->text('key');
$table->text('value')->nullable();
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::drop('ltm_translations');
}
}

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,41 @@
<?php
namespace Barryvdh\TranslationManager\Console;
use Barryvdh\TranslationManager\Manager;
use Illuminate\Console\Command;
class CleanCommand extends Command
{
/**
* The console command name.
*
* @var string
*/
protected $name = 'translations:clean';
/**
* The console command description.
*
* @var string
*/
protected $description = 'Clean empty translations';
/** @var \Barryvdh\TranslationManager\Manager */
protected $manager;
public function __construct(Manager $manager)
{
$this->manager = $manager;
parent::__construct();
}
/**
* Execute the console command.
*/
public function handle()
{
$this->manager->cleanTranslations();
$this->info('Done cleaning translations');
}
}

View File

@@ -0,0 +1,87 @@
<?php
namespace Barryvdh\TranslationManager\Console;
use Barryvdh\TranslationManager\Manager;
use Illuminate\Console\Command;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputOption;
class ExportCommand extends Command
{
/**
* The console command name.
*
* @var string
*/
protected $name = 'translations:export';
/**
* The console command description.
*
* @var string
*/
protected $description = 'Export translations to PHP files';
/** @var \Barryvdh\TranslationManager\Manager */
protected $manager;
public function __construct(Manager $manager)
{
$this->manager = $manager;
parent::__construct();
}
/**
* Execute the console command.
*/
public function handle()
{
$group = $this->argument('group');
$json = $this->option('json');
if (is_null($group) && !$json) {
$this->warn('You must either specify a group argument or export as --json');
return;
}
if (!is_null($group) && $json) {
$this->warn('You cannot use both group argument and --json option at the same time');
return;
}
$this->manager->exportTranslations($group, $json);
if (!is_null($group)) {
$this->info('Done writing language files for '.(($group == '*') ? 'ALL groups' : $group.' group'));
} elseif ($json) {
$this->info('Done writing JSON language files for translation strings');
}
}
/**
* Get the console command arguments.
*
* @return array
*/
protected function getArguments()
{
return [
['group', InputArgument::OPTIONAL, 'The group to export (`*` for all).'],
];
}
/**
* Get the console command options.
*
* @return array
*/
protected function getOptions()
{
return [
['json', 'J', InputOption::VALUE_NONE, 'Export anonymous strings to JSON'],
];
}
}

View File

@@ -0,0 +1,41 @@
<?php
namespace Barryvdh\TranslationManager\Console;
use Barryvdh\TranslationManager\Manager;
use Illuminate\Console\Command;
class FindCommand extends Command
{
/**
* The console command name.
*
* @var string
*/
protected $name = 'translations:find';
/**
* The console command description.
*
* @var string
*/
protected $description = 'Find translations in php/twig files';
/** @var \Barryvdh\TranslationManager\Manager */
protected $manager;
public function __construct(Manager $manager)
{
$this->manager = $manager;
parent::__construct();
}
/**
* Execute the console command.
*/
public function handle()
{
$counter = $this->manager->findTranslations(null);
$this->info('Done importing, processed '.$counter.' items!');
}
}

View File

@@ -0,0 +1,55 @@
<?php
namespace Barryvdh\TranslationManager\Console;
use Barryvdh\TranslationManager\Manager;
use Illuminate\Console\Command;
use Symfony\Component\Console\Input\InputOption;
class ImportCommand extends Command
{
/**
* The console command name.
*
* @var string
*/
protected $name = 'translations:import';
/**
* The console command description.
*
* @var string
*/
protected $description = 'Import translations from the PHP sources';
/** @var \Barryvdh\TranslationManager\Manager */
protected $manager;
public function __construct(Manager $manager)
{
$this->manager = $manager;
parent::__construct();
}
/**
* Execute the console command.
*/
public function handle()
{
$replace = $this->option('replace');
$counter = $this->manager->importTranslations($replace);
$this->info('Done importing, processed '.$counter.' items!');
}
/**
* Get the console command options.
*
* @return array
*/
protected function getOptions()
{
return [
['replace', 'R', InputOption::VALUE_NONE, 'Replace existing keys'],
];
}
}

View File

@@ -0,0 +1,41 @@
<?php
namespace Barryvdh\TranslationManager\Console;
use Illuminate\Console\Command;
use Barryvdh\TranslationManager\Manager;
class ResetCommand extends Command
{
/**
* The console command name.
*
* @var string
*/
protected $name = 'translations:reset';
/**
* The console command description.
*
* @var string
*/
protected $description = 'Delete all translations from the database';
/** @var \Barryvdh\TranslationManager\Manager */
protected $manager;
public function __construct(Manager $manager)
{
$this->manager = $manager;
parent::__construct();
}
/**
* Execute the console command.
*/
public function handle()
{
$this->manager->truncateTranslations();
$this->info('All translations are deleted');
}
}

View File

@@ -0,0 +1,24 @@
<?php
/**
* Created by PhpStorm.
* User: kgbot
* Date: 5/29/18
* Time: 12:40 PM
*/
namespace Barryvdh\TranslationManager\Events;
class TranslationsExportedEvent
{
/**
* Create a new event instance.
*
* @return void
*/
public function __construct()
{
}
}

View File

@@ -0,0 +1,111 @@
<?php namespace Barryvdh\TranslationManager;
use Illuminate\Routing\Router;
use Illuminate\Support\ServiceProvider;
class ManagerServiceProvider extends ServiceProvider {
/**
* Indicates if loading of the provider is deferred.
*
* @var bool
*/
protected $defer = false;
/**
* Register the service provider.
*
* @return void
*/
public function register()
{
// Register the config publish path
$configPath = __DIR__ . '/../config/translation-manager.php';
$this->mergeConfigFrom($configPath, 'translation-manager');
$this->publishes([$configPath => config_path('translation-manager.php')], 'config');
$this->app->singleton('translation-manager', function ($app) {
$manager = $app->make('Barryvdh\TranslationManager\Manager');
return $manager;
});
$this->app->singleton('command.translation-manager.reset', function ($app) {
return new Console\ResetCommand($app['translation-manager']);
});
$this->commands('command.translation-manager.reset');
$this->app->singleton('command.translation-manager.import', function ($app) {
return new Console\ImportCommand($app['translation-manager']);
});
$this->commands('command.translation-manager.import');
$this->app->singleton('command.translation-manager.find', function ($app) {
return new Console\FindCommand($app['translation-manager']);
});
$this->commands('command.translation-manager.find');
$this->app->singleton('command.translation-manager.export', function ($app) {
return new Console\ExportCommand($app['translation-manager']);
});
$this->commands('command.translation-manager.export');
$this->app->singleton('command.translation-manager.clean', function ($app) {
return new Console\CleanCommand($app['translation-manager']);
});
$this->commands('command.translation-manager.clean');
}
/**
* Bootstrap the application events.
*
* @param \Illuminate\Routing\Router $router
* @return void
*/
public function boot(Router $router)
{
$viewPath = __DIR__.'/../resources/views';
$this->loadViewsFrom($viewPath, 'translation-manager');
$this->publishes([
$viewPath => base_path('resources/views/vendor/translation-manager'),
], 'views');
$migrationPath = __DIR__.'/../database/migrations';
$this->publishes([
$migrationPath => base_path('database/migrations'),
], 'migrations');
$config = $this->app['config']->get('translation-manager.route', []);
$config['namespace'] = 'Barryvdh\TranslationManager';
$router->group($config, function($router)
{
$router->get('view/{groupKey?}', 'Controller@getView')->where('groupKey', '.*');
$router->get('/{groupKey?}', 'Controller@getIndex')->where('groupKey', '.*');
$router->post('/add/{groupKey}', 'Controller@postAdd')->where('groupKey', '.*');
$router->post('/edit/{groupKey}', 'Controller@postEdit')->where('groupKey', '.*');
$router->post('/groups/add', 'Controller@postAddGroup');
$router->post('/delete/{groupKey}/{translationKey}', 'Controller@postDelete')->where('groupKey', '.*');
$router->post('/import', 'Controller@postImport');
$router->post('/find', 'Controller@postFind');
$router->post('/locales/add', 'Controller@postAddLocale');
$router->post('/locales/remove', 'Controller@postRemoveLocale');
$router->post('/publish/{groupKey}', 'Controller@postPublish')->where('groupKey', '.*');
});
}
/**
* Get the services provided by the provider.
*
* @return array
*/
public function provides()
{
return array('translation-manager',
'command.translation-manager.reset',
'command.translation-manager.import',
'command.translation-manager.find',
'command.translation-manager.export',
'command.translation-manager.clean'
);
}
}

View File

@@ -0,0 +1,55 @@
<?php namespace Barryvdh\TranslationManager\Models;
use Illuminate\Database\Eloquent\Model;
use DB;
/**
* Translation model
*
* @property integer $id
* @property integer $status
* @property string $locale
* @property string $group
* @property string $key
* @property string $value
* @property \Carbon\Carbon $created_at
* @property \Carbon\Carbon $updated_at
*/
class Translation extends Model{
const STATUS_SAVED = 0;
const STATUS_CHANGED = 1;
protected $table = 'ltm_translations';
protected $guarded = array('id', 'created_at', 'updated_at');
public function scopeOfTranslatedGroup($query, $group)
{
return $query->where('group', $group)->whereNotNull('value');
}
public function scopeOrderByGroupKeys($query, $ordered) {
if ($ordered) {
$query->orderBy('group')->orderBy('key');
}
return $query;
}
public function scopeSelectDistinctGroup($query)
{
$select = '';
switch (DB::getDriverName()){
case 'mysql':
$select = 'DISTINCT `group`';
break;
default:
$select = 'DISTINCT "group"';
break;
}
return $query->select(DB::raw($select));
}
}

View File

@@ -0,0 +1,41 @@
<?php namespace Barryvdh\TranslationManager;
use Illuminate\Translation\TranslationServiceProvider as BaseTranslationServiceProvider;
class TranslationServiceProvider extends BaseTranslationServiceProvider {
/**
* Register the service provider.
*
* @return void
*/
public function register()
{
$this->registerLoader();
$this->app->singleton('translator', function($app)
{
$loader = $app['translation.loader'];
// When registering the translator component, we'll need to set the default
// locale as well as the fallback locale. So, we'll grab the application
// configuration so we can easily get both of these values from there.
$locale = $app['config']['app.locale'];
$trans = new Translator($loader, $locale);
$trans->setFallback($app['config']['app.fallback_locale']);
if($app->bound('translation-manager')){
$trans->setTranslationManager($app['translation-manager']);
}
return $trans;
});
}
}

View File

@@ -0,0 +1,47 @@
<?php namespace Barryvdh\TranslationManager;
use Illuminate\Translation\Translator as LaravelTranslator;
use Illuminate\Events\Dispatcher;
class Translator extends LaravelTranslator {
/** @var Dispatcher */
protected $events;
/**
* Get the translation for the given key.
*
* @param string $key
* @param array $replace
* @param string $locale
* @return string
*/
public function get($key, array $replace = array(), $locale = null, $fallback = true)
{
// Get without fallback
$result = parent::get($key, $replace, $locale, false);
if($result === $key){
$this->notifyMissingKey($key);
// Reget with fallback
$result = parent::get($key, $replace, $locale, $fallback);
}
return $result;
}
public function setTranslationManager(Manager $manager)
{
$this->manager = $manager;
}
protected function notifyMissingKey($key)
{
list($namespace, $group, $item) = $this->parseKey($key);
if($this->manager && $namespace === '*' && $group && $item ){
$this->manager->missingKey($namespace, $group, $item);
}
}
}

117
vendor/bin/doctrine-dbal vendored Executable file
View File

@@ -0,0 +1,117 @@
#!/usr/bin/env php
<?php
/**
* Proxy PHP file generated by Composer
*
* This file includes the referenced bin path (../doctrine/dbal/bin/doctrine-dbal)
* using a stream wrapper to prevent the shebang from being output on PHP<8
*
* @generated
*/
namespace Composer;
$GLOBALS['_composer_bin_dir'] = __DIR__;
$GLOBALS['_composer_autoload_path'] = __DIR__ . '/..'.'/autoload.php';
if (PHP_VERSION_ID < 80000) {
if (!class_exists('Composer\BinProxyWrapper')) {
/**
* @internal
*/
final class BinProxyWrapper
{
private $handle;
private $position;
private $realpath;
public function stream_open($path, $mode, $options, &$opened_path)
{
// get rid of phpvfscomposer:// prefix for __FILE__ & __DIR__ resolution
$opened_path = substr($path, 17);
$this->realpath = realpath($opened_path) ?: $opened_path;
$opened_path = $this->realpath;
$this->handle = fopen($this->realpath, $mode);
$this->position = 0;
return (bool) $this->handle;
}
public function stream_read($count)
{
$data = fread($this->handle, $count);
if ($this->position === 0) {
$data = preg_replace('{^#!.*\r?\n}', '', $data);
}
$this->position += strlen($data);
return $data;
}
public function stream_cast($castAs)
{
return $this->handle;
}
public function stream_close()
{
fclose($this->handle);
}
public function stream_lock($operation)
{
return $operation ? flock($this->handle, $operation) : true;
}
public function stream_seek($offset, $whence)
{
if (0 === fseek($this->handle, $offset, $whence)) {
$this->position = ftell($this->handle);
return true;
}
return false;
}
public function stream_tell()
{
return $this->position;
}
public function stream_eof()
{
return feof($this->handle);
}
public function stream_stat()
{
return array();
}
public function stream_set_option($option, $arg1, $arg2)
{
return true;
}
public function url_stat($path, $flags)
{
$path = substr($path, 17);
if (file_exists($path)) {
return stat($path);
}
return false;
}
}
}
if (function_exists('stream_wrapper_register') && stream_wrapper_register('phpvfscomposer', 'Composer\BinProxyWrapper')) {
include("phpvfscomposer://" . __DIR__ . '/..'.'/doctrine/dbal/bin/doctrine-dbal');
exit(0);
}
}
include __DIR__ . '/..'.'/doctrine/dbal/bin/doctrine-dbal';

119
vendor/bin/php-parse vendored Executable file
View File

@@ -0,0 +1,119 @@
#!/usr/bin/env php
<?php
/**
* Proxy PHP file generated by Composer
*
* This file includes the referenced bin path (../nikic/php-parser/bin/php-parse)
* using a stream wrapper to prevent the shebang from being output on PHP<8
*
* @generated
*/
namespace Composer;
$GLOBALS['_composer_bin_dir'] = __DIR__;
$GLOBALS['_composer_autoload_path'] = __DIR__ . '/..'.'/autoload.php';
if (PHP_VERSION_ID < 80000) {
if (!class_exists('Composer\BinProxyWrapper')) {
/**
* @internal
*/
final class BinProxyWrapper
{
private $handle;
private $position;
private $realpath;
public function stream_open($path, $mode, $options, &$opened_path)
{
// get rid of phpvfscomposer:// prefix for __FILE__ & __DIR__ resolution
$opened_path = substr($path, 17);
$this->realpath = realpath($opened_path) ?: $opened_path;
$opened_path = $this->realpath;
$this->handle = fopen($this->realpath, $mode);
$this->position = 0;
return (bool) $this->handle;
}
public function stream_read($count)
{
$data = fread($this->handle, $count);
if ($this->position === 0) {
$data = preg_replace('{^#!.*\r?\n}', '', $data);
}
$this->position += strlen($data);
return $data;
}
public function stream_cast($castAs)
{
return $this->handle;
}
public function stream_close()
{
fclose($this->handle);
}
public function stream_lock($operation)
{
return $operation ? flock($this->handle, $operation) : true;
}
public function stream_seek($offset, $whence)
{
if (0 === fseek($this->handle, $offset, $whence)) {
$this->position = ftell($this->handle);
return true;
}
return false;
}
public function stream_tell()
{
return $this->position;
}
public function stream_eof()
{
return feof($this->handle);
}
public function stream_stat()
{
return array();
}
public function stream_set_option($option, $arg1, $arg2)
{
return true;
}
public function url_stat($path, $flags)
{
$path = substr($path, 17);
if (file_exists($path)) {
return stat($path);
}
return false;
}
}
}
if (
(function_exists('stream_get_wrappers') && in_array('phpvfscomposer', stream_get_wrappers(), true))
|| (function_exists('stream_wrapper_register') && stream_wrapper_register('phpvfscomposer', 'Composer\BinProxyWrapper'))
) {
return include("phpvfscomposer://" . __DIR__ . '/..'.'/nikic/php-parser/bin/php-parse');
}
}
return include __DIR__ . '/..'.'/nikic/php-parser/bin/php-parse';

117
vendor/bin/psysh vendored Executable file
View File

@@ -0,0 +1,117 @@
#!/usr/bin/env php
<?php
/**
* Proxy PHP file generated by Composer
*
* This file includes the referenced bin path (../psy/psysh/bin/psysh)
* using a stream wrapper to prevent the shebang from being output on PHP<8
*
* @generated
*/
namespace Composer;
$GLOBALS['_composer_bin_dir'] = __DIR__;
$GLOBALS['_composer_autoload_path'] = __DIR__ . '/..'.'/autoload.php';
if (PHP_VERSION_ID < 80000) {
if (!class_exists('Composer\BinProxyWrapper')) {
/**
* @internal
*/
final class BinProxyWrapper
{
private $handle;
private $position;
private $realpath;
public function stream_open($path, $mode, $options, &$opened_path)
{
// get rid of phpvfscomposer:// prefix for __FILE__ & __DIR__ resolution
$opened_path = substr($path, 17);
$this->realpath = realpath($opened_path) ?: $opened_path;
$opened_path = $this->realpath;
$this->handle = fopen($this->realpath, $mode);
$this->position = 0;
return (bool) $this->handle;
}
public function stream_read($count)
{
$data = fread($this->handle, $count);
if ($this->position === 0) {
$data = preg_replace('{^#!.*\r?\n}', '', $data);
}
$this->position += strlen($data);
return $data;
}
public function stream_cast($castAs)
{
return $this->handle;
}
public function stream_close()
{
fclose($this->handle);
}
public function stream_lock($operation)
{
return $operation ? flock($this->handle, $operation) : true;
}
public function stream_seek($offset, $whence)
{
if (0 === fseek($this->handle, $offset, $whence)) {
$this->position = ftell($this->handle);
return true;
}
return false;
}
public function stream_tell()
{
return $this->position;
}
public function stream_eof()
{
return feof($this->handle);
}
public function stream_stat()
{
return array();
}
public function stream_set_option($option, $arg1, $arg2)
{
return true;
}
public function url_stat($path, $flags)
{
$path = substr($path, 17);
if (file_exists($path)) {
return stat($path);
}
return false;
}
}
}
if (function_exists('stream_wrapper_register') && stream_wrapper_register('phpvfscomposer', 'Composer\BinProxyWrapper')) {
include("phpvfscomposer://" . __DIR__ . '/..'.'/psy/psysh/bin/psysh');
exit(0);
}
}
include __DIR__ . '/..'.'/psy/psysh/bin/psysh';

32
vendor/chumper/zipper/.travis.yml vendored Normal file
View File

@@ -0,0 +1,32 @@
language: php
sudo: false
php:
- 5.6
- 7.0
- 7.1
env:
global:
- setup=basic
matrix:
fast_finish: true
include:
- php: 5.6
env: setup=lowest
- php: 5.6
env: setup=stable
before_install:
- composer self-update
- composer clear-cache
install:
- if [[ $setup = 'basic' ]]; then travis_retry composer update --no-interaction --prefer-dist --no-suggest; fi
- if [[ $setup = 'stable' ]]; then travis_retry composer update --prefer-dist --no-interaction --prefer-stable --no-suggest; fi
- if [[ $setup = 'lowest' ]]; then travis_retry composer update --prefer-dist --no-interaction --prefer-lowest --prefer-stable --no-suggest; fi
script: vendor/bin/phpunit

View File

@@ -0,0 +1,13 @@
<?php
namespace Chumper\Zipper\Facades;
use Illuminate\Support\Facades\Facade;
class Zipper extends Facade
{
protected static function getFacadeAccessor()
{
return 'zipper';
}
}

View File

@@ -0,0 +1,106 @@
<?php
namespace Chumper\Zipper\Repositories;
/**
* RepositoryInterface that needs to be implemented by every Repository
*
* Class RepositoryInterface
*/
interface RepositoryInterface
{
/**
* Construct with a given path
*
* @param $filePath
* @param bool $new
* @param $archiveImplementation
*/
public function __construct($filePath, $new = false, $archiveImplementation = null);
/**
* Add a file to the opened Archive
*
* @param $pathToFile
* @param $pathInArchive
*/
public function addFile($pathToFile, $pathInArchive);
/**
* Add a file to the opened Archive using its contents
*
* @param $name
* @param $content
*/
public function addFromString($name, $content);
/**
* Add an empty directory
*
* @param $dirName
*/
public function addEmptyDir($dirName);
/**
* Remove a file permanently from the Archive
*
* @param $pathInArchive
*/
public function removeFile($pathInArchive);
/**
* Get the content of a file
*
* @param $pathInArchive
*
* @return string
*/
public function getFileContent($pathInArchive);
/**
* Get the stream of a file
*
* @param $pathInArchive
*
* @return mixed
*/
public function getFileStream($pathInArchive);
/**
* Will loop over every item in the archive and will execute the callback on them
* Will provide the filename for every item
*
* @param $callback
*/
public function each($callback);
/**
* Checks whether the file is in the archive
*
* @param $fileInArchive
*
* @return bool
*/
public function fileExists($fileInArchive);
/**
* Sets the password to be used for decompressing
*
* @param $password
*
* @return bool
*/
public function usePassword($password);
/**
* Returns the status of the archive as a string
*
* @return string
*/
public function getStatus();
/**
* Closes the archive and saves it
*/
public function close();
}

View File

@@ -0,0 +1,50 @@
<?php
namespace Chumper\Zipper;
use Illuminate\Foundation\AliasLoader;
use Illuminate\Support\ServiceProvider;
class ZipperServiceProvider extends ServiceProvider
{
/**
* Indicates if loading of the provider is deferred.
*
* @var bool
*/
protected $defer = false;
/**
* Bootstrap the application events.
*/
public function boot()
{
}
/**
* Register the service provider.
*/
public function register()
{
$this->app->singleton('zipper', function ($app) {
$return = $app->make('Chumper\Zipper\Zipper');
return $return;
});
$this->app->booting(function () {
$loader = AliasLoader::getInstance();
$loader->alias('Zipper', 'Chumper\Zipper\Facades\Zipper');
});
}
/**
* Get the services provided by the provider.
*
* @return array
*/
public function provides()
{
return ['zipper'];
}
}

View File

@@ -0,0 +1,16 @@
preset: laravel
risky: false
enabled:
- no_useless_else
- phpdoc_align
- phpdoc_no_empty_return
- phpdoc_order
- phpdoc_separation
finder:
exclude:
- "resources"
- "storage"
- "tests"

View File

@@ -0,0 +1,18 @@
language: php
php:
- 5.5
- 5.6
branches:
only:
- 5.x
install:
- travis_retry composer install --no-interaction --prefer-source
script:
- vendor/bin/phpunit --verbose --coverage-text --coverage-clover=coverage.xml
after_success:
- bash <(curl -s https://codecov.io/bash)

View File

@@ -0,0 +1,116 @@
<?php
return [
/*
|--------------------------------------------------------------------------
| Default source repository type
|--------------------------------------------------------------------------
|
| The default source repository type you want to pull your updates from.
|
*/
'default' => env('SELF_UPDATER_SOURCE', 'github'),
/*
|--------------------------------------------------------------------------
| Version installed
|--------------------------------------------------------------------------
|
| Set this to the version of your software installed on your system.
|
*/
'version_installed' => env('SELF_UPDATER_VERSION_INSTALLED', ''),
/*
|--------------------------------------------------------------------------
| Repository types
|--------------------------------------------------------------------------
|
| A repository can be of different types, which can be specified here.
| Current options:
| - github
|
*/
'repository_types' => [
'github' => [
'type' => 'github',
'repository_vendor' => env('SELF_UPDATER_REPO_VENDOR', ''),
'repository_name' => env('SELF_UPDATER_REPO_NAME', ''),
'repository_url' => '',
'download_path' => env('SELF_UPDATER_DOWNLOAD_PATH', '/tmp'),
],
],
/*
|--------------------------------------------------------------------------
| Exclude folders from update
|--------------------------------------------------------------------------
|
| Specifiy folders which should not be updated and will be skipped during the
| update process.
|
| Here's already a list of good examples to skip. You may want to keep those.
|
*/
'exclude_folders' => [
'node_modules',
'bootstrap/cache',
'bower',
'storage/app',
'storage/framework',
'storage/logs',
'storage/self-update',
'vendor',
],
/*
|--------------------------------------------------------------------------
| Event Logging
|--------------------------------------------------------------------------
|
| Configure if fired events should be logged
|
*/
'log_events' => env('SELF_UPDATER_LOG_EVENTS', false),
/*
|--------------------------------------------------------------------------
| Mail To Settings
|--------------------------------------------------------------------------
|
| Configure if fired events should be logged
|
*/
'mail_to' => [
'address' => env('SELF_UPDATER_MAILTO_ADDRESS', ''),
'name' => env('SELF_UPDATER_MAILTO_NAME', ''),
'subject_update_available' => env('SELF_UPDATER_MAILTO_UPDATE_AVAILABLE_SUBJECT', 'Update available'),
'subject_update_succeeded' => env('SELF_UPDATER_MAILTO_UPDATE_SUCCEEDED_SUBJECT', 'Update succeeded'),
],
/*
|---------------------------------------------------------------------------
| Register custom artisan commands
|---------------------------------------------------------------------------
*/
'artisan_commands' => [
'pre_update' => [
//'command:signature' => [
// 'class' => Command class
// 'params' => []
//]
],
'post_update' => [
],
],
];

View File

@@ -0,0 +1,5 @@
Hello!
The new version {{ $newVersion }} is available.
Kind regards

View File

@@ -0,0 +1,162 @@
<?php
namespace Codedge\Updater;
use File;
use GuzzleHttp\Client;
use Symfony\Component\Finder\Finder;
use Codedge\Updater\Events\HasWrongPermissions;
/**
* AbstractRepositoryType.php.
*
* @author Holger Lösken <holger.loesken@codedge.de>
* @copyright See LICENSE file that was distributed with this source code.
*/
abstract class AbstractRepositoryType
{
/**
* @var array
*/
protected $config;
/**
* @var Finder|SplFileInfo[]
*/
protected $pathToUpdate;
/**
* Unzip an archive.
*
* @param string $file
* @param string $targetDir
* @param bool $deleteZipArchive
*
* @throws \Exception
*
* @return bool
*/
protected function unzipArchive($file = '', $targetDir = '', $deleteZipArchive = true)
{
if (empty($file) || ! File::exists($file)) {
throw new \InvalidArgumentException("Archive [{$file}] cannot be found or is empty.");
}
$zip = new \ZipArchive();
$res = $zip->open($file);
if (! $res) {
throw new \Exception("Cannot open zip archive [{$file}].");
}
if (empty($targetDir)) {
$extracted = $zip->extractTo(File::dirname($file));
} else {
$extracted = $zip->extractTo($targetDir);
}
$zip->close();
if ($extracted && $deleteZipArchive === true) {
File::delete($file);
}
return true;
}
/**
* Check a given directory recursively if all files are writeable.
*
* @throws \Exception
*
* @return bool
*/
protected function hasCorrectPermissionForUpdate()
{
if (! $this->pathToUpdate) {
throw new \Exception('No directory set for update. Please set the update with: setPathToUpdate(path).');
}
$collection = collect($this->pathToUpdate->files())->each(function ($file) { /* @var \SplFileInfo $file */
if (! File::isWritable($file->getRealPath())) {
event(new HasWrongPermissions($this));
return false;
}
});
return true;
}
/**
* Download a file to a given location.
*
* @param Client $client
* @param string $source
* @param string $storagePath
*
* @return mixed|\Psr\Http\Message\ResponseInterface
*/
protected function downloadRelease(Client $client, $source, $storagePath)
{
return $client->request(
'GET', $source, ['sink' => $storagePath]
);
}
/**
* Check if the source has already been downloaded.
*
* @param string $version A specific version
*
* @return bool
*/
protected function isSourceAlreadyFetched($version)
{
$storagePath = $this->config['download_path'].'/'.$version;
if (! File::exists($storagePath) || empty(File::directories($storagePath))
) {
return false;
}
return true;
}
/**
* Set the paths to be updated.
*
* @param string $path Path where the update should be run into
* @param array $exclude List of folder names that shall not be updated
*/
protected function setPathToUpdate($path, array $exclude)
{
$finder = (new Finder())->in($path)->exclude($exclude);
$this->pathToUpdate = $finder;
}
/**
* Create a releas sub-folder inside the storage dir.
*
* @param string $storagePath
* @param string $releaseName
*/
public function createReleaseFolder($storagePath, $releaseName)
{
$subDirName = File::directories($storagePath);
$directories = File::directories($subDirName[0]);
File::makeDirectory($storagePath.'/'.$releaseName, 493, true, true);
foreach ($directories as $directory) { /* @var string $directory */
File::moveDirectory($directory, $storagePath.'/'.$releaseName.'/'.File::name($directory));
}
$files = File::allFiles($subDirName[0], true);
foreach ($files as $file) { /* @var \SplFileInfo $file */
File::move($file->getRealPath(), $storagePath.'/'.$releaseName.'/'.$file->getFilename());
}
File::deleteDirectory($subDirName[0]);
}
}

View File

@@ -0,0 +1,56 @@
<?php
namespace Codedge\Updater\Commands;
use Illuminate\Console\Command;
use Codedge\Updater\UpdaterManager;
class CheckForUpdate extends Command
{
/**
* @var string
*/
protected $signature = 'updater:check-for-update
{--prefixVersionWith= : Prefix the currently installed version with something.}
{--suffixVersionWith= : Suffix the currently installed version with something.}';
/**
* @var string
*/
protected $description = 'Check if a new update is available.';
/**
* @var UpdaterManager
*/
protected $updater;
/**
* CheckForUpdate constructor.
*
* @param UpdaterManager $updater
*/
public function __construct(UpdaterManager $updater)
{
parent::__construct();
$this->updater = $updater;
}
/**
* Execute the command.
*/
public function handle()
{
$prefix = $this->option('prefixVersionWith');
$suffix = $this->option('suffixVersionWith');
$currentVersion = $this->updater->source()->getVersionInstalled($prefix, $suffix);
$isAvail = $this->updater->source()->isNewVersionAvailable($currentVersion);
if ($isAvail) {
$newVersion = $this->updater->source()->getVersionAvailable();
$this->info('A new version ['.$newVersion.'] is available.');
} else {
$this->comment('There\'s no new version available.');
}
}
}

View File

@@ -0,0 +1,55 @@
<?php
namespace Codedge\Updater\Contracts;
interface SourceRepositoryTypeContract
{
/**
* Fetches the latest version. If you do not want the latest version, specify one and pass it.
*
* @param string $version
*
* @return mixed
*/
public function fetch($version = '');
/**
* Perform the actual update process.
*
* @return bool
*/
public function update();
/**
* Check repository if a newer version than the installed one is available.
* Caution: v.1.1 compared to 1.1 is not the same. Check to actually compare correct version, including letters
* before or after.
*
* @param string $currentVersion
*
* @return bool
*/
public function isNewVersionAvailable($currentVersion = '');
/**
* Get the version that is currenly installed.
* Example: 1.1.0 or v1.1.0 or "1.1.0 version".
*
* @param string $prepend
* @param string $append
*
* @return string
*/
public function getVersionInstalled($prepend = '', $append = '');
/**
* Get the latest version that has been published in a certain repository.
* Example: 2.6.5 or v2.6.5.
*
* @param string $prepend Prepend a string to the latest version
* @param string $append Append a string to the latest version
*
* @return string
*/
public function getVersionAvailable($prepend = '', $append = '');
}

View File

@@ -0,0 +1,15 @@
<?php
namespace Codedge\Updater\Contracts;
interface UpdaterContract
{
/**
* Get a source type instance.
*
* @param string $name
*
* @return mixed
*/
public function source($name = '');
}

View File

@@ -0,0 +1,24 @@
<?php
namespace Codedge\Updater\Events;
/**
* HasWrongPermissions.php.
*
* @author Holger Lösken <holger.loesken@codedge.de>
* @copyright See LICENSE file that was distributed with this source code.
*/
class HasWrongPermissions
{
protected $repository;
/**
* UpdateFailed constructor.
*
* @param $repository
*/
public function __construct($repository)
{
$this->repository = $repository;
}
}

View File

@@ -0,0 +1,55 @@
<?php
namespace Codedge\Updater\Events;
/**
* UpdateFailed.php.
*
* @author Holger Lösken <holger.loesken@codedge.de>
* @copyright See LICENSE file that was distributed with this source code.
*/
class UpdateAvailable
{
/**
* @var string
*/
protected $eventName = 'Update available';
/**
* @var string
*/
protected $versionAvailable;
/**
* UpdateFailed constructor.
*
* @param string $versionAvailable
*/
public function __construct($versionAvailable)
{
$this->versionAvailable = $versionAvailable;
}
/**
* Get the event name.
*
* @return string
*/
public function getEventName()
{
return $this->eventName;
}
/**
* Get the new version.
*
* @param string $prepend
* @param string $append
*
* @return string
*/
public function getVersionAvailable($prepend = '', $append = '')
{
return $prepend.$this->versionAvailable.$append;
}
}

View File

@@ -0,0 +1,44 @@
<?php
namespace Codedge\Updater\Events;
use Codedge\Updater\Contracts\SourceRepositoryTypeContract;
/**
* UpdateFailed.php.
*
* @author Holger Lösken <holger.loesken@codedge.de>
* @copyright See LICENSE file that was distributed with this source code.
*/
class UpdateFailed
{
/**
* @var SourceRepositoryTypeContract
*/
protected $sourceRepository;
/**
* @var string
*/
protected $eventName = 'Update failed';
/**
* UpdateFailed constructor.
*
* @param SourceRepositoryTypeContract $sourceRepository
*/
public function __construct(SourceRepositoryTypeContract $sourceRepository)
{
$this->sourceRepository = $sourceRepository;
}
/**
* Get the event name.
*
* @return string
*/
public function getName()
{
return $this->eventName;
}
}

View File

@@ -0,0 +1,55 @@
<?php
namespace Codedge\Updater\Events;
/**
* UpdateFailed.php.
*
* @author Holger Lösken <holger.loesken@codedge.de>
* @copyright See LICENSE file that was distributed with this source code.
*/
class UpdateSucceeded
{
/**
* @var string
*/
protected $eventName = 'Update succeeded';
/**
* @var string The version of the new software package.
*/
protected $versionUpdatedTo;
/**
* UpdateFailed constructor.
*
* @param $versionUpdatedTo
*/
public function __construct($versionUpdatedTo)
{
$this->versionUpdatedTo = $versionUpdatedTo;
}
/**
* Get the event name.
*
* @return string
*/
public function getEventName()
{
return $this->eventName;
}
/**
* Get the new version.
*
* @param string $prepend
* @param string $append
*
* @return string
*/
public function getVersionUpdatedTo($prepend = '', $append = '')
{
return $prepend.$this->versionUpdatedTo.$append;
}
}

View File

@@ -0,0 +1,80 @@
<?php
namespace Codedge\Updater\Listeners;
use Illuminate\Log\Writer;
use Illuminate\Mail\Mailer;
use Codedge\Updater\Events\UpdateAvailable;
/**
* SendUpdateAvailableNotification.php.
*
* @author Holger Lösken <holger.loesken@codedge.de>
* @copyright See LICENSE file that was distributed with this source code.
*/
class SendUpdateAvailableNotification
{
/**
* @var \Monolog\Logger
*/
protected $logger;
/**
* @var Mailer
*/
protected $mailer;
/**
* SendUpdateAvailableNotification constructor.
*
* @param Writer $logger
* @param Mailer $mailer
*/
public function __construct(Writer $logger, Mailer $mailer)
{
$this->logger = $logger->getMonolog();
$this->mailer = $mailer;
}
/**
* Handle the event.
*
* @param UpdateAvailable $event
*/
public function handle(UpdateAvailable $event)
{
if (config('self-update.log_events')) {
$this->logger->addInfo('['.$event->getEventName().'] event: Notification triggered.');
}
$sendToAddress = config('self-update.mail_to.address');
$sendToName = config('self-update.mail_to.name');
$subject = config('self-update.mail_to.subject_update_available');
if (empty($sendToAddress)) {
$this->logger->addCritical(
'['.$event->getEventName().'] event: '
.'Missing recipient email address. Please set SELF_UPDATER_MAILTO_ADDRESS in your .env file.'
);
}
if (empty($sendToName)) {
$this->logger->addWarning(
'['.$event->getEventName().'] event: '
.'Missing recipient email name. Please set SELF_UPDATER_MAILTO_NAME in your .env file.'
);
}
$this->mailer->send(
'vendor.self-update.mails.update-available',
[
'newVersion' => $event->getVersionAvailable(),
],
function ($m) use ($subject, $sendToAddress, $sendToName) {
$m->subject($subject);
$m->from(config('mail.from.address'), config('mail.from.name'));
$m->to($sendToAddress, $sendToName);
}
);
}
}

View File

@@ -0,0 +1,80 @@
<?php
namespace Codedge\Updater\Listeners;
use Illuminate\Log\Writer;
use Illuminate\Mail\Mailer;
use Codedge\Updater\Events\UpdateSucceeded;
/**
* SendUpdateSucceededNotification.php.
*
* @author Holger Lösken <holger.loesken@codedge.de>
* @copyright See LICENSE file that was distributed with this source code.
*/
class SendUpdateSucceededNotification
{
/**
* @var \Monolog\Logger
*/
protected $logger;
/**
* @var Mailer
*/
protected $mailer;
/**
* SendUpdateAvailableNotification constructor.
*
* @param Writer $logger
* @param Mailer $mailer
*/
public function __construct(Writer $logger, Mailer $mailer)
{
$this->logger = $logger->getMonolog();
$this->mailer = $mailer;
}
/**
* Handle the event.
*
* @param UpdateSucceeded $event
*/
public function handle(UpdateSucceeded $event)
{
if (config('self-update.log_events')) {
$this->logger->addInfo('['.$event->getEventName().'] event: Notification triggered.');
}
$sendToAddress = config('self-update.mail_to.address');
$sendToName = config('self-update.mail_to.name');
$subject = config('self-update.mail_to.subject_update_succeeded');
if (empty($sendToAddress)) {
$this->logger->addCritical(
'['.$event->getEventName().'] event: '
.'Missing recipient email address. Please set SELF_UPDATER_MAILTO_ADDRESS in your .env file.'
);
}
if (empty($sendToName)) {
$this->logger->addWarning(
'['.$event->getEventName().'] event: '
.'Missing recipient email name. Please set SELF_UPDATER_MAILTO_NAME in your .env file.'
);
}
$this->mailer->send(
'vendor.self-update.mails.update-available',
[
'newVersion' => $event->getVersionAvailable(),
],
function ($m) use ($subject, $sendToAddress, $sendToName) {
$m->subject($subject);
$m->from(config('mail.from.address'), config('mail.from.name'));
$m->to($sendToAddress, $sendToName);
}
);
}
}

View File

@@ -0,0 +1,127 @@
<?php
namespace Codedge\Updater;
use Illuminate\Support\Facades\Artisan;
use Codedge\Updater\Contracts\SourceRepositoryTypeContract;
/**
* SourceRepository.
*
* @author Holger Lösken <holger.loesken@codedge.de>
* @copyright See LICENSE file that was distributed with this source code.
*/
class SourceRepository implements SourceRepositoryTypeContract
{
/**
* @var SourceRepositoryTypeContract
*/
protected $sourceRepository;
/**
* SourceRepository constructor.
*
* @param SourceRepositoryTypeContract $sourceRepository
*/
public function __construct(SourceRepositoryTypeContract $sourceRepository)
{
$this->sourceRepository = $sourceRepository;
}
/**
* Fetches the latest version. If you do not want the latest version, specify one and pass it.
*
* @param string $version
*
* @return mixed
*/
public function fetch($version = '')
{
$version = ! empty($version) ? $version : $this->getVersionAvailable();
return $this->sourceRepository->fetch($version);
}
/**
* Perform the actual update process.
*
* @param string $version Define the version you want to update to
* @param bool $forceFetching Forces a fresh download of the latest update version
*
* @return bool
*/
public function update($version = '', $forceFetching = true)
{
$version = ! empty($version) ? $version : $this->getVersionAvailable();
if ($forceFetching) {
$this->fetch($version);
}
$this->preUpdateArtisanCommands();
$updateStatus = $this->sourceRepository->update($version);
$this->postUpdateArtisanCommands();
return $updateStatus;
}
/**
* Check repository if a newer version than the installed one is available.
*
* @param string $currentVersion
*
* @return bool
*/
public function isNewVersionAvailable($currentVersion = '')
{
return $this->sourceRepository->isNewVersionAvailable($currentVersion);
}
/**
* Get the version that is currenly installed.
* Example: 1.1.0 or v1.1.0 or "1.1.0 version".
*
* @param string $prepend
* @param string $append
*
* @return string
*/
public function getVersionInstalled($prepend = '', $append = '')
{
return $this->sourceRepository->getVersionInstalled($prepend, $append);
}
/**
* Get the latest version that has been published in a certain repository.
* Example: 2.6.5 or v2.6.5.
*
* @param string $prepend Prepend a string to the latest version
* @param string $append Append a string to the latest version
*
* @return string
*/
public function getVersionAvailable($prepend = '', $append = '')
{
return $this->sourceRepository->getVersionAvailable($prepend, $append);
}
/**
* Run pre update artisan commands from config.
*/
protected function preUpdateArtisanCommands()
{
collect(config('self-update.artisan_commands.pre_update'))->every(function ($commandParams, $commandKey) {
Artisan::call($commandKey, $commandParams['params']);
});
}
/**
* Run post update artisan commands from config.
*/
protected function postUpdateArtisanCommands()
{
collect(config('self-update.artisan_commands.post_update'))->every(function ($commandParams, $commandKey) {
Artisan::call($commandKey, $commandParams['params']);
});
}
}

View File

@@ -0,0 +1,24 @@
<?php
namespace Codedge\Updater;
use Illuminate\Support\Facades\Facade;
/**
* UpdaterFacade.php.
*
* @author Holger Lösken <holger.loesken@codedge.de>
* @copyright See LICENSE file that was distributed with this source code.
*/
class UpdaterFacade extends Facade
{
/**
* Get the registered component name.
*
* @return string
*/
protected static function getFacadeAccessor()
{
return 'updater';
}
}

View File

@@ -0,0 +1,186 @@
<?php
namespace Codedge\Updater;
use Closure;
use GuzzleHttp\Client;
use Illuminate\Foundation\Application;
use Codedge\Updater\Contracts\UpdaterContract;
use Codedge\Updater\Contracts\SourceRepositoryTypeContract;
use Codedge\Updater\SourceRepositoryTypes\GithubRepositoryType;
/**
* Updater.php.
*
* @author Holger Lösken <holger.loesken@codedge.de>
* @copyright See LICENSE file that was distributed with this source code.
*/
class UpdaterManager implements UpdaterContract
{
/**
* Application instance.
*
* @var Application
*/
protected $app;
/**
* @var array
*/
protected $sources = [];
/**
* @var array
*/
protected $customSourceCreators = [];
/**
* Create a new Updater manager instance.
*
* @param Application $app
*/
public function __construct(Application $app)
{
$this->app = $app;
}
/**
* Get a source repository type instance.
*
* @param string $name
*
* @return SourceRepository
*/
public function source($name = '')
{
$name = ! empty($name) ? $name : $this->getDefaultSourceRepository();
return $this->sources[$name] = $this->get($name);
}
/**
* Get the default source repository type.
*
* @return string
*/
public function getDefaultSourceRepository()
{
return $this->app['config']['self-update']['default'];
}
/**
* @param SourceRepositoryTypeContract $sourceRepository
*
* @return SourceRepository
*/
public function sourceRepository(SourceRepositoryTypeContract $sourceRepository)
{
return new SourceRepository($sourceRepository);
}
/**
* Register a custom driver creator Closure.
*
* @param string $source
* @param Closure $callback
*
* @return $this
*/
public function extend($source, Closure $callback)
{
$this->customRepositoryTypes[$source] = $callback;
return $this;
}
/**
* Dynamically call the default source repository instance.
*
* @param string $method
* @param array $parameters
*
* @return mixed
*/
public function __call($method, $parameters)
{
return call_user_func_array([$this->source(), $method], $parameters);
}
/**
* Get the source repository connection configuration.
*
* @param string $name
*
* @return array
*/
protected function getConfig($name)
{
return $this->app['config']['self-update']['repository_types'][$name];
}
/**
* Attempt to get the right source repository instance.
*
* @param string $name
*
* @return SourceRepositoryTypeContract
*/
protected function get($name)
{
return isset($this->sources[$name]) ? $this->sources[$name] : $this->resolve($name);
}
/**
* Try to find the correct source repository implementation ;-).
*
* @param string $name
*
* @throws InvalidArgumentException
*
* @return mixed
*/
protected function resolve($name)
{
$config = $this->getConfig($name);
if (is_null($config)) {
throw new InvalidArgumentException("Source repository [{$name}] is not defined.");
}
if (isset($this->customSourceCreators[$config['type']])) {
return $this->callCustomSourceCreators($config);
}
$repositoryMethod = 'create'.ucfirst($name).'Repository';
if (method_exists($this, $repositoryMethod)) {
return $this->{$repositoryMethod}($config);
}
throw new InvalidArgumentException("Repository [{$name}] is not supported.");
}
/**
* Create an instance for the Github source repository.
*
* @param array $config
*
* @return SourceRepository
*/
protected function createGithubRepository(array $config)
{
$client = new Client();
return $this->sourceRepository(new GithubRepositoryType($client, $config));
}
/**
* Call a custom source repository type.
*
* @param array $config
*
* @return mixed
*/
protected function callCustomSourceCreators(array $config)
{
return $this->customSourceCreators[$config['type']]($this->app, $config);
}
}

View File

@@ -0,0 +1,98 @@
<?php
namespace Codedge\Updater;
use Illuminate\Support\ServiceProvider;
use Codedge\Updater\Commands\CheckForUpdate;
use Illuminate\Contracts\Container\Container;
/**
* UpdaterServiceProvider.php.
*
* @author Holger Lösken <holger.loesken@codedge.de>
* @copyright See LICENSE file that was distributed with this source code.
*/
class UpdaterServiceProvider extends ServiceProvider
{
/**
* Indicates if loading of the provider is deferred.
*
* @var bool
*/
protected $defer = false;
/**
* Perform post-registration booting of services.
*/
public function boot()
{
$this->publishes([
__DIR__.'/../config/self-update.php' => config_path('self-update.php'),
], 'config');
$this->loadViews();
}
/**
* Set up views.
*/
protected function loadViews()
{
$this->loadViewsFrom(__DIR__.'/../resources/views', 'self-update');
$this->publishes([
__DIR__.'/../resources/views' => resource_path('views/vendor/self-update'),
]);
}
/**
* Register the service provider.
*/
public function register()
{
$this->mergeConfigFrom(__DIR__.'/../config/self-update.php', 'self-update');
$this->registerCommands();
$this->registerManager();
}
/**
* Register the package its commands.
*/
protected function registerCommands()
{
$this->commands([
CheckForUpdate::class,
]);
// Register custom commands from config
collect(config('self-update.artisan_commands.pre_update'))->each(function ($command) {
$this->commands([$command['class']]);
});
collect(config('self-update.artisan_commands.post_update'))->each(function ($command) {
$this->commands([$command['class']]);
});
}
/**
* Register the manager class.
*/
protected function registerManager()
{
$this->app->singleton('updater', function (Container $app) {
return new UpdaterManager($app);
});
$this->app->alias('updater', UpdaterManager::class);
}
/**
* Get the services provided by the provider.
*
* @return array
*/
public function provides()
{
return [
'updater',
];
}
}

579
vendor/composer/ClassLoader.php vendored Normal file
View File

@@ -0,0 +1,579 @@
<?php
/*
* This file is part of Composer.
*
* (c) Nils Adermann <naderman@naderman.de>
* Jordi Boggiano <j.boggiano@seld.be>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Composer\Autoload;
/**
* ClassLoader implements a PSR-0, PSR-4 and classmap class loader.
*
* $loader = new \Composer\Autoload\ClassLoader();
*
* // register classes with namespaces
* $loader->add('Symfony\Component', __DIR__.'/component');
* $loader->add('Symfony', __DIR__.'/framework');
*
* // activate the autoloader
* $loader->register();
*
* // to enable searching the include path (eg. for PEAR packages)
* $loader->setUseIncludePath(true);
*
* In this example, if you try to use a class in the Symfony\Component
* namespace or one of its children (Symfony\Component\Console for instance),
* the autoloader will first look for the class under the component/
* directory, and it will then fallback to the framework/ directory if not
* found before giving up.
*
* This class is loosely based on the Symfony UniversalClassLoader.
*
* @author Fabien Potencier <fabien@symfony.com>
* @author Jordi Boggiano <j.boggiano@seld.be>
* @see https://www.php-fig.org/psr/psr-0/
* @see https://www.php-fig.org/psr/psr-4/
*/
class ClassLoader
{
/** @var \Closure(string):void */
private static $includeFile;
/** @var string|null */
private $vendorDir;
// PSR-4
/**
* @var array<string, array<string, int>>
*/
private $prefixLengthsPsr4 = array();
/**
* @var array<string, list<string>>
*/
private $prefixDirsPsr4 = array();
/**
* @var list<string>
*/
private $fallbackDirsPsr4 = array();
// PSR-0
/**
* List of PSR-0 prefixes
*
* Structured as array('F (first letter)' => array('Foo\Bar (full prefix)' => array('path', 'path2')))
*
* @var array<string, array<string, list<string>>>
*/
private $prefixesPsr0 = array();
/**
* @var list<string>
*/
private $fallbackDirsPsr0 = array();
/** @var bool */
private $useIncludePath = false;
/**
* @var array<string, string>
*/
private $classMap = array();
/** @var bool */
private $classMapAuthoritative = false;
/**
* @var array<string, bool>
*/
private $missingClasses = array();
/** @var string|null */
private $apcuPrefix;
/**
* @var array<string, self>
*/
private static $registeredLoaders = array();
/**
* @param string|null $vendorDir
*/
public function __construct($vendorDir = null)
{
$this->vendorDir = $vendorDir;
self::initializeIncludeClosure();
}
/**
* @return array<string, list<string>>
*/
public function getPrefixes()
{
if (!empty($this->prefixesPsr0)) {
return call_user_func_array('array_merge', array_values($this->prefixesPsr0));
}
return array();
}
/**
* @return array<string, list<string>>
*/
public function getPrefixesPsr4()
{
return $this->prefixDirsPsr4;
}
/**
* @return list<string>
*/
public function getFallbackDirs()
{
return $this->fallbackDirsPsr0;
}
/**
* @return list<string>
*/
public function getFallbackDirsPsr4()
{
return $this->fallbackDirsPsr4;
}
/**
* @return array<string, string> Array of classname => path
*/
public function getClassMap()
{
return $this->classMap;
}
/**
* @param array<string, string> $classMap Class to filename map
*
* @return void
*/
public function addClassMap(array $classMap)
{
if ($this->classMap) {
$this->classMap = array_merge($this->classMap, $classMap);
} else {
$this->classMap = $classMap;
}
}
/**
* Registers a set of PSR-0 directories for a given prefix, either
* appending or prepending to the ones previously set for this prefix.
*
* @param string $prefix The prefix
* @param list<string>|string $paths The PSR-0 root directories
* @param bool $prepend Whether to prepend the directories
*
* @return void
*/
public function add($prefix, $paths, $prepend = false)
{
$paths = (array) $paths;
if (!$prefix) {
if ($prepend) {
$this->fallbackDirsPsr0 = array_merge(
$paths,
$this->fallbackDirsPsr0
);
} else {
$this->fallbackDirsPsr0 = array_merge(
$this->fallbackDirsPsr0,
$paths
);
}
return;
}
$first = $prefix[0];
if (!isset($this->prefixesPsr0[$first][$prefix])) {
$this->prefixesPsr0[$first][$prefix] = $paths;
return;
}
if ($prepend) {
$this->prefixesPsr0[$first][$prefix] = array_merge(
$paths,
$this->prefixesPsr0[$first][$prefix]
);
} else {
$this->prefixesPsr0[$first][$prefix] = array_merge(
$this->prefixesPsr0[$first][$prefix],
$paths
);
}
}
/**
* Registers a set of PSR-4 directories for a given namespace, either
* appending or prepending to the ones previously set for this namespace.
*
* @param string $prefix The prefix/namespace, with trailing '\\'
* @param list<string>|string $paths The PSR-4 base directories
* @param bool $prepend Whether to prepend the directories
*
* @throws \InvalidArgumentException
*
* @return void
*/
public function addPsr4($prefix, $paths, $prepend = false)
{
$paths = (array) $paths;
if (!$prefix) {
// Register directories for the root namespace.
if ($prepend) {
$this->fallbackDirsPsr4 = array_merge(
$paths,
$this->fallbackDirsPsr4
);
} else {
$this->fallbackDirsPsr4 = array_merge(
$this->fallbackDirsPsr4,
$paths
);
}
} elseif (!isset($this->prefixDirsPsr4[$prefix])) {
// Register directories for a new namespace.
$length = strlen($prefix);
if ('\\' !== $prefix[$length - 1]) {
throw new \InvalidArgumentException("A non-empty PSR-4 prefix must end with a namespace separator.");
}
$this->prefixLengthsPsr4[$prefix[0]][$prefix] = $length;
$this->prefixDirsPsr4[$prefix] = $paths;
} elseif ($prepend) {
// Prepend directories for an already registered namespace.
$this->prefixDirsPsr4[$prefix] = array_merge(
$paths,
$this->prefixDirsPsr4[$prefix]
);
} else {
// Append directories for an already registered namespace.
$this->prefixDirsPsr4[$prefix] = array_merge(
$this->prefixDirsPsr4[$prefix],
$paths
);
}
}
/**
* Registers a set of PSR-0 directories for a given prefix,
* replacing any others previously set for this prefix.
*
* @param string $prefix The prefix
* @param list<string>|string $paths The PSR-0 base directories
*
* @return void
*/
public function set($prefix, $paths)
{
if (!$prefix) {
$this->fallbackDirsPsr0 = (array) $paths;
} else {
$this->prefixesPsr0[$prefix[0]][$prefix] = (array) $paths;
}
}
/**
* Registers a set of PSR-4 directories for a given namespace,
* replacing any others previously set for this namespace.
*
* @param string $prefix The prefix/namespace, with trailing '\\'
* @param list<string>|string $paths The PSR-4 base directories
*
* @throws \InvalidArgumentException
*
* @return void
*/
public function setPsr4($prefix, $paths)
{
if (!$prefix) {
$this->fallbackDirsPsr4 = (array) $paths;
} else {
$length = strlen($prefix);
if ('\\' !== $prefix[$length - 1]) {
throw new \InvalidArgumentException("A non-empty PSR-4 prefix must end with a namespace separator.");
}
$this->prefixLengthsPsr4[$prefix[0]][$prefix] = $length;
$this->prefixDirsPsr4[$prefix] = (array) $paths;
}
}
/**
* Turns on searching the include path for class files.
*
* @param bool $useIncludePath
*
* @return void
*/
public function setUseIncludePath($useIncludePath)
{
$this->useIncludePath = $useIncludePath;
}
/**
* Can be used to check if the autoloader uses the include path to check
* for classes.
*
* @return bool
*/
public function getUseIncludePath()
{
return $this->useIncludePath;
}
/**
* Turns off searching the prefix and fallback directories for classes
* that have not been registered with the class map.
*
* @param bool $classMapAuthoritative
*
* @return void
*/
public function setClassMapAuthoritative($classMapAuthoritative)
{
$this->classMapAuthoritative = $classMapAuthoritative;
}
/**
* Should class lookup fail if not found in the current class map?
*
* @return bool
*/
public function isClassMapAuthoritative()
{
return $this->classMapAuthoritative;
}
/**
* APCu prefix to use to cache found/not-found classes, if the extension is enabled.
*
* @param string|null $apcuPrefix
*
* @return void
*/
public function setApcuPrefix($apcuPrefix)
{
$this->apcuPrefix = function_exists('apcu_fetch') && filter_var(ini_get('apc.enabled'), FILTER_VALIDATE_BOOLEAN) ? $apcuPrefix : null;
}
/**
* The APCu prefix in use, or null if APCu caching is not enabled.
*
* @return string|null
*/
public function getApcuPrefix()
{
return $this->apcuPrefix;
}
/**
* Registers this instance as an autoloader.
*
* @param bool $prepend Whether to prepend the autoloader or not
*
* @return void
*/
public function register($prepend = false)
{
spl_autoload_register(array($this, 'loadClass'), true, $prepend);
if (null === $this->vendorDir) {
return;
}
if ($prepend) {
self::$registeredLoaders = array($this->vendorDir => $this) + self::$registeredLoaders;
} else {
unset(self::$registeredLoaders[$this->vendorDir]);
self::$registeredLoaders[$this->vendorDir] = $this;
}
}
/**
* Unregisters this instance as an autoloader.
*
* @return void
*/
public function unregister()
{
spl_autoload_unregister(array($this, 'loadClass'));
if (null !== $this->vendorDir) {
unset(self::$registeredLoaders[$this->vendorDir]);
}
}
/**
* Loads the given class or interface.
*
* @param string $class The name of the class
* @return true|null True if loaded, null otherwise
*/
public function loadClass($class)
{
if ($file = $this->findFile($class)) {
$includeFile = self::$includeFile;
$includeFile($file);
return true;
}
return null;
}
/**
* Finds the path to the file where the class is defined.
*
* @param string $class The name of the class
*
* @return string|false The path if found, false otherwise
*/
public function findFile($class)
{
// class map lookup
if (isset($this->classMap[$class])) {
return $this->classMap[$class];
}
if ($this->classMapAuthoritative || isset($this->missingClasses[$class])) {
return false;
}
if (null !== $this->apcuPrefix) {
$file = apcu_fetch($this->apcuPrefix.$class, $hit);
if ($hit) {
return $file;
}
}
$file = $this->findFileWithExtension($class, '.php');
// Search for Hack files if we are running on HHVM
if (false === $file && defined('HHVM_VERSION')) {
$file = $this->findFileWithExtension($class, '.hh');
}
if (null !== $this->apcuPrefix) {
apcu_add($this->apcuPrefix.$class, $file);
}
if (false === $file) {
// Remember that this class does not exist.
$this->missingClasses[$class] = true;
}
return $file;
}
/**
* Returns the currently registered loaders keyed by their corresponding vendor directories.
*
* @return array<string, self>
*/
public static function getRegisteredLoaders()
{
return self::$registeredLoaders;
}
/**
* @param string $class
* @param string $ext
* @return string|false
*/
private function findFileWithExtension($class, $ext)
{
// PSR-4 lookup
$logicalPathPsr4 = strtr($class, '\\', DIRECTORY_SEPARATOR) . $ext;
$first = $class[0];
if (isset($this->prefixLengthsPsr4[$first])) {
$subPath = $class;
while (false !== $lastPos = strrpos($subPath, '\\')) {
$subPath = substr($subPath, 0, $lastPos);
$search = $subPath . '\\';
if (isset($this->prefixDirsPsr4[$search])) {
$pathEnd = DIRECTORY_SEPARATOR . substr($logicalPathPsr4, $lastPos + 1);
foreach ($this->prefixDirsPsr4[$search] as $dir) {
if (file_exists($file = $dir . $pathEnd)) {
return $file;
}
}
}
}
}
// PSR-4 fallback dirs
foreach ($this->fallbackDirsPsr4 as $dir) {
if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr4)) {
return $file;
}
}
// PSR-0 lookup
if (false !== $pos = strrpos($class, '\\')) {
// namespaced class name
$logicalPathPsr0 = substr($logicalPathPsr4, 0, $pos + 1)
. strtr(substr($logicalPathPsr4, $pos + 1), '_', DIRECTORY_SEPARATOR);
} else {
// PEAR-like class name
$logicalPathPsr0 = strtr($class, '_', DIRECTORY_SEPARATOR) . $ext;
}
if (isset($this->prefixesPsr0[$first])) {
foreach ($this->prefixesPsr0[$first] as $prefix => $dirs) {
if (0 === strpos($class, $prefix)) {
foreach ($dirs as $dir) {
if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr0)) {
return $file;
}
}
}
}
}
// PSR-0 fallback dirs
foreach ($this->fallbackDirsPsr0 as $dir) {
if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr0)) {
return $file;
}
}
// PSR-0 include paths.
if ($this->useIncludePath && $file = stream_resolve_include_path($logicalPathPsr0)) {
return $file;
}
return false;
}
/**
* @return void
*/
private static function initializeIncludeClosure()
{
if (self::$includeFile !== null) {
return;
}
/**
* Scope isolated include.
*
* Prevents access to $this/self from included files.
*
* @param string $file
* @return void
*/
self::$includeFile = \Closure::bind(static function($file) {
include $file;
}, null, null);
}
}

362
vendor/composer/InstalledVersions.php vendored Normal file
View File

@@ -0,0 +1,362 @@
<?php
/*
* This file is part of Composer.
*
* (c) Nils Adermann <naderman@naderman.de>
* Jordi Boggiano <j.boggiano@seld.be>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Composer;
use Composer\Autoload\ClassLoader;
use Composer\Semver\VersionParser;
/**
* This class is copied in every Composer installed project and available to all
*
* See also https://getcomposer.org/doc/07-runtime.md#installed-versions
*
* To require its presence, you can require `composer-runtime-api ^2.0`
*
* @final
*/
class InstalledVersions
{
/**
* @var mixed[]|null
* @psalm-var array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>}|array{}|null
*/
private static $installed;
/**
* @var bool|null
*/
private static $canGetVendors;
/**
* @var array[]
* @psalm-var array<string, array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>}>
*/
private static $installedByVendor = array();
/**
* Returns a list of all package names which are present, either by being installed, replaced or provided
*
* @return string[]
* @psalm-return list<string>
*/
public static function getInstalledPackages()
{
$packages = array();
foreach (self::getInstalled() as $installed) {
$packages[] = array_keys($installed['versions']);
}
if (1 === \count($packages)) {
return $packages[0];
}
return array_keys(array_flip(\call_user_func_array('array_merge', $packages)));
}
/**
* Returns a list of all package names with a specific type e.g. 'library'
*
* @param string $type
* @return string[]
* @psalm-return list<string>
*/
public static function getInstalledPackagesByType($type)
{
$packagesByType = array();
foreach (self::getInstalled() as $installed) {
foreach ($installed['versions'] as $name => $package) {
if (isset($package['type']) && $package['type'] === $type) {
$packagesByType[] = $name;
}
}
}
return $packagesByType;
}
/**
* Checks whether the given package is installed
*
* This also returns true if the package name is provided or replaced by another package
*
* @param string $packageName
* @param bool $includeDevRequirements
* @return bool
*/
public static function isInstalled($packageName, $includeDevRequirements = true)
{
foreach (self::getInstalled() as $installed) {
if (isset($installed['versions'][$packageName])) {
return $includeDevRequirements || !isset($installed['versions'][$packageName]['dev_requirement']) || $installed['versions'][$packageName]['dev_requirement'] === false;
}
}
return false;
}
/**
* Checks whether the given package satisfies a version constraint
*
* e.g. If you want to know whether version 2.3+ of package foo/bar is installed, you would call:
*
* Composer\InstalledVersions::satisfies(new VersionParser, 'foo/bar', '^2.3')
*
* @param VersionParser $parser Install composer/semver to have access to this class and functionality
* @param string $packageName
* @param string|null $constraint A version constraint to check for, if you pass one you have to make sure composer/semver is required by your package
* @return bool
*/
public static function satisfies(VersionParser $parser, $packageName, $constraint)
{
$constraint = $parser->parseConstraints((string) $constraint);
$provided = $parser->parseConstraints(self::getVersionRanges($packageName));
return $provided->matches($constraint);
}
/**
* Returns a version constraint representing all the range(s) which are installed for a given package
*
* It is easier to use this via isInstalled() with the $constraint argument if you need to check
* whether a given version of a package is installed, and not just whether it exists
*
* @param string $packageName
* @return string Version constraint usable with composer/semver
*/
public static function getVersionRanges($packageName)
{
foreach (self::getInstalled() as $installed) {
if (!isset($installed['versions'][$packageName])) {
continue;
}
$ranges = array();
if (isset($installed['versions'][$packageName]['pretty_version'])) {
$ranges[] = $installed['versions'][$packageName]['pretty_version'];
}
if (array_key_exists('aliases', $installed['versions'][$packageName])) {
$ranges = array_merge($ranges, $installed['versions'][$packageName]['aliases']);
}
if (array_key_exists('replaced', $installed['versions'][$packageName])) {
$ranges = array_merge($ranges, $installed['versions'][$packageName]['replaced']);
}
if (array_key_exists('provided', $installed['versions'][$packageName])) {
$ranges = array_merge($ranges, $installed['versions'][$packageName]['provided']);
}
return implode(' || ', $ranges);
}
throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed');
}
/**
* @param string $packageName
* @return string|null If the package is being replaced or provided but is not really installed, null will be returned as version, use satisfies or getVersionRanges if you need to know if a given version is present
*/
public static function getVersion($packageName)
{
foreach (self::getInstalled() as $installed) {
if (!isset($installed['versions'][$packageName])) {
continue;
}
if (!isset($installed['versions'][$packageName]['version'])) {
return null;
}
return $installed['versions'][$packageName]['version'];
}
throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed');
}
/**
* @param string $packageName
* @return string|null If the package is being replaced or provided but is not really installed, null will be returned as version, use satisfies or getVersionRanges if you need to know if a given version is present
*/
public static function getPrettyVersion($packageName)
{
foreach (self::getInstalled() as $installed) {
if (!isset($installed['versions'][$packageName])) {
continue;
}
if (!isset($installed['versions'][$packageName]['pretty_version'])) {
return null;
}
return $installed['versions'][$packageName]['pretty_version'];
}
throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed');
}
/**
* @param string $packageName
* @return string|null If the package is being replaced or provided but is not really installed, null will be returned as reference
*/
public static function getReference($packageName)
{
foreach (self::getInstalled() as $installed) {
if (!isset($installed['versions'][$packageName])) {
continue;
}
if (!isset($installed['versions'][$packageName]['reference'])) {
return null;
}
return $installed['versions'][$packageName]['reference'];
}
throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed');
}
/**
* @param string $packageName
* @return string|null If the package is being replaced or provided but is not really installed, null will be returned as install path. Packages of type metapackages also have a null install path.
*/
public static function getInstallPath($packageName)
{
foreach (self::getInstalled() as $installed) {
if (!isset($installed['versions'][$packageName])) {
continue;
}
return isset($installed['versions'][$packageName]['install_path']) ? $installed['versions'][$packageName]['install_path'] : null;
}
throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed');
}
/**
* @return array
* @psalm-return array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}
*/
public static function getRootPackage()
{
$installed = self::getInstalled();
return $installed[0]['root'];
}
/**
* Returns the raw installed.php data for custom implementations
*
* @deprecated Use getAllRawData() instead which returns all datasets for all autoloaders present in the process. getRawData only returns the first dataset loaded, which may not be what you expect.
* @return array[]
* @psalm-return array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>}
*/
public static function getRawData()
{
@trigger_error('getRawData only returns the first dataset loaded, which may not be what you expect. Use getAllRawData() instead which returns all datasets for all autoloaders present in the process.', E_USER_DEPRECATED);
if (null === self::$installed) {
// only require the installed.php file if this file is loaded from its dumped location,
// and not from its source location in the composer/composer package, see https://github.com/composer/composer/issues/9937
if (substr(__DIR__, -8, 1) !== 'C') {
self::$installed = include __DIR__ . '/installed.php';
} else {
self::$installed = array();
}
}
return self::$installed;
}
/**
* Returns the raw data of all installed.php which are currently loaded for custom implementations
*
* @return array[]
* @psalm-return list<array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>}>
*/
public static function getAllRawData()
{
return self::getInstalled();
}
/**
* Lets you reload the static array from another file
*
* This is only useful for complex integrations in which a project needs to use
* this class but then also needs to execute another project's autoloader in process,
* and wants to ensure both projects have access to their version of installed.php.
*
* A typical case would be PHPUnit, where it would need to make sure it reads all
* the data it needs from this class, then call reload() with
* `require $CWD/vendor/composer/installed.php` (or similar) as input to make sure
* the project in which it runs can then also use this class safely, without
* interference between PHPUnit's dependencies and the project's dependencies.
*
* @param array[] $data A vendor/composer/installed.php data set
* @return void
*
* @psalm-param array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>} $data
*/
public static function reload($data)
{
self::$installed = $data;
self::$installedByVendor = array();
}
/**
* @return array[]
* @psalm-return list<array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>}>
*/
private static function getInstalled()
{
if (null === self::$canGetVendors) {
self::$canGetVendors = method_exists('Composer\Autoload\ClassLoader', 'getRegisteredLoaders');
}
$installed = array();
$copiedLocalDir = false;
if (self::$canGetVendors) {
foreach (ClassLoader::getRegisteredLoaders() as $vendorDir => $loader) {
if (isset(self::$installedByVendor[$vendorDir])) {
$installed[] = self::$installedByVendor[$vendorDir];
} elseif (is_file($vendorDir.'/composer/installed.php')) {
/** @var array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>} $required */
$required = require $vendorDir.'/composer/installed.php';
self::$installedByVendor[$vendorDir] = $required;
$installed[] = $required;
if (strtr($vendorDir.'/composer', '\\', '/') === strtr(__DIR__, '\\', '/')) {
self::$installed = $required;
$copiedLocalDir = true;
}
}
}
}
if (null === self::$installed) {
// only require the installed.php file if this file is loaded from its dumped location,
// and not from its source location in the composer/composer package, see https://github.com/composer/composer/issues/9937
if (substr(__DIR__, -8, 1) !== 'C') {
/** @var array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>} $required */
$required = require __DIR__ . '/installed.php';
self::$installed = $required;
} else {
self::$installed = array();
}
}
if (self::$installed !== array() && !$copiedLocalDir) {
$installed[] = self::$installed;
}
return $installed;
}
}

3364
vendor/composer/autoload_classmap.php vendored Normal file

File diff suppressed because it is too large Load Diff

27
vendor/composer/autoload_files.php vendored Normal file
View File

@@ -0,0 +1,27 @@
<?php
// autoload_files.php @generated by Composer
$vendorDir = dirname(__DIR__);
$baseDir = dirname($vendorDir);
return array(
'0e6d7bf4a5811bfa5cf40c5ccd6fae6a' => $vendorDir . '/symfony/polyfill-mbstring/bootstrap.php',
'023d27dca8066ef29e6739335ea73bad' => $vendorDir . '/symfony/polyfill-php70/bootstrap.php',
'a4a119a56e50fbb293281d9a48007e0e' => $vendorDir . '/symfony/polyfill-php80/bootstrap.php',
'5897ea0ac4cccf14d323035e65887801' => $vendorDir . '/symfony/polyfill-php82/bootstrap.php',
'320cde22f66dd4f5d3fd621d3e88b98f' => $vendorDir . '/symfony/polyfill-ctype/bootstrap.php',
'667aeda72477189d0494fecd327c3641' => $vendorDir . '/symfony/var-dumper/Resources/functions/dump.php',
'2cffec82183ee1cea088009cef9a6fc3' => $vendorDir . '/ezyang/htmlpurifier/library/HTMLPurifier.composer.php',
'801c31d8ed748cfa537fa45402288c95' => $vendorDir . '/psy/psysh/src/functions.php',
'e39a8b23c42d4e1452234d762b03835a' => $vendorDir . '/ramsey/uuid/src/functions.php',
'e91d0dc994644828154ae2387ede1ca8' => $vendorDir . '/spatie/string/src/string_functions.php',
'2c102faa651ef8ea5874edb585946bce' => $vendorDir . '/swiftmailer/swiftmailer/lib/swift_required.php',
'f0906e6318348a765ffb6eb24e0d0938' => $vendorDir . '/laravel/framework/src/Illuminate/Foundation/helpers.php',
'58571171fd5812e6e447dce228f52f4d' => $vendorDir . '/laravel/framework/src/Illuminate/Support/helpers.php',
'cb61d74ad51d00867155534456b38b23' => $vendorDir . '/mews/purifier/src/helpers.php',
'9f394da3192a168c4633675768d80428' => $vendorDir . '/nwidart/laravel-modules/src/helpers.php',
'd7354eb4c8441fbf08eec280b61c7c73' => $vendorDir . '/rachidlaasri/laravel-installer/src/Helpers/functions.php',
'72b1e3f4a2af9b30b3f137b3ec2057fc' => $vendorDir . '/spatie/laravel-activitylog/src/helpers.php',
'b3709fe79d9d3d527d2a936c35802426' => $baseDir . '/app/Misc/Functions.php',
);

15
vendor/composer/autoload_namespaces.php vendored Normal file
View File

@@ -0,0 +1,15 @@
<?php
// autoload_namespaces.php @generated by Composer
$vendorDir = dirname(__DIR__);
$baseDir = dirname($vendorDir);
return array(
'Swift_' => array($baseDir . '/overrides/swiftmailer/swiftmailer/lib/classes'),
'Rap2hpoutre\\LaravelLogViewer\\' => array($vendorDir . '/rap2hpoutre/laravel-log-viewer/src'),
'Parsedown' => array($vendorDir . '/erusev/parsedown'),
'JShrink' => array($vendorDir . '/tedivm/jshrink/src'),
'HTMLPurifier' => array($vendorDir . '/ezyang/htmlpurifier/library'),
'Doctrine\\Common\\Lexer\\' => array($vendorDir . '/doctrine/lexer/lib'),
);

178
vendor/composer/autoload_psr4.php vendored Normal file
View File

@@ -0,0 +1,178 @@
<?php
// autoload_psr4.php @generated by Composer
$vendorDir = dirname(__DIR__);
$baseDir = dirname($vendorDir);
return array(
'enshrined\\svgSanitize\\' => array($vendorDir . '/enshrined/svg-sanitize/src'),
'XdgBaseDir\\' => array($vendorDir . '/dnoegel/php-xdg-base-dir/src'),
'Whoops\\Util\\' => array($baseDir . '/overrides/filp/whoops/src/Whoops/Util'),
'Whoops\\Handler\\' => array($baseDir . '/overrides/filp/whoops/src/Whoops/Handler'),
'Whoops\\' => array($baseDir . '/overrides/filp/whoops/src/Whoops'),
'Webklex\\PHPIMAP\\' => array($baseDir . '/overrides/webklex/php-imap/src', $vendorDir . '/webklex/php-imap/src'),
'Watson\\Rememberable\\' => array($vendorDir . '/watson/rememberable/src'),
'Underscore\\' => array($vendorDir . '/anahkiasen/underscore-php/src', $vendorDir . '/anahkiasen/underscore-php/tests'),
'TorMorten\\Eventy\\' => array($baseDir . '/overrides/tormjens/eventy/src', $vendorDir . '/tormjens/eventy/src'),
'TijsVerkoyen\\CssToInlineStyles\\Css\\Property\\' => array($baseDir . '/overrides/tijsverkoyen/css-to-inline-styles/src/Css/Property'),
'TijsVerkoyen\\CssToInlineStyles\\' => array($baseDir . '/overrides/tijsverkoyen/css-to-inline-styles/src', $vendorDir . '/tijsverkoyen/css-to-inline-styles/src'),
'Symfony\\Polyfill\\Php82\\' => array($vendorDir . '/symfony/polyfill-php82'),
'Symfony\\Polyfill\\Php80\\' => array($vendorDir . '/symfony/polyfill-php80'),
'Symfony\\Polyfill\\Php70\\' => array($vendorDir . '/symfony/polyfill-php70'),
'Symfony\\Polyfill\\Mbstring\\' => array($vendorDir . '/symfony/polyfill-mbstring'),
'Symfony\\Polyfill\\Ctype\\' => array($vendorDir . '/symfony/polyfill-ctype'),
'Symfony\\Component\\VarDumper\\Dumper\\' => array($baseDir . '/overrides/symfony/var-dumper/Dumper'),
'Symfony\\Component\\VarDumper\\Cloner\\' => array($baseDir . '/overrides/symfony/var-dumper/Cloner'),
'Symfony\\Component\\VarDumper\\' => array($vendorDir . '/symfony/var-dumper'),
'Symfony\\Component\\Translation\\Loader\\' => array($baseDir . '/overrides/symfony/translation/Loader'),
'Symfony\\Component\\Translation\\Formatter\\' => array($baseDir . '/overrides/symfony/translation/Formatter'),
'Symfony\\Component\\Translation\\' => array($baseDir . '/overrides/symfony/translation', $vendorDir . '/symfony/translation'),
'Symfony\\Component\\Routing\\Generator\\' => array($baseDir . '/overrides/symfony/routing/generator'),
'Symfony\\Component\\Routing\\' => array($baseDir . '/overrides/symfony/routing', $vendorDir . '/symfony/routing'),
'Symfony\\Component\\Process\\' => array($baseDir . '/overrides/symfony/process', $vendorDir . '/symfony/process'),
'Symfony\\Component\\HttpKernel\\HttpCache\\' => array($baseDir . '/overrides/symfony/http-kernel/HttpCache'),
'Symfony\\Component\\HttpKernel\\Exception\\' => array($baseDir . '/overrides/symfony/http-kernel/Exception'),
'Symfony\\Component\\HttpKernel\\' => array($baseDir . '/overrides/symfony/http-kernel', $vendorDir . '/symfony/http-kernel'),
'Symfony\\Component\\HttpFoundation\\File\\MimeType\\' => array($baseDir . '/overrides/symfony/http-foundation/File/MimeType'),
'Symfony\\Component\\HttpFoundation\\' => array($baseDir . '/overrides/symfony/http-foundation', $vendorDir . '/symfony/http-foundation'),
'Symfony\\Component\\Finder\\Iterator\\' => array($baseDir . '/overrides/symfony/finder/Iterator'),
'Symfony\\Component\\Finder\\' => array($baseDir . '/overrides/symfony/finder', $vendorDir . '/symfony/finder'),
'Symfony\\Component\\EventDispatcher\\' => array($vendorDir . '/symfony/event-dispatcher'),
'Symfony\\Component\\Debug\\Exception\\' => array($baseDir . '/overrides/symfony/debug/Exception'),
'Symfony\\Component\\Debug\\' => array($baseDir . '/overrides/symfony/debug', $vendorDir . '/symfony/debug'),
'Symfony\\Component\\CssSelector\\XPath\\Extension\\' => array($baseDir . '/overrides/symfony/css-selector/XPath/Extension'),
'Symfony\\Component\\CssSelector\\XPath\\' => array($baseDir . '/overrides/symfony/css-selector/XPath'),
'Symfony\\Component\\CssSelector\\Parser\\' => array($baseDir . '/overrides/symfony/css-selector/Parser'),
'Symfony\\Component\\CssSelector\\' => array($vendorDir . '/symfony/css-selector'),
'Symfony\\Component\\Console\\Question\\' => array($baseDir . '/overrides/symfony/console'),
'Symfony\\Component\\Console\\Output\\' => array($baseDir . '/overrides/symfony/console/Output'),
'Symfony\\Component\\Console\\Input\\' => array($baseDir . '/overrides/symfony/console/Input'),
'Symfony\\Component\\Console\\Helper\\' => array($baseDir . '/overrides/symfony/console/Helper'),
'Symfony\\Component\\Console\\Formatter\\' => array($baseDir . '/overrides/symfony/console/Formatter'),
'Symfony\\Component\\Console\\Exception\\' => array($baseDir . '/overrides/symfony/console/Exception'),
'Symfony\\Component\\Console\\Descriptor\\' => array($baseDir . '/overrides/symfony/console/Descriptor'),
'Symfony\\Component\\Console\\Command\\' => array($baseDir . '/overrides/symfony/console/Command'),
'Symfony\\Component\\Console\\' => array($baseDir . '/overrides/symfony/console', $vendorDir . '/symfony/console'),
'Spatie\\String\\' => array($baseDir . '/overrides/spatie/string/src', $vendorDir . '/spatie/string/src'),
'Spatie\\Activitylog\\' => array($vendorDir . '/spatie/laravel-activitylog/src'),
'Rap2hpoutre\\LaravelLogViewer\\' => array($baseDir . '/overrides/rap2hpoutre/laravel-log-viewer/src/Rap2hpoutre/LaravelLogViewer'),
'Ramsey\\Uuid\\' => array($baseDir . '/overrides/ramsey/uuid/src', $vendorDir . '/ramsey/uuid/src'),
'RachidLaasri\\LaravelInstaller\\Providers\\' => array($baseDir . '/overrides/rachidlaasri/laravel-installer/src/Providers'),
'RachidLaasri\\LaravelInstaller\\Middleware\\' => array($baseDir . '/overrides/rachidlaasri/laravel-installer/src/Middleware'),
'RachidLaasri\\LaravelInstaller\\Helpers\\' => array($baseDir . '/overrides/rachidlaasri/laravel-installer/src/Helpers'),
'RachidLaasri\\LaravelInstaller\\Events\\' => array($baseDir . '/overrides/rachidlaasri/laravel-installer/src/Events'),
'RachidLaasri\\LaravelInstaller\\Controllers\\' => array($baseDir . '/overrides/rachidlaasri/laravel-installer/src/Controllers'),
'RachidLaasri\\LaravelInstaller\\' => array($vendorDir . '/rachidlaasri/laravel-installer/src'),
'Psy\\VarDumper\\' => array($baseDir . '/overrides/psy/psysh/src/VarDumper'),
'Psy\\TimeitCommand\\' => array($baseDir . '/overrides/psy/psysh/src/TimeitCommand'),
'Psy\\Output\\' => array($baseDir . '/overrides/psy/psysh/src/Output'),
'Psy\\Input\\' => array($baseDir . '/overrides/psy/psysh/src/Input'),
'Psy\\Exception\\' => array($baseDir . '/overrides/psy/psysh/src/ErrorException'),
'Psy\\Command\\ListCommand\\' => array($baseDir . '/overrides/psy/psysh/src/Command/ListCommand'),
'Psy\\Command\\' => array($baseDir . '/overrides/psy/psysh/src/Command'),
'Psy\\' => array($baseDir . '/overrides/psy/psysh/src', $vendorDir . '/psy/psysh/src'),
'Psr\\SimpleCache\\' => array($vendorDir . '/psr/simple-cache/src'),
'Psr\\Log\\' => array($vendorDir . '/psr/log/Psr/Log'),
'Psr\\Http\\Message\\' => array($vendorDir . '/psr/http-factory/src', $vendorDir . '/psr/http-message/src'),
'Psr\\Http\\Client\\' => array($vendorDir . '/psr/http-client/src'),
'Psr\\Container\\' => array($vendorDir . '/psr/container/src'),
'PhpParser\\' => array($vendorDir . '/nikic/php-parser/lib/PhpParser'),
'Patchwork\\' => array($vendorDir . '/patchwork/utf8/src/Patchwork'),
'PHPUnit\\Util\\Xml\\' => array($baseDir . '/overrides/phpunit/phpunit/src/Util/Xml'),
'PHPUnit\\Util\\PHP\\' => array($baseDir . '/overrides/phpunit/phpunit/src/Util/PHP'),
'PHPUnit\\Runner\\' => array($baseDir . '/overrides/phpunit/phpunit/src/Runner'),
'Nwidart\\Modules\\Generators\\' => array($baseDir . '/overrides/nwidart/laravel-modules/src/Generators'),
'Nwidart\\Modules\\' => array($baseDir . '/overrides/nwidart/laravel-modules/src', $vendorDir . '/nwidart/laravel-modules/src'),
'Monolog\\' => array($vendorDir . '/monolog/monolog/src/Monolog'),
'Modules\\' => array($baseDir . '/Modules'),
'Mews\\Purifier\\' => array($vendorDir . '/mews/purifier/src'),
'Lord\\Laroute\\Routes\\' => array($baseDir . '/overrides/lord/laroute/src/Routes'),
'Lord\\Laroute\\' => array($vendorDir . '/lord/laroute/src'),
'League\\MimeTypeDetection\\' => array($vendorDir . '/league/mime-type-detection/src'),
'League\\Flysystem\\' => array($baseDir . '/overrides/league/flysystem/src', $vendorDir . '/league/flysystem/src'),
'Laravel\\Tinker\\' => array($vendorDir . '/laravel/tinker/src'),
'Javoscript\\MacroableModels\\' => array($baseDir . '/overrides/javoscript/laravel-macroable-models/src', $vendorDir . '/javoscript/laravel-macroable-models/src'),
'JakubOnderka\\PhpConsoleHighlighter\\' => array($vendorDir . '/jakub-onderka/php-console-highlighter/src'),
'JakubOnderka\\PhpConsoleColor\\' => array($vendorDir . '/jakub-onderka/php-console-color/src'),
'Illuminate\\View\\Concerns\\' => array($baseDir . '/overrides/laravel/framework/src/Illuminate/View/Concerns'),
'Illuminate\\View\\Compilers\\Concerns\\' => array($baseDir . '/overrides/laravel/framework/src/Illuminate/View/Compilers/Concerns'),
'Illuminate\\View\\Compilers\\' => array($baseDir . '/overrides/laravel/framework/src/Illuminate/View/Compilers'),
'Illuminate\\View\\' => array($baseDir . '/overrides/laravel/framework/src/Illuminate/View'),
'Illuminate\\Validation\\Concerns\\' => array($baseDir . '/overrides/laravel/framework/src/Illuminate/Validation/Concerns'),
'Illuminate\\Validation\\' => array($baseDir . '/overrides/laravel/framework/src/Illuminate/Validation'),
'Illuminate\\Support\\' => array($baseDir . '/overrides/laravel/framework/src/Illuminate/Support'),
'Illuminate\\Session\\Middleware\\' => array($baseDir . '/overrides/laravel/framework/src/Illuminate/Session/Middleware'),
'Illuminate\\Session\\' => array($baseDir . '/overrides/laravel/framework/src/Illuminate/Session'),
'Illuminate\\Routing\\' => array($baseDir . '/overrides/laravel/framework/src/Illuminate/Routing'),
'Illuminate\\Queue\\' => array($baseDir . '/overrides/laravel/framework/src/Illuminate/Queue'),
'Illuminate\\Pipeline\\' => array($baseDir . '/overrides/laravel/framework/src/Illuminate/Pipeline'),
'Illuminate\\Pagination\\' => array($baseDir . '/overrides/laravel/framework/src/Illuminate/Pagination'),
'Illuminate\\Notifications\\' => array($baseDir . '/overrides/laravel/framework/src/Illuminate/Notifications'),
'Illuminate\\Mail\\' => array($baseDir . '/overrides/laravel/framework/src/Illuminate/Mail'),
'Illuminate\\Log\\' => array($baseDir . '/overrides/laravel/framework/src/Illuminate/Log'),
'Illuminate\\Http\\Exceptions\\' => array($baseDir . '/overrides/laravel/framework/src/Illuminate/Http/Exceptions'),
'Illuminate\\Http\\' => array($baseDir . '/overrides/laravel/framework/src/Illuminate/Http'),
'Illuminate\\Foundation\\Testing\\' => array($baseDir . '/overrides/laravel/framework/src/Illuminate/Foundation/Testing'),
'Illuminate\\Foundation\\Http\\Middleware\\' => array($baseDir . '/overrides/laravel/framework/src/Illuminate/Foundation/Http/Middleware'),
'Illuminate\\Foundation\\Bootstrap\\' => array($baseDir . '/overrides/laravel/framework/src/Illuminate/Foundation/Bootstrap'),
'Illuminate\\Foundation\\' => array($baseDir . '/overrides/laravel/framework/src/Illuminate/Foundation'),
'Illuminate\\Filesystem\\' => array($baseDir . '/overrides/laravel/framework/src/Illuminate/Filesystem'),
'Illuminate\\Events\\' => array($baseDir . '/overrides/laravel/framework/src/Illuminate/Events'),
'Illuminate\\Database\\Schema\\' => array($baseDir . '/overrides/laravel/framework/src/Illuminate/Database/Schema'),
'Illuminate\\Database\\Query\\' => array($baseDir . '/overrides/laravel/framework/src/Illuminate/Database/Query'),
'Illuminate\\Database\\Eloquent\\Relations\\' => array($baseDir . '/overrides/laravel/framework/src/Illuminate/Database/Eloquent/Relations'),
'Illuminate\\Database\\Eloquent\\Concerns\\' => array($baseDir . '/overrides/laravel/framework/src/Illuminate/Database/Eloquent/Concerns'),
'Illuminate\\Database\\Eloquent\\' => array($baseDir . '/overrides/laravel/framework/src/Illuminate/Database/Eloquent'),
'Illuminate\\Database\\' => array($baseDir . '/overrides/laravel/framework/src/Illuminate/Database'),
'Illuminate\\Cookie\\Middleware\\' => array($baseDir . '/overrides/laravel/framework/src/Illuminate/Cookie/Middleware'),
'Illuminate\\Cookie\\' => array($baseDir . '/overrides/laravel/framework/src/Illuminate/Cookie'),
'Illuminate\\Contracts\\Container\\' => array($baseDir . '/overrides/laravel/framework/src/Illuminate/Contracts/Container'),
'Illuminate\\Container\\' => array($baseDir . '/overrides/laravel/framework/src/Illuminate/Container'),
'Illuminate\\Console\\' => array($baseDir . '/overrides/laravel/framework/src/Illuminate/Console'),
'Illuminate\\Config\\' => array($baseDir . '/overrides/laravel/framework/src/Illuminate/Config'),
'Illuminate\\Cache\\Console\\' => array($baseDir . '/overrides/laravel/framework/src/Illuminate/Cache/Console'),
'Illuminate\\Cache\\' => array($baseDir . '/overrides/laravel/framework/src/Illuminate/Cache'),
'Illuminate\\Bus\\' => array($baseDir . '/overrides/laravel/framework/src/Illuminate/Bus'),
'Illuminate\\Broadcasting\\Broadcasters\\' => array($baseDir . '/overrides/laravel/framework/src/Illuminate/Broadcasting/Broadcasters'),
'Illuminate\\Broadcasting\\' => array($baseDir . '/overrides/laravel/framework/src/Illuminate/Broadcasting'),
'Illuminate\\Auth\\Middleware\\' => array($baseDir . '/overrides/laravel/framework/src/Illuminate/Auth/Middleware'),
'Illuminate\\Auth\\Access\\' => array($baseDir . '/overrides/laravel/framework/src/Illuminate/Auth/Access'),
'Illuminate\\Auth\\' => array($baseDir . '/overrides/laravel/framework/src/Illuminate/Auth'),
'Illuminate\\' => array($vendorDir . '/laravel/framework/src/Illuminate'),
'Html2Text\\' => array($baseDir . '/overrides/html2text/html2text/src', $vendorDir . '/html2text/html2text/src', $vendorDir . '/html2text/html2text/test'),
'GuzzleHttp\\Psr7\\' => array($vendorDir . '/guzzlehttp/psr7/src'),
'GuzzleHttp\\Promise\\' => array($vendorDir . '/guzzlehttp/promises/src'),
'GuzzleHttp\\' => array($vendorDir . '/guzzlehttp/guzzle/src'),
'Fideloper\\Proxy\\' => array($vendorDir . '/fideloper/proxy/src'),
'Faker\\Provider\\' => array($baseDir . '/overrides/fzaninotto/faker/src/Faker/Provider'),
'Egulias\\EmailValidator\\' => array($vendorDir . '/egulias/email-validator/EmailValidator'),
'Dotenv\\' => array($baseDir . '/overrides/vlucas/phpdotenv/src', $vendorDir . '/vlucas/phpdotenv/src'),
'Doctrine\\Deprecations\\' => array($vendorDir . '/doctrine/deprecations/src'),
'Doctrine\\DBAL\\Schema\\' => array($baseDir . '/overrides/doctrine/dbal/lib/Doctrine/DBAL/Schema'),
'Doctrine\\DBAL\\Platforms\\' => array($baseDir . '/overrides/doctrine/dbal/lib/Doctrine/DBAL/Platforms'),
'Doctrine\\DBAL\\Driver\\' => array($baseDir . '/overrides/doctrine/dbal/lib/Doctrine/DBAL/Driver'),
'Doctrine\\DBAL\\' => array($vendorDir . '/doctrine/dbal/lib/Doctrine/DBAL'),
'Doctrine\\Common\\Inflector\\' => array($vendorDir . '/doctrine/inflector/lib/Doctrine/Common/Inflector'),
'Doctrine\\Common\\Cache\\' => array($vendorDir . '/doctrine/cache/lib/Doctrine/Common/Cache'),
'Doctrine\\Common\\' => array($vendorDir . '/doctrine/event-manager/src'),
'Devfactory\\Minify\\Providers\\' => array($baseDir . '/overrides/devfactory/minify/src/Providers'),
'Devfactory\\Minify\\' => array($vendorDir . '/devfactory/minify/src'),
'DebugBar\\DataFormatter\\' => array($baseDir . '/overrides/maximebf/debugbar/src/DataFormatter/DataFormatter'),
'DebugBar\\DataCollector\\PDO\\' => array($baseDir . '/overrides/maximebf/debugbar/src/DataFormatter/DataCollector/PDO'),
'DebugBar\\' => array($baseDir . '/overrides/maximebf/debugbar/src/DebugBar'),
'Cron\\' => array($baseDir . '/overrides/mtdowling/cron-expression/src/Cron', $vendorDir . '/mtdowling/cron-expression/src/Cron'),
'Codedge\\Updater\\SourceRepositoryTypes\\' => array($baseDir . '/overrides/codedge/laravel-selfupdater/src/SourceRepositoryTypes'),
'Codedge\\Updater\\' => array($vendorDir . '/codedge/laravel-selfupdater/src'),
'Chumper\\Zipper\\Repositories\\' => array($baseDir . '/overrides/chumper/zipper/src/Chumper/Zipper/Repositories'),
'Chumper\\Zipper\\' => array($baseDir . '/overrides/chumper/zipper/src/Chumper/Zipper', $vendorDir . '/chumper/zipper/src/Chumper/Zipper'),
'Carbon\\' => array($baseDir . '/overrides/nesbot/carbon/src/Carbon'),
'Barryvdh\\TranslationManager\\' => array($baseDir . '/overrides/barryvdh/laravel-translation-manager/src', $vendorDir . '/barryvdh/laravel-translation-manager/src'),
'Barryvdh\\Debugbar\\DataFormatter\\' => array($baseDir . '/overrides/barryvdh/laravel-debugbar/src/DataFormatter'),
'Barryvdh\\Debugbar\\DataCollector\\' => array($baseDir . '/overrides/barryvdh/laravel-debugbar/src/DataCollector'),
'Barryvdh\\Debugbar\\' => array($baseDir . '/overrides/barryvdh/laravel-debugbar/src'),
'Axn\\Laroute\\Routes\\' => array($baseDir . '/overrides/axn/laravel-laroute/src/Routes'),
'Axn\\Laroute\\' => array($vendorDir . '/axn/laravel-laroute/src'),
'App\\' => array($baseDir . '/app'),
'' => array($vendorDir . '/nesbot/carbon/src'),
);

48
vendor/composer/autoload_real.php vendored Normal file
View File

@@ -0,0 +1,48 @@
<?php
// autoload_real.php @generated by Composer
class ComposerAutoloaderInitbf8dc242a640d7c740f283f226d0bdb4
{
private static $loader;
public static function loadClassLoader($class)
{
if ('Composer\Autoload\ClassLoader' === $class) {
require __DIR__ . '/ClassLoader.php';
}
}
/**
* @return \Composer\Autoload\ClassLoader
*/
public static function getLoader()
{
if (null !== self::$loader) {
return self::$loader;
}
spl_autoload_register(array('ComposerAutoloaderInitbf8dc242a640d7c740f283f226d0bdb4', 'loadClassLoader'), true, true);
self::$loader = $loader = new \Composer\Autoload\ClassLoader(\dirname(__DIR__));
spl_autoload_unregister(array('ComposerAutoloaderInitbf8dc242a640d7c740f283f226d0bdb4', 'loadClassLoader'));
require __DIR__ . '/autoload_static.php';
call_user_func(\Composer\Autoload\ComposerStaticInitbf8dc242a640d7c740f283f226d0bdb4::getInitializer($loader));
$loader->register(true);
$filesToLoad = \Composer\Autoload\ComposerStaticInitbf8dc242a640d7c740f283f226d0bdb4::$files;
$requireFile = \Closure::bind(static function ($fileIdentifier, $file) {
if (empty($GLOBALS['__composer_autoload_files'][$fileIdentifier])) {
$GLOBALS['__composer_autoload_files'][$fileIdentifier] = true;
require $file;
}
}, null, null);
foreach ($filesToLoad as $fileIdentifier => $file) {
$requireFile($fileIdentifier, $file);
}
return $loader;
}
}

4382
vendor/composer/autoload_static.php vendored Normal file

File diff suppressed because it is too large Load Diff

5128
vendor/composer/installed.json vendored Normal file

File diff suppressed because it is too large Load Diff

894
vendor/composer/installed.php vendored Normal file
View File

@@ -0,0 +1,894 @@
<?php return array(
'root' => array(
'name' => 'freescout-helpdesk/freescout',
'pretty_version' => 'dev-master',
'version' => 'dev-master',
'reference' => '63b008c6d23ab8d8a78ccf0a616c83901250ce8e',
'type' => 'library',
'install_path' => __DIR__ . '/../../',
'aliases' => array(),
'dev' => false,
),
'versions' => array(
'anahkiasen/underscore-php' => array(
'pretty_version' => '2.0.0',
'version' => '2.0.0.0',
'reference' => '48f97b295c82d99c1fe10d8b0684c43f051b5580',
'type' => 'library',
'install_path' => __DIR__ . '/../anahkiasen/underscore-php',
'aliases' => array(),
'dev_requirement' => false,
),
'axn/laravel-laroute' => array(
'pretty_version' => '1.3.0',
'version' => '1.3.0.0',
'reference' => '40ccb656a5ca380c4cd7de7f80667f1d6cd9aeeb',
'type' => 'library',
'install_path' => __DIR__ . '/../axn/laravel-laroute',
'aliases' => array(),
'dev_requirement' => false,
),
'barryvdh/laravel-translation-manager' => array(
'pretty_version' => 'v0.5.0',
'version' => '0.5.0.0',
'reference' => '857334ea6ffa2511982442495460c9c3ff096160',
'type' => 'library',
'install_path' => __DIR__ . '/../barryvdh/laravel-translation-manager',
'aliases' => array(),
'dev_requirement' => false,
),
'chumper/zipper' => array(
'pretty_version' => 'v1.0.2',
'version' => '1.0.2.0',
'reference' => '6a1733c34d67c3952b8439afb36ad4ea5c3ceacb',
'type' => 'library',
'install_path' => __DIR__ . '/../chumper/zipper',
'aliases' => array(),
'dev_requirement' => false,
),
'codedge/laravel-selfupdater' => array(
'pretty_version' => 'dev-customized',
'version' => 'dev-customized',
'reference' => 'e80eefef4666d8882e510e55e1bbc5aa4844affb',
'type' => 'library',
'install_path' => __DIR__ . '/../codedge/laravel-selfupdater',
'aliases' => array(),
'dev_requirement' => false,
),
'devfactory/minify' => array(
'pretty_version' => '1.0.7',
'version' => '1.0.7.0',
'reference' => '95d518081aa29c91b8c89243c61a7b1fc726120e',
'type' => 'library',
'install_path' => __DIR__ . '/../devfactory/minify',
'aliases' => array(),
'dev_requirement' => false,
),
'dnoegel/php-xdg-base-dir' => array(
'pretty_version' => 'v0.1.1',
'version' => '0.1.1.0',
'reference' => '8f8a6e48c5ecb0f991c2fdcf5f154a47d85f9ffd',
'type' => 'library',
'install_path' => __DIR__ . '/../dnoegel/php-xdg-base-dir',
'aliases' => array(),
'dev_requirement' => false,
),
'doctrine/cache' => array(
'pretty_version' => 'v1.6.2',
'version' => '1.6.2.0',
'reference' => 'eb152c5100571c7a45470ff2a35095ab3f3b900b',
'type' => 'library',
'install_path' => __DIR__ . '/../doctrine/cache',
'aliases' => array(),
'dev_requirement' => false,
),
'doctrine/dbal' => array(
'pretty_version' => '2.12.1',
'version' => '2.12.1.0',
'reference' => 'adce7a954a1c2f14f85e94aed90c8489af204086',
'type' => 'library',
'install_path' => __DIR__ . '/../doctrine/dbal',
'aliases' => array(),
'dev_requirement' => false,
),
'doctrine/deprecations' => array(
'pretty_version' => '1.1.6',
'version' => '1.1.6.0',
'reference' => 'd4fe3e6fd9bb9e72557a19674f44d8ac7db4c6ca',
'type' => 'library',
'install_path' => __DIR__ . '/../doctrine/deprecations',
'aliases' => array(),
'dev_requirement' => false,
),
'doctrine/event-manager' => array(
'pretty_version' => '1.2.0',
'version' => '1.2.0.0',
'reference' => '95aa4cb529f1e96576f3fda9f5705ada4056a520',
'type' => 'library',
'install_path' => __DIR__ . '/../doctrine/event-manager',
'aliases' => array(),
'dev_requirement' => false,
),
'doctrine/inflector' => array(
'pretty_version' => 'v1.2.0',
'version' => '1.2.0.0',
'reference' => 'e11d84c6e018beedd929cff5220969a3c6d1d462',
'type' => 'library',
'install_path' => __DIR__ . '/../doctrine/inflector',
'aliases' => array(),
'dev_requirement' => false,
),
'doctrine/lexer' => array(
'pretty_version' => 'v1.0.1',
'version' => '1.0.1.0',
'reference' => '83893c552fd2045dd78aef794c31e694c37c0b8c',
'type' => 'library',
'install_path' => __DIR__ . '/../doctrine/lexer',
'aliases' => array(),
'dev_requirement' => false,
),
'egulias/email-validator' => array(
'pretty_version' => '2.1.10',
'version' => '2.1.10.0',
'reference' => 'a6c8d7101b19a451c1707b1b79bbbc56e4bdb7ec',
'type' => 'library',
'install_path' => __DIR__ . '/../egulias/email-validator',
'aliases' => array(),
'dev_requirement' => false,
),
'enshrined/svg-sanitize' => array(
'pretty_version' => '0.22.0',
'version' => '0.22.0.0',
'reference' => '0afa95ea74be155a7bcd6c6fb60c276c39984500',
'type' => 'library',
'install_path' => __DIR__ . '/../enshrined/svg-sanitize',
'aliases' => array(),
'dev_requirement' => false,
),
'erusev/parsedown' => array(
'pretty_version' => 'v1.7.2',
'version' => '1.7.2.0',
'reference' => 'd60bcdc46978357759ecb13cb4b078da783f8faf',
'type' => 'library',
'install_path' => __DIR__ . '/../erusev/parsedown',
'aliases' => array(),
'dev_requirement' => false,
),
'ezyang/htmlpurifier' => array(
'pretty_version' => 'v4.19.0',
'version' => '4.19.0.0',
'reference' => 'b287d2a16aceffbf6e0295559b39662612b77fcf',
'type' => 'library',
'install_path' => __DIR__ . '/../ezyang/htmlpurifier',
'aliases' => array(),
'dev_requirement' => false,
),
'fideloper/proxy' => array(
'pretty_version' => '3.3.4',
'version' => '3.3.4.0',
'reference' => '9cdf6f118af58d89764249bbcc7bb260c132924f',
'type' => 'library',
'install_path' => __DIR__ . '/../fideloper/proxy',
'aliases' => array(),
'dev_requirement' => false,
),
'freescout-helpdesk/freescout' => array(
'pretty_version' => 'dev-master',
'version' => 'dev-master',
'reference' => '63b008c6d23ab8d8a78ccf0a616c83901250ce8e',
'type' => 'library',
'install_path' => __DIR__ . '/../../',
'aliases' => array(),
'dev_requirement' => false,
),
'guzzlehttp/guzzle' => array(
'pretty_version' => '8.0.1',
'version' => '8.0.1.0',
'reference' => '3aeea0406aab88cbbd86531313d7cebf8ae149a4',
'type' => 'library',
'install_path' => __DIR__ . '/../guzzlehttp/guzzle',
'aliases' => array(),
'dev_requirement' => false,
),
'guzzlehttp/promises' => array(
'pretty_version' => '3.0.0',
'version' => '3.0.0.0',
'reference' => 'd961a21387cd680ec1cc6f52aa1fdcef33105e24',
'type' => 'library',
'install_path' => __DIR__ . '/../guzzlehttp/promises',
'aliases' => array(),
'dev_requirement' => false,
),
'guzzlehttp/psr7' => array(
'pretty_version' => '3.0.0',
'version' => '3.0.0.0',
'reference' => 'b094ded77ee97a6027ad6cf0e8c7b9f88381814c',
'type' => 'library',
'install_path' => __DIR__ . '/../guzzlehttp/psr7',
'aliases' => array(),
'dev_requirement' => false,
),
'html2text/html2text' => array(
'pretty_version' => '4.1.0',
'version' => '4.1.0.0',
'reference' => 'bf613dc8d3389d70c891cd847954346acab16574',
'type' => 'library',
'install_path' => __DIR__ . '/../html2text/html2text',
'aliases' => array(),
'dev_requirement' => false,
),
'illuminate/auth' => array(
'dev_requirement' => false,
'replaced' => array(
0 => 'v5.5.40',
),
),
'illuminate/broadcasting' => array(
'dev_requirement' => false,
'replaced' => array(
0 => 'v5.5.40',
),
),
'illuminate/bus' => array(
'dev_requirement' => false,
'replaced' => array(
0 => 'v5.5.40',
),
),
'illuminate/cache' => array(
'dev_requirement' => false,
'replaced' => array(
0 => 'v5.5.40',
),
),
'illuminate/config' => array(
'dev_requirement' => false,
'replaced' => array(
0 => 'v5.5.40',
),
),
'illuminate/console' => array(
'dev_requirement' => false,
'replaced' => array(
0 => 'v5.5.40',
),
),
'illuminate/container' => array(
'dev_requirement' => false,
'replaced' => array(
0 => 'v5.5.40',
),
),
'illuminate/contracts' => array(
'dev_requirement' => false,
'replaced' => array(
0 => 'v5.5.40',
),
),
'illuminate/cookie' => array(
'dev_requirement' => false,
'replaced' => array(
0 => 'v5.5.40',
),
),
'illuminate/database' => array(
'dev_requirement' => false,
'replaced' => array(
0 => 'v5.5.40',
),
),
'illuminate/encryption' => array(
'dev_requirement' => false,
'replaced' => array(
0 => 'v5.5.40',
),
),
'illuminate/events' => array(
'dev_requirement' => false,
'replaced' => array(
0 => 'v5.5.40',
),
),
'illuminate/filesystem' => array(
'dev_requirement' => false,
'replaced' => array(
0 => 'v5.5.40',
),
),
'illuminate/hashing' => array(
'dev_requirement' => false,
'replaced' => array(
0 => 'v5.5.40',
),
),
'illuminate/http' => array(
'dev_requirement' => false,
'replaced' => array(
0 => 'v5.5.40',
),
),
'illuminate/log' => array(
'dev_requirement' => false,
'replaced' => array(
0 => 'v5.5.40',
),
),
'illuminate/mail' => array(
'dev_requirement' => false,
'replaced' => array(
0 => 'v5.5.40',
),
),
'illuminate/notifications' => array(
'dev_requirement' => false,
'replaced' => array(
0 => 'v5.5.40',
),
),
'illuminate/pagination' => array(
'dev_requirement' => false,
'replaced' => array(
0 => 'v5.5.40',
),
),
'illuminate/pipeline' => array(
'dev_requirement' => false,
'replaced' => array(
0 => 'v5.5.40',
),
),
'illuminate/queue' => array(
'dev_requirement' => false,
'replaced' => array(
0 => 'v5.5.40',
),
),
'illuminate/redis' => array(
'dev_requirement' => false,
'replaced' => array(
0 => 'v5.5.40',
),
),
'illuminate/routing' => array(
'dev_requirement' => false,
'replaced' => array(
0 => 'v5.5.40',
),
),
'illuminate/session' => array(
'dev_requirement' => false,
'replaced' => array(
0 => 'v5.5.40',
),
),
'illuminate/support' => array(
'dev_requirement' => false,
'replaced' => array(
0 => 'v5.5.40',
),
),
'illuminate/translation' => array(
'dev_requirement' => false,
'replaced' => array(
0 => 'v5.5.40',
),
),
'illuminate/validation' => array(
'dev_requirement' => false,
'replaced' => array(
0 => 'v5.5.40',
),
),
'illuminate/view' => array(
'dev_requirement' => false,
'replaced' => array(
0 => 'v5.5.40',
),
),
'jakub-onderka/php-console-color' => array(
'pretty_version' => 'v0.2',
'version' => '0.2.0.0',
'reference' => 'd5deaecff52a0d61ccb613bb3804088da0307191',
'type' => 'library',
'install_path' => __DIR__ . '/../jakub-onderka/php-console-color',
'aliases' => array(),
'dev_requirement' => false,
),
'jakub-onderka/php-console-highlighter' => array(
'pretty_version' => 'v0.4',
'version' => '0.4.0.0',
'reference' => '9f7a229a69d52506914b4bc61bfdb199d90c5547',
'type' => 'library',
'install_path' => __DIR__ . '/../jakub-onderka/php-console-highlighter',
'aliases' => array(),
'dev_requirement' => false,
),
'javoscript/laravel-macroable-models' => array(
'pretty_version' => '1.0.4',
'version' => '1.0.4.0',
'reference' => '2ade1984f33362c0a304da6352f95c407d5c761f',
'type' => 'library',
'install_path' => __DIR__ . '/../javoscript/laravel-macroable-models',
'aliases' => array(),
'dev_requirement' => false,
),
'laravel/framework' => array(
'pretty_version' => 'v5.5.40',
'version' => '5.5.40.0',
'reference' => 'd724ce0aa61bbd9adf658215eec484f5dd6711d6',
'type' => 'library',
'install_path' => __DIR__ . '/../laravel/framework',
'aliases' => array(),
'dev_requirement' => false,
),
'laravel/tinker' => array(
'pretty_version' => 'v1.0.7',
'version' => '1.0.7.0',
'reference' => 'e3086ee8cb1f54a39ae8dcb72d1c37d10128997d',
'type' => 'library',
'install_path' => __DIR__ . '/../laravel/tinker',
'aliases' => array(),
'dev_requirement' => false,
),
'league/flysystem' => array(
'pretty_version' => '1.1.4',
'version' => '1.1.4.0',
'reference' => 'f3ad69181b8afed2c9edf7be5a2918144ff4ea32',
'type' => 'library',
'install_path' => __DIR__ . '/../league/flysystem',
'aliases' => array(),
'dev_requirement' => false,
),
'league/mime-type-detection' => array(
'pretty_version' => '1.17.0',
'version' => '1.17.0.0',
'reference' => 'f5f47eff7c48ed1003069a2ca67f316fb4021c76',
'type' => 'library',
'install_path' => __DIR__ . '/../league/mime-type-detection',
'aliases' => array(),
'dev_requirement' => false,
),
'lord/laroute' => array(
'pretty_version' => '2.4.7',
'version' => '2.4.7.0',
'reference' => '915501506ee5dfd07b9f9716537a16e1c66d4125',
'type' => 'library',
'install_path' => __DIR__ . '/../lord/laroute',
'aliases' => array(),
'dev_requirement' => false,
),
'mews/purifier' => array(
'pretty_version' => 'dev-customized',
'version' => 'dev-customized',
'reference' => '6ef282797274c62687aa31b5fc74665135bb8e7d',
'type' => 'package',
'install_path' => __DIR__ . '/../mews/purifier',
'aliases' => array(),
'dev_requirement' => false,
),
'monolog/monolog' => array(
'pretty_version' => '1.27.1',
'version' => '1.27.1.0',
'reference' => '904713c5929655dc9b97288b69cfeedad610c9a1',
'type' => 'library',
'install_path' => __DIR__ . '/../monolog/monolog',
'aliases' => array(),
'dev_requirement' => false,
),
'mtdowling/cron-expression' => array(
'pretty_version' => 'v1.2.3',
'version' => '1.2.3.0',
'reference' => '9be552eebcc1ceec9776378f7dcc085246cacca6',
'type' => 'library',
'install_path' => __DIR__ . '/../mtdowling/cron-expression',
'aliases' => array(),
'dev_requirement' => false,
),
'natxet/cssmin' => array(
'pretty_version' => 'v3.0.6',
'version' => '3.0.6.0',
'reference' => 'd5d9f4c3e5cedb1ae96a95a21731f8790e38f1dd',
'type' => 'library',
'install_path' => __DIR__ . '/../natxet/cssmin',
'aliases' => array(),
'dev_requirement' => false,
),
'nesbot/carbon' => array(
'pretty_version' => '1.35.1',
'version' => '1.35.1.0',
'reference' => '5c05a2be472b22f63291d192410df9f0e0de3b19',
'type' => 'library',
'install_path' => __DIR__ . '/../nesbot/carbon',
'aliases' => array(),
'dev_requirement' => false,
),
'nikic/php-parser' => array(
'pretty_version' => 'v4.19.5',
'version' => '4.19.5.0',
'reference' => '51bd93cc741b7fc3d63d20b6bdcd99fdaa359837',
'type' => 'library',
'install_path' => __DIR__ . '/../nikic/php-parser',
'aliases' => array(),
'dev_requirement' => false,
),
'nwidart/laravel-modules' => array(
'pretty_version' => '2.7.0',
'version' => '2.7.0.0',
'reference' => '30c1475f99ef8b439a1cf7d8a9c55787c80bbf71',
'type' => 'library',
'install_path' => __DIR__ . '/../nwidart/laravel-modules',
'aliases' => array(),
'dev_requirement' => false,
),
'paragonie/random_compat' => array(
'pretty_version' => 'v9.99.100',
'version' => '9.99.100.0',
'reference' => '996434e5492cb4c3edcb9168db6fbb1359ef965a',
'type' => 'library',
'install_path' => __DIR__ . '/../paragonie/random_compat',
'aliases' => array(),
'dev_requirement' => false,
),
'patchwork/utf8' => array(
'pretty_version' => 'v1.3.3',
'version' => '1.3.3.0',
'reference' => 'e1fa4d4a57896d074c9a8d01742b688d5db4e9d5',
'type' => 'library',
'install_path' => __DIR__ . '/../patchwork/utf8',
'aliases' => array(),
'dev_requirement' => false,
),
'psr/container' => array(
'pretty_version' => '1.0.0',
'version' => '1.0.0.0',
'reference' => 'b7ce3b176482dbbc1245ebf52b181af44c2cf55f',
'type' => 'library',
'install_path' => __DIR__ . '/../psr/container',
'aliases' => array(),
'dev_requirement' => false,
),
'psr/http-client' => array(
'pretty_version' => '1.0.3',
'version' => '1.0.3.0',
'reference' => 'bb5906edc1c324c9a05aa0873d40117941e5fa90',
'type' => 'library',
'install_path' => __DIR__ . '/../psr/http-client',
'aliases' => array(),
'dev_requirement' => false,
),
'psr/http-client-implementation' => array(
'dev_requirement' => false,
'provided' => array(
0 => '1.0',
),
),
'psr/http-factory' => array(
'pretty_version' => '1.1.0',
'version' => '1.1.0.0',
'reference' => '2b4765fddfe3b508ac62f829e852b1501d3f6e8a',
'type' => 'library',
'install_path' => __DIR__ . '/../psr/http-factory',
'aliases' => array(),
'dev_requirement' => false,
),
'psr/http-factory-implementation' => array(
'dev_requirement' => false,
'provided' => array(
0 => '1.1',
),
),
'psr/http-message' => array(
'pretty_version' => '2.0',
'version' => '2.0.0.0',
'reference' => '402d35bcb92c70c026d1a6a9883f06b2ead23d71',
'type' => 'library',
'install_path' => __DIR__ . '/../psr/http-message',
'aliases' => array(),
'dev_requirement' => false,
),
'psr/http-message-implementation' => array(
'dev_requirement' => false,
'provided' => array(
0 => '2.0',
),
),
'psr/log' => array(
'pretty_version' => '1.0.2',
'version' => '1.0.2.0',
'reference' => '4ebe3a8bf773a19edfe0a84b6585ba3d401b724d',
'type' => 'library',
'install_path' => __DIR__ . '/../psr/log',
'aliases' => array(),
'dev_requirement' => false,
),
'psr/log-implementation' => array(
'dev_requirement' => false,
'provided' => array(
0 => '1.0',
1 => '1.0.0',
),
),
'psr/simple-cache' => array(
'pretty_version' => '1.0.1',
'version' => '1.0.1.0',
'reference' => '408d5eafb83c57f6365a3ca330ff23aa4a5fa39b',
'type' => 'library',
'install_path' => __DIR__ . '/../psr/simple-cache',
'aliases' => array(),
'dev_requirement' => false,
),
'psy/psysh' => array(
'pretty_version' => 'v0.9.12',
'version' => '0.9.12.0',
'reference' => '90da7f37568aee36b116a030c5f99c915267edd4',
'type' => 'library',
'install_path' => __DIR__ . '/../psy/psysh',
'aliases' => array(),
'dev_requirement' => false,
),
'rachidlaasri/laravel-installer' => array(
'pretty_version' => '4.0.2',
'version' => '4.0.2.0',
'reference' => '8063eda959fdee8b337e6ea543603e169e843897',
'type' => 'library',
'install_path' => __DIR__ . '/../rachidlaasri/laravel-installer',
'aliases' => array(),
'dev_requirement' => false,
),
'ramsey/uuid' => array(
'pretty_version' => '3.9.6',
'version' => '3.9.6.0',
'reference' => 'ffa80ab953edd85d5b6c004f96181a538aad35a3',
'type' => 'library',
'install_path' => __DIR__ . '/../ramsey/uuid',
'aliases' => array(),
'dev_requirement' => false,
),
'rap2hpoutre/laravel-log-viewer' => array(
'pretty_version' => 'v2.0.0',
'version' => '2.0.0.0',
'reference' => '4fa9b45738095fc5febeed6e44f1516e93a8de8c',
'type' => 'laravel-package',
'install_path' => __DIR__ . '/../rap2hpoutre/laravel-log-viewer',
'aliases' => array(),
'dev_requirement' => false,
),
'rhumsaa/uuid' => array(
'dev_requirement' => false,
'replaced' => array(
0 => '3.9.6',
),
),
'spatie/laravel-activitylog' => array(
'pretty_version' => '2.7.0',
'version' => '2.7.0.0',
'reference' => 'e354e84cee54565d59873dfd5826c57fff338c57',
'type' => 'library',
'install_path' => __DIR__ . '/../spatie/laravel-activitylog',
'aliases' => array(),
'dev_requirement' => false,
),
'spatie/string' => array(
'pretty_version' => '2.2.3',
'version' => '2.2.3.0',
'reference' => '79ed501c8d624fb85bf71da4254e1878fb616c51',
'type' => 'library',
'install_path' => __DIR__ . '/../spatie/string',
'aliases' => array(),
'dev_requirement' => false,
),
'swiftmailer/swiftmailer' => array(
'pretty_version' => 'v6.1.3',
'version' => '6.1.3.0',
'reference' => '8ddcb66ac10c392d3beb54829eef8ac1438595f4',
'type' => 'library',
'install_path' => __DIR__ . '/../swiftmailer/swiftmailer',
'aliases' => array(),
'dev_requirement' => false,
),
'symfony/console' => array(
'pretty_version' => 'v3.4.47',
'version' => '3.4.47.0',
'reference' => 'a10b1da6fc93080c180bba7219b5ff5b7518fe81',
'type' => 'library',
'install_path' => __DIR__ . '/../symfony/console',
'aliases' => array(),
'dev_requirement' => false,
),
'symfony/css-selector' => array(
'pretty_version' => 'v3.4.18',
'version' => '3.4.18.0',
'reference' => '3503415d4aafabc31cd08c3a4ebac7f43fde8feb',
'type' => 'library',
'install_path' => __DIR__ . '/../symfony/css-selector',
'aliases' => array(),
'dev_requirement' => false,
),
'symfony/debug' => array(
'pretty_version' => 'v3.4.18',
'version' => '3.4.18.0',
'reference' => 'fe9793af008b651c5441bdeab21ede8172dab097',
'type' => 'library',
'install_path' => __DIR__ . '/../symfony/debug',
'aliases' => array(),
'dev_requirement' => false,
),
'symfony/event-dispatcher' => array(
'pretty_version' => 'v3.4.18',
'version' => '3.4.18.0',
'reference' => 'db9e829c8f34c3d35cf37fcd4cdb4293bc4a2f14',
'type' => 'library',
'install_path' => __DIR__ . '/../symfony/event-dispatcher',
'aliases' => array(),
'dev_requirement' => false,
),
'symfony/finder' => array(
'pretty_version' => 'v3.4.18',
'version' => '3.4.18.0',
'reference' => '54ba444dddc5bd5708a34bd095ea67c6eb54644d',
'type' => 'library',
'install_path' => __DIR__ . '/../symfony/finder',
'aliases' => array(),
'dev_requirement' => false,
),
'symfony/http-foundation' => array(
'pretty_version' => 'v3.4.18',
'version' => '3.4.18.0',
'reference' => '5aea7a86ca3203dd7a257e765b4b9c9cfd01c6c0',
'type' => 'library',
'install_path' => __DIR__ . '/../symfony/http-foundation',
'aliases' => array(),
'dev_requirement' => false,
),
'symfony/http-kernel' => array(
'pretty_version' => 'v3.4.18',
'version' => '3.4.18.0',
'reference' => '4bf0be7c7fe63eff6a5eae2f21c83e77e31a56fb',
'type' => 'library',
'install_path' => __DIR__ . '/../symfony/http-kernel',
'aliases' => array(),
'dev_requirement' => false,
),
'symfony/polyfill-ctype' => array(
'pretty_version' => 'v1.10.0',
'version' => '1.10.0.0',
'reference' => 'e3d826245268269cd66f8326bd8bc066687b4a19',
'type' => 'library',
'install_path' => __DIR__ . '/../symfony/polyfill-ctype',
'aliases' => array(),
'dev_requirement' => false,
),
'symfony/polyfill-mbstring' => array(
'pretty_version' => 'v1.24.0',
'version' => '1.24.0.0',
'reference' => '0abb51d2f102e00a4eefcf46ba7fec406d245825',
'type' => 'library',
'install_path' => __DIR__ . '/../symfony/polyfill-mbstring',
'aliases' => array(),
'dev_requirement' => false,
),
'symfony/polyfill-php70' => array(
'pretty_version' => 'v1.10.0',
'version' => '1.10.0.0',
'reference' => '6b88000cdd431cd2e940caa2cb569201f3f84224',
'type' => 'library',
'install_path' => __DIR__ . '/../symfony/polyfill-php70',
'aliases' => array(),
'dev_requirement' => false,
),
'symfony/polyfill-php80' => array(
'pretty_version' => 'v1.37.0',
'version' => '1.37.0.0',
'reference' => 'dfb55726c3a76ea3b6459fcfda1ec2d80a682411',
'type' => 'library',
'install_path' => __DIR__ . '/../symfony/polyfill-php80',
'aliases' => array(),
'dev_requirement' => false,
),
'symfony/polyfill-php82' => array(
'pretty_version' => 'v1.38.1',
'version' => '1.38.1.0',
'reference' => '002dc0cfe5fd4ed6033d48f27d4f19a486c4b04b',
'type' => 'library',
'install_path' => __DIR__ . '/../symfony/polyfill-php82',
'aliases' => array(),
'dev_requirement' => false,
),
'symfony/process' => array(
'pretty_version' => 'v3.4.18',
'version' => '3.4.18.0',
'reference' => '35c2914a9f50519bd207164c353ae4d59182c2cb',
'type' => 'library',
'install_path' => __DIR__ . '/../symfony/process',
'aliases' => array(),
'dev_requirement' => false,
),
'symfony/routing' => array(
'pretty_version' => 'v3.4.18',
'version' => '3.4.18.0',
'reference' => '585f6e2d740393d546978769dd56e496a6233e0b',
'type' => 'library',
'install_path' => __DIR__ . '/../symfony/routing',
'aliases' => array(),
'dev_requirement' => false,
),
'symfony/translation' => array(
'pretty_version' => 'v3.4.18',
'version' => '3.4.18.0',
'reference' => '94bc3a79008e6640defedf5e14eb3b4f20048352',
'type' => 'library',
'install_path' => __DIR__ . '/../symfony/translation',
'aliases' => array(),
'dev_requirement' => false,
),
'symfony/var-dumper' => array(
'pretty_version' => 'v3.4.18',
'version' => '3.4.18.0',
'reference' => 'ff8ac19e97e5c7c3979236b584719a1190f84181',
'type' => 'library',
'install_path' => __DIR__ . '/../symfony/var-dumper',
'aliases' => array(),
'dev_requirement' => false,
),
'tedivm/jshrink' => array(
'pretty_version' => 'v1.4.0',
'version' => '1.4.0.0',
'reference' => '0513ba1407b1f235518a939455855e6952a48bbc',
'type' => 'library',
'install_path' => __DIR__ . '/../tedivm/jshrink',
'aliases' => array(),
'dev_requirement' => false,
),
'tightenco/collect' => array(
'dev_requirement' => false,
'replaced' => array(
0 => '<5.5.33',
),
),
'tijsverkoyen/css-to-inline-styles' => array(
'pretty_version' => 'v2.2.7',
'version' => '2.2.7.0',
'reference' => '83ee6f38df0a63106a9e4536e3060458b74ccedb',
'type' => 'library',
'install_path' => __DIR__ . '/../tijsverkoyen/css-to-inline-styles',
'aliases' => array(),
'dev_requirement' => false,
),
'tormjens/eventy' => array(
'pretty_version' => '0.5.4',
'version' => '0.5.4.0',
'reference' => 'ed48fe39107168c21199c8abfee558cd3370d971',
'type' => 'library',
'install_path' => __DIR__ . '/../tormjens/eventy',
'aliases' => array(),
'dev_requirement' => false,
),
'vlucas/phpdotenv' => array(
'pretty_version' => 'v2.5.1',
'version' => '2.5.1.0',
'reference' => '8abb4f9aa89ddea9d52112c65bbe8d0125e2fa8e',
'type' => 'library',
'install_path' => __DIR__ . '/../vlucas/phpdotenv',
'aliases' => array(),
'dev_requirement' => false,
),
'watson/rememberable' => array(
'pretty_version' => '2.0.4',
'version' => '2.0.4.0',
'reference' => '8718614835370f67f58d86387a26bfc315fa9a8b',
'type' => 'library',
'install_path' => __DIR__ . '/../watson/rememberable',
'aliases' => array(),
'dev_requirement' => false,
),
'webklex/php-imap' => array(
'pretty_version' => '4.1.1',
'version' => '4.1.1.0',
'reference' => '5415d520d235ce8585e7f3c03c2b937bd8662a3e',
'type' => 'library',
'install_path' => __DIR__ . '/../webklex/php-imap',
'aliases' => array(),
'dev_requirement' => false,
),
),
);

16
vendor/devfactory/minify/.travis.yml vendored Normal file
View File

@@ -0,0 +1,16 @@
language: php
php:
- 5.4
- 5.5
- 5.6
- hhvm
matrix:
allow_failures:
- php: hhvm
before_script:
- composer install --dev --prefer-source --no-interaction
script: vendor/bin/phpspec run

View File

@@ -0,0 +1,101 @@
<?php namespace spec\Devfactory\Minify\Providers;
use PhpSpec\ObjectBehavior;
use Prophecy\Argument;
use Prophecy\Prophet;
use org\bovigo\vfs\vfsStream;
use Illuminate\Filesystem\Filesystem;
class JavaScriptSpec extends ObjectBehavior
{
function it_is_initializable()
{
$this->shouldHaveType('Devfactory\Minify\Providers\JavaScript');
}
function it_adds_one_file()
{
vfsStream::setup('js',null, array(
'1.js' => 'a',
));
$this->add(VfsStream::url('js'));
$this->shouldHaveCount(1);
}
function it_adds_multiple_files()
{
vfsStream::setup('root',null, array(
'1.js' => 'a',
'2.js' => 'b',
));
$this->add(array(
VfsStream::url('root/1.js'),
VfsStream::url('root/2.js')
));
$this->shouldHaveCount(2);
}
function it_adds_custom_attributes()
{
$this->tag('file', array('foobar' => 'baz', 'defer' => true))
->shouldReturn('<script src="file" foobar="baz" defer></script>' . PHP_EOL);
}
function it_adds_without_custom_attributes()
{
$this->tag('file', array())
->shouldReturn('<script src="file"></script>' . PHP_EOL);
}
function it_throws_exception_when_file_not_exists()
{
$this->shouldThrow('Devfactory\Minify\Exceptions\FileNotExistException')
->duringAdd('foobar');
}
function it_should_throw_exception_when_buildpath_not_exist()
{
$prophet = new Prophet;
$file = $prophet->prophesize('Illuminate\Filesystem\Filesystem');
$file->makeDirectory('dir_bar', 0775, true)->willReturn(false);
$this->beConstructedWith(null, null, $file);
$this->shouldThrow('Devfactory\Minify\Exceptions\DirNotExistException')
->duringMake('dir_bar');
}
function it_should_throw_exception_when_buildpath_not_writable()
{
vfsStream::setup('js',0555, array());
$this->shouldThrow('Devfactory\Minify\Exceptions\DirNotWritableException')
->duringMake(vfsStream::url('js'));
}
function it_minifies_multiple_files()
{
vfsStream::setup('root',null, array(
'output' => array(),
'1.js' => 'a',
'2.js' => 'b',
));
$this->add(vfsStream::url('root/1.js'));
$this->add(vfsStream::url('root/2.js'));
$this->make(vfsStream::url('root/output'));
$this->getAppended()->shouldBe("a\nb\n");
$output = md5('vfs://root/1.js-vfs://root/2.js');
$filemtime = filemtime(vfsStream::url('root/1.js')) + filemtime(vfsStream::url('root/2.js'));
$extension = '.js';
$this->getFilename()->shouldBe($output . $filemtime . $extension);
}
}

View File

@@ -0,0 +1,99 @@
<?php namespace spec\Devfactory\Minify\Providers;
use PhpSpec\ObjectBehavior;
use Prophecy\Argument;
use Prophecy\Prophet;
use org\bovigo\vfs\vfsStream;
use Illuminate\Filesystem\Filesystem;
class StyleSheetSpec extends ObjectBehavior
{
function it_is_initializable()
{
$this->shouldHaveType('Devfactory\Minify\Providers\StyleSheet');
}
function it_adds_one_file()
{
vfsStream::setup('css',null, array(
'1.css' => 'a',
));
$this->add(VfsStream::url('css'));
$this->shouldHaveCount(1);
}
function it_adds_multiple_files()
{
vfsStream::setup('root',null, array(
'1.css' => 'a',
'2.css' => 'b',
));
$this->add(array(
VfsStream::url('root/1.css'),
VfsStream::url('root/2.css')
));
$this->shouldHaveCount(2);
}
function it_adds_custom_attributes()
{
$this->tag('file', array('foobar' => 'baz', 'defer' => true))
->shouldReturn('<link href="file" rel="stylesheet" foobar="baz" defer>' . PHP_EOL);
}
function it_adds_without_custom_attributes()
{
$this->tag('file')
->shouldReturn('<link href="file" rel="stylesheet">' . PHP_EOL);
}
function it_throws_exception_when_file_not_exists()
{
$this->shouldThrow('Devfactory\Minify\Exceptions\FileNotExistException')
->duringAdd('foobar');
}
function it_should_throw_exception_when_buildpath_not_exist()
{
$prophet = new Prophet;
$file = $prophet->prophesize('Illuminate\Filesystem\Filesystem');
$file->makeDirectory('dir_bar', 0775, true)->willReturn(false);
$this->beConstructedWith(null, null, $file);
$this->shouldThrow('Devfactory\Minify\Exceptions\DirNotExistException')
->duringMake('dir_bar');
}
function it_should_throw_exception_when_buildpath_not_writable()
{
vfsStream::setup('css',0555, array());
$this->shouldThrow('Devfactory\Minify\Exceptions\DirNotWritableException')
->duringMake(vfsStream::url('css'));
}
function it_minifies_multiple_files()
{
vfsStream::setup('root',null, array(
'output' => array(),
'1.css' => 'a',
'2.css' => 'b',
));
$this->add(vfsStream::url('root/1.css'));
$this->add(vfsStream::url('root/2.css'));
$this->make(vfsStream::url('root/output'));
$this->getAppended()->shouldBe("a\nb\n");
$output = md5('vfs://root/1.css-vfs://root/2.css');
$filemtime = filemtime(vfsStream::url('root/1.css')) + filemtime(vfsStream::url('root/2.css'));
$extension = '.css';
$this->getFilename()->shouldBe($output . $filemtime . $extension);
}
}

View File

@@ -0,0 +1,16 @@
<?php namespace Devfactory\Minify\Contracts;
interface MinifyInterface {
/**
* @return mixed
*/
public function minify();
/**
* @param string $file
* @param array $attributes
* @return mixed
*/
public function tag($file, array $attributes);
}

View File

@@ -0,0 +1,3 @@
<?php namespace Devfactory\Minify\Exceptions;
class CannotRemoveFileException extends \Exception{}

View File

@@ -0,0 +1,3 @@
<?php namespace Devfactory\Minify\Exceptions;
class CannotSaveFileException extends \Exception{}

View File

@@ -0,0 +1,3 @@
<?php namespace Devfactory\Minify\Exceptions;
class DirNotExistException extends \Exception {}

View File

@@ -0,0 +1,3 @@
<?php namespace Devfactory\Minify\Exceptions;
class DirNotWritableException extends \Exception {}

View File

@@ -0,0 +1,3 @@
<?php namespace Devfactory\Minify\Exceptions;
class FileNotExistException extends \Exception {}

View File

@@ -0,0 +1,3 @@
<?php namespace Devfactory\Minify\Exceptions;
class InvalidArgumentException extends \Exception{}

View File

@@ -0,0 +1,16 @@
<?php namespace Devfactory\Minify\Facades;
use Illuminate\Support\Facades\Facade;
class MinifyFacade extends Facade
{
/**
* Name of the binding in the IoC container
*
* @return string
*/
protected static function getFacadeAccessor()
{
return 'minify';
}
}

259
vendor/devfactory/minify/src/Minify.php vendored Normal file
View File

@@ -0,0 +1,259 @@
<?php namespace Devfactory\Minify;
use Devfactory\Minify\Exceptions\InvalidArgumentException;
use Devfactory\Minify\Providers\JavaScript;
use Devfactory\Minify\Providers\StyleSheet;
use RecursiveIteratorIterator;
use RecursiveDirectoryIterator;
use Request;
class Minify
{
/**
* @var array
*/
protected $config;
/**
* @var array
*/
protected $attributes = array();
/**
* @var string
*/
private $environment;
/**
* @var
*/
private $provider;
/**
* @var
*/
private $buildPath;
/**
* @var bool
*/
private $fullUrl = false;
/**
* @var bool
*/
private $onlyUrl = false;
/**
* @var bool
*/
private $buildExtension;
/**
* @param array $config
* @param string $environment
*/
public function __construct(array $config, $environment) {
$this->checkConfiguration($config);
$this->config = $config;
$this->environment = $environment;
}
/**
* @param $file
* @param array $attributes
* @return string
*/
public function javascript($file, $attributes = array()) {
$this->provider = new JavaScript(public_path(), ['hash_salt' => $this->config['hash_salt'], 'disable_mtime' => $this->config['disable_mtime']]);
$this->buildPath = $this->config['js_build_path'];
$this->attributes = $attributes;
$this->buildExtension = 'js';
$this->process($file);
return $this;
}
/**
* @param $file
* @param array $attributes
* @return string
*/
public function stylesheet($file, $attributes = array()) {
$this->provider = new StyleSheet(public_path(), ['hash_salt' => $this->config['hash_salt'], 'disable_mtime' => $this->config['disable_mtime']]);
$this->buildPath = $this->config['css_build_path'];
$this->attributes = $attributes;
$this->buildExtension = 'css';
$this->process($file);
return $this;
}
/**
* @param $dir
* @param array $attributes
* @return string
*/
public function stylesheetDir($dir, $attributes = array()) {
$this->provider = new StyleSheet(public_path(), ['hash_salt' => $this->config['hash_salt'], 'disable_mtime' => $this->config['disable_mtime']]);
$this->buildPath = $this->config['css_build_path'];
$this->attributes = $attributes;
$this->buildExtension = 'css';
return $this->assetDirHelper('css', $dir);
}
/**
* @param $dir
* @param array $attributes
* @return string
*/
public function javascriptDir($dir, $attributes = array()) {
$this->provider = new JavaScript(public_path(), ['hash_salt' => $this->config['hash_salt'], 'disable_mtime' => $this->config['disable_mtime']]);
$this->buildPath = $this->config['js_build_path'];
$this->attributes = $attributes;
$this->buildExtension = 'js';
return $this->assetDirHelper('js', $dir);
}
/**
* @param $ext
* @param $dir
* @return string
*/
private function assetDirHelper($ext, $dir) {
$files = array();
$itr_obj = new RecursiveDirectoryIterator(public_path().$dir);
$itr_obj->setFlags(RecursiveDirectoryIterator::SKIP_DOTS);
$dir_obj = new RecursiveIteratorIterator($itr_obj);
foreach ($dir_obj as $fileinfo)
{
if (!$fileinfo->isDir() && ($filename = $fileinfo->getFilename()) && (pathinfo($filename, PATHINFO_EXTENSION) == $ext) && (strlen($fileinfo->getFilename()) < 30))
{
$files[] = str_replace(public_path(), '', $fileinfo);
}
}
if (count($files) > 0)
{
if($this->config['reverse_sort']) {
rsort($files);
}
else {
sort($files);
}
$this->process($files);
}
return $this;
}
/**
* @param $file
*/
private function process($file) {
$this->provider->add($file);
if($this->minifyForCurrentEnvironment() && $this->provider->make($this->buildPath))
{
$this->provider->minify();
}
$this->fullUrl = false;
}
/**
* @return mixed
*/
protected function render()
{
$baseUrl = $this->fullUrl ? $this->getBaseUrl() : '';
if (!$this->minifyForCurrentEnvironment())
{
return $this->provider->tags($baseUrl, $this->attributes);
}
if( $this->buildExtension == 'js')
{
$buildPath = isset($this->config['js_url_path']) ? $this->config['js_url_path'] : $this->buildPath;
}
else# if( $this->buildExtension == 'css')
{
$buildPath = isset($this->config['css_url_path']) ? $this->config['css_url_path'] : $this->buildPath;
}
$filename = $baseUrl . $buildPath . $this->provider->getFilename();
if ($this->onlyUrl) {
return $filename;
}
return $this->provider->tag($filename, $this->attributes);
}
/**
* @return bool
*/
protected function minifyForCurrentEnvironment()
{
return !in_array($this->environment, $this->config['ignore_environments']);
}
/**
* @return string
*/
public function withFullUrl() {
$this->fullUrl = true;
return $this;
}
/**
* @return mixed
*/
public function onlyUrl()
{
$this->onlyUrl = true;
return $this;
}
/**
* @return string
*/
public function __toString() {
return $this->render();
}
/**
* @param array $config
* @throws Exceptions\InvalidArgumentException
* @return array
*/
private function checkConfiguration(array $config) {
if(!isset($config['css_build_path']) || !is_string($config['css_build_path']))
throw new InvalidArgumentException("Missing css_build_path field");
if(!isset($config['js_build_path']) || !is_string($config['js_build_path']))
throw new InvalidArgumentException("Missing js_build_path field");
if(!isset($config['ignore_environments']) || !is_array($config['ignore_environments']))
throw new InvalidArgumentException("Missing ignore_environments field");
}
/**
* @return string
*/
private function getBaseUrl() {
if (is_null($this->config['base_url']) || (trim($this->config['base_url']) == '')) {
return Request::root();
} else {
return $this->config['base_url'];
}
}
}

View File

@@ -0,0 +1,89 @@
<?php namespace Devfactory\Minify;
use Illuminate\Foundation\AliasLoader;
use Illuminate\Support\ServiceProvider;
class MinifyServiceProvider extends ServiceProvider {
/**
* Indicates if loading of the provider is deferred.
*
* @var bool
*/
protected $defer = false;
/**
* Bootstrap the application events.
*
* @return void
*/
public function boot()
{
$this->publishConfig();
}
/**
* Register the service provider.
*
* @return void
*/
public function register()
{
$this->registerServices();
$this->mergeConfig();
}
/**
* Register the package services.
*
* @return void
*/
protected function registerServices() {
$this->app->singleton('minify', function ($app) {
return new Minify(
array(
'css_build_path' => config('minify.config.css_build_path'),
'css_url_path' => config('minify.config.css_url_path'),
'js_build_path' => config('minify.config.js_build_path'),
'js_url_path' => config('minify.config.js_url_path'),
'ignore_environments' => config('minify.config.ignore_environments'),
'base_url' => config('minify.config.base_url'),
'reverse_sort' => config('minify.config.reverse_sort'),
'disable_mtime' => config('minify.config.disable_mtime'),
'hash_salt' => config('minify.config.hash_salt'),
),
$app->environment()
);
});
}
/**
* Publish the package configuration
*/
protected function publishConfig() {
$this->publishes([
__DIR__ . '/config/config.php' => config_path('minify.config.php'),
]);
}
/**
* Merge media config with users.
*/
private function mergeConfig() {
$this->mergeConfigFrom(
__DIR__ . '/config/config.php', 'minify.config'
);
}
/**
* Get the services provided by the provider.
*
* @return array
*/
public function provides()
{
return array('minify');
}
}

View File

@@ -0,0 +1,34 @@
<?php namespace Devfactory\Minify\Providers;
use Devfactory\Minify\Contracts\MinifyInterface;
use JShrink\Minifier;
class JavaScript extends BaseProvider implements MinifyInterface
{
/**
* The extension of the outputted file.
*/
const EXTENSION = '.js';
/**
* @return string
*/
public function minify()
{
$minified = Minifier::minify($this->appended);
return $this->put($minified);
}
/**
* @param $file
* @param array $attributes
* @return string
*/
public function tag($file, array $attributes)
{
$attributes = array('src' => $file) + $attributes;
return "<script {$this->attributes($attributes)}></script>" . PHP_EOL;
}
}

View File

@@ -0,0 +1,34 @@
<?php namespace Devfactory\Minify\Providers;
use Devfactory\Minify\Contracts\MinifyInterface;
use CssMinifier;
class StyleSheet extends BaseProvider implements MinifyInterface
{
/**
* The extension of the outputted file.
*/
const EXTENSION = '.css';
/**
* @return string
*/
public function minify()
{
$minified = new CssMinifier($this->appended);
return $this->put($minified->getMinified());
}
/**
* @param $file
* @param array $attributes
* @return string
*/
public function tag($file, array $attributes = array())
{
$attributes = array('href' => $file, 'rel' => 'stylesheet') + $attributes;
return "<link {$this->attributes($attributes)}>" . PHP_EOL;
}
}

View File

@@ -0,0 +1,84 @@
<?php
return array(
/*
|--------------------------------------------------------------------------
| Sort Direction
|--------------------------------------------------------------------------
|
| You can set the sort direction (ascending/descending) when
| minifying full directories.
|
*/
'reverse_sort' => true,
/*
|--------------------------------------------------------------------------
| App environments to not minify
|--------------------------------------------------------------------------
|
| These environments will not be minified and all individual files are
| returned
|
*/
'ignore_environments' => array(
'local',
),
/*
|--------------------------------------------------------------------------
| CSS build path
|--------------------------------------------------------------------------
|
| Minify is an extension that can minify your css files into one build file.
| The css_builds_path property is the location where the builded files are
| stored. This is relative to your public path. Notice the trailing slash.
| Note that this directory must be writeable.
|
*/
'css_build_path' => '/css/builds/',
'css_url_path' => '/css/builds/',
/*
|--------------------------------------------------------------------------
| JS build path
|--------------------------------------------------------------------------
|
| Minify is an extension that can minify your js files into one build file.
| The js_build_path property is the location where the builded files are
| stored. This is relative to your public path. Notice the trailing slash.
| Note that this directory must be writeable.
|
*/
'js_build_path' => '/js/builds/',
'js_url_path' => '/js/builds/',
/*
|--------------------------------------------------------------------------
| Hash modification
|--------------------------------------------------------------------------
|
| You can disable usage of modification time (mtime) for hash build and
| add additional salt (exp. commit hash) for hash build
|
*/
'disable_mtime' => false,
'hash_salt' => '',
/*
|--------------------------------------------------------------------------
| Base URL
|--------------------------------------------------------------------------
|
| You can set the base URL for the links generated with the configuration
| value. By default if empty HTTP_HOST would be used.
|
*/
'base_url' => ''
);

View File

@@ -0,0 +1,132 @@
<?php
namespace XdgBaseDir;
/**
* Simple implementation of the XDG standard http://standards.freedesktop.org/basedir-spec/basedir-spec-latest.html
*
* Based on the python implementation https://github.com/takluyver/pyxdg/blob/master/xdg/BaseDirectory.py
*/
class Xdg
{
const S_IFDIR = 040000; // directory
const S_IRWXO = 00007; // rwx other
const S_IRWXG = 00056; // rwx group
const RUNTIME_DIR_FALLBACK = 'php-xdg-runtime-dir-fallback-';
/**
* @return string
*/
public function getHomeDir()
{
return getenv('HOME') ?: (getenv('HOMEDRIVE') . DIRECTORY_SEPARATOR . getenv('HOMEPATH'));
}
/**
* @return string
*/
public function getHomeConfigDir()
{
if ($path = getenv('XDG_CONFIG_HOME')) {
return $path;
}
$homeDir = $this->getHomeDir();
$path = DIRECTORY_SEPARATOR === $homeDir ? $homeDir.'.config' : $homeDir . DIRECTORY_SEPARATOR . '.config';
return $path;
}
/**
* @return string
*/
public function getHomeDataDir()
{
$path = getenv('XDG_DATA_HOME') ?: $this->getHomeDir() . DIRECTORY_SEPARATOR . '.local' . DIRECTORY_SEPARATOR . 'share';
return $path;
}
/**
* @return array
*/
public function getConfigDirs()
{
$configDirs = getenv('XDG_CONFIG_DIRS') ? explode(':', getenv('XDG_CONFIG_DIRS')) : array('/etc/xdg');
$paths = array_merge(array($this->getHomeConfigDir()), $configDirs);
return $paths;
}
/**
* @return array
*/
public function getDataDirs()
{
$dataDirs = getenv('XDG_DATA_DIRS') ? explode(':', getenv('XDG_DATA_DIRS')) : array('/usr/local/share', '/usr/share');
$paths = array_merge(array($this->getHomeDataDir()), $dataDirs);
return $paths;
}
/**
* @return string
*/
public function getHomeCacheDir()
{
$path = getenv('XDG_CACHE_HOME') ?: $this->getHomeDir() . DIRECTORY_SEPARATOR . '.cache';
return $path;
}
public function getRuntimeDir($strict=true)
{
if ($runtimeDir = getenv('XDG_RUNTIME_DIR')) {
return $runtimeDir;
}
if ($strict) {
throw new \RuntimeException('XDG_RUNTIME_DIR was not set');
}
$fallback = sys_get_temp_dir() . DIRECTORY_SEPARATOR . self::RUNTIME_DIR_FALLBACK . getenv('USER');
$create = false;
if (!is_dir($fallback)) {
mkdir($fallback, 0700, true);
}
$st = lstat($fallback);
# The fallback must be a directory
if (!$st['mode'] & self::S_IFDIR) {
rmdir($fallback);
$create = true;
} elseif ($st['uid'] != $this->getUid() ||
$st['mode'] & (self::S_IRWXG | self::S_IRWXO)
) {
rmdir($fallback);
$create = true;
}
if ($create) {
mkdir($fallback, 0700, true);
}
return $fallback;
}
private function getUid()
{
if (function_exists('posix_getuid')) {
return posix_getuid();
}
return getmyuid();
}
}

4
vendor/doctrine/cache/.coveralls.yml vendored Normal file
View File

@@ -0,0 +1,4 @@
# for php-coveralls
service_name: travis-ci
src_dir: lib
coverage_clover: build/logs/clover.xml

42
vendor/doctrine/cache/.travis.yml vendored Normal file
View File

@@ -0,0 +1,42 @@
language: php
sudo: false
cache:
directories:
- vendor
- $HOME/.composer/cache
php:
- 5.5
- 5.6
- 7.0
- hhvm
services:
- riak
- mongodb
- memcached
- redis-server
before_install:
- if [[ $TRAVIS_PHP_VERSION != 'hhvm' ]] ; then pecl channel-update pecl.php.net; fi;
- if [[ $TRAVIS_PHP_VERSION != 'hhvm' && $TRAVIS_PHP_VERSION != '7.0' ]]; then pecl install riak-beta; fi;
- if [[ $TRAVIS_PHP_VERSION =~ 5.[56] ]] ; then echo yes | pecl install apcu-4.0.10; fi;
- if [[ $TRAVIS_PHP_VERSION = 7.* ]] ; then pecl config-set preferred_state beta; echo yes | pecl install apcu; fi;
- if [[ $TRAVIS_PHP_VERSION != 'hhvm' ]]; then phpenv config-add ./tests/travis/php.ini; fi;
install:
- travis_retry composer install
script:
- ./vendor/bin/phpunit -c ./tests/travis/phpunit.travis.xml -v
after_script:
- php vendor/bin/coveralls -v
matrix:
fast_finish: true
allow_failures:
- php: hhvm
- php: 7.0

View File

@@ -0,0 +1,3 @@
# Version class and file
project.version_class = Doctrine\\Common\\Cache\\Version
project.version_file = lib/Doctrine/Common/Cache/Version.php

View File

@@ -0,0 +1,118 @@
<?php
/*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This software consists of voluntary contributions made by many individuals
* and is licensed under the MIT license. For more information, see
* <http://www.doctrine-project.org>.
*/
namespace Doctrine\Common\Cache;
/**
* APC cache provider.
*
* @link www.doctrine-project.org
* @deprecated since version 1.6, use ApcuCache instead
* @since 2.0
* @author Benjamin Eberlei <kontakt@beberlei.de>
* @author Guilherme Blanco <guilhermeblanco@hotmail.com>
* @author Jonathan Wage <jonwage@gmail.com>
* @author Roman Borschel <roman@code-factory.org>
* @author David Abdemoulaie <dave@hobodave.com>
*/
class ApcCache extends CacheProvider
{
/**
* {@inheritdoc}
*/
protected function doFetch($id)
{
return apc_fetch($id);
}
/**
* {@inheritdoc}
*/
protected function doContains($id)
{
return apc_exists($id);
}
/**
* {@inheritdoc}
*/
protected function doSave($id, $data, $lifeTime = 0)
{
return apc_store($id, $data, $lifeTime);
}
/**
* {@inheritdoc}
*/
protected function doDelete($id)
{
// apc_delete returns false if the id does not exist
return apc_delete($id) || ! apc_exists($id);
}
/**
* {@inheritdoc}
*/
protected function doFlush()
{
return apc_clear_cache() && apc_clear_cache('user');
}
/**
* {@inheritdoc}
*/
protected function doFetchMultiple(array $keys)
{
return apc_fetch($keys) ?: [];
}
/**
* {@inheritdoc}
*/
protected function doSaveMultiple(array $keysAndValues, $lifetime = 0)
{
$result = apc_store($keysAndValues, null, $lifetime);
return empty($result);
}
/**
* {@inheritdoc}
*/
protected function doGetStats()
{
$info = apc_cache_info('', true);
$sma = apc_sma_info();
// @TODO - Temporary fix @see https://github.com/krakjoe/apcu/pull/42
if (PHP_VERSION_ID >= 50500) {
$info['num_hits'] = isset($info['num_hits']) ? $info['num_hits'] : $info['nhits'];
$info['num_misses'] = isset($info['num_misses']) ? $info['num_misses'] : $info['nmisses'];
$info['start_time'] = isset($info['start_time']) ? $info['start_time'] : $info['stime'];
}
return array(
Cache::STATS_HITS => $info['num_hits'],
Cache::STATS_MISSES => $info['num_misses'],
Cache::STATS_UPTIME => $info['start_time'],
Cache::STATS_MEMORY_USAGE => $info['mem_size'],
Cache::STATS_MEMORY_AVAILABLE => $sma['avail_mem'],
);
}
}

View File

@@ -0,0 +1,106 @@
<?php
/*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This software consists of voluntary contributions made by many individuals
* and is licensed under the MIT license. For more information, see
* <http://www.doctrine-project.org>.
*/
namespace Doctrine\Common\Cache;
/**
* APCu cache provider.
*
* @link www.doctrine-project.org
* @since 1.6
* @author Kévin Dunglas <dunglas@gmail.com>
*/
class ApcuCache extends CacheProvider
{
/**
* {@inheritdoc}
*/
protected function doFetch($id)
{
return apcu_fetch($id);
}
/**
* {@inheritdoc}
*/
protected function doContains($id)
{
return apcu_exists($id);
}
/**
* {@inheritdoc}
*/
protected function doSave($id, $data, $lifeTime = 0)
{
return apcu_store($id, $data, $lifeTime);
}
/**
* {@inheritdoc}
*/
protected function doDelete($id)
{
// apcu_delete returns false if the id does not exist
return apcu_delete($id) || ! apcu_exists($id);
}
/**
* {@inheritdoc}
*/
protected function doFlush()
{
return apcu_clear_cache();
}
/**
* {@inheritdoc}
*/
protected function doFetchMultiple(array $keys)
{
return apcu_fetch($keys) ?: [];
}
/**
* {@inheritdoc}
*/
protected function doSaveMultiple(array $keysAndValues, $lifetime = 0)
{
$result = apcu_store($keysAndValues, null, $lifetime);
return empty($result);
}
/**
* {@inheritdoc}
*/
protected function doGetStats()
{
$info = apcu_cache_info(true);
$sma = apcu_sma_info();
return array(
Cache::STATS_HITS => $info['num_hits'],
Cache::STATS_MISSES => $info['num_misses'],
Cache::STATS_UPTIME => $info['start_time'],
Cache::STATS_MEMORY_USAGE => $info['mem_size'],
Cache::STATS_MEMORY_AVAILABLE => $sma['avail_mem'],
);
}
}

View File

@@ -0,0 +1,142 @@
<?php
/*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This software consists of voluntary contributions made by many individuals
* and is licensed under the MIT license. For more information, see
* <http://www.doctrine-project.org>.
*/
namespace Doctrine\Common\Cache;
/**
* Array cache driver.
*
* @link www.doctrine-project.org
* @since 2.0
* @author Benjamin Eberlei <kontakt@beberlei.de>
* @author Guilherme Blanco <guilhermeblanco@hotmail.com>
* @author Jonathan Wage <jonwage@gmail.com>
* @author Roman Borschel <roman@code-factory.org>
* @author David Abdemoulaie <dave@hobodave.com>
*/
class ArrayCache extends CacheProvider
{
/**
* @var array[] $data each element being a tuple of [$data, $expiration], where the expiration is int|bool
*/
private $data = [];
/**
* @var int
*/
private $hitsCount = 0;
/**
* @var int
*/
private $missesCount = 0;
/**
* @var int
*/
private $upTime;
/**
* {@inheritdoc}
*/
public function __construct()
{
$this->upTime = time();
}
/**
* {@inheritdoc}
*/
protected function doFetch($id)
{
if (! $this->doContains($id)) {
$this->missesCount += 1;
return false;
}
$this->hitsCount += 1;
return $this->data[$id][0];
}
/**
* {@inheritdoc}
*/
protected function doContains($id)
{
if (! isset($this->data[$id])) {
return false;
}
$expiration = $this->data[$id][1];
if ($expiration && $expiration < time()) {
$this->doDelete($id);
return false;
}
return true;
}
/**
* {@inheritdoc}
*/
protected function doSave($id, $data, $lifeTime = 0)
{
$this->data[$id] = [$data, $lifeTime ? time() + $lifeTime : false];
return true;
}
/**
* {@inheritdoc}
*/
protected function doDelete($id)
{
unset($this->data[$id]);
return true;
}
/**
* {@inheritdoc}
*/
protected function doFlush()
{
$this->data = [];
return true;
}
/**
* {@inheritdoc}
*/
protected function doGetStats()
{
return [
Cache::STATS_HITS => $this->hitsCount,
Cache::STATS_MISSES => $this->missesCount,
Cache::STATS_UPTIME => $this->upTime,
Cache::STATS_MEMORY_USAGE => null,
Cache::STATS_MEMORY_AVAILABLE => null,
];
}
}

View File

@@ -0,0 +1,116 @@
<?php
/*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This software consists of voluntary contributions made by many individuals
* and is licensed under the MIT license. For more information, see
* <http://www.doctrine-project.org>.
*/
namespace Doctrine\Common\Cache;
/**
* Interface for cache drivers.
*
* @link www.doctrine-project.org
* @since 2.0
* @author Benjamin Eberlei <kontakt@beberlei.de>
* @author Guilherme Blanco <guilhermeblanco@hotmail.com>
* @author Jonathan Wage <jonwage@gmail.com>
* @author Roman Borschel <roman@code-factory.org>
* @author Fabio B. Silva <fabio.bat.silva@gmail.com>
* @author Kévin Dunglas <dunglas@gmail.com>
*/
interface Cache
{
const STATS_HITS = 'hits';
const STATS_MISSES = 'misses';
const STATS_UPTIME = 'uptime';
const STATS_MEMORY_USAGE = 'memory_usage';
const STATS_MEMORY_AVAILABLE = 'memory_available';
/**
* Only for backward compatibility (may be removed in next major release)
*
* @deprecated
*/
const STATS_MEMORY_AVAILIABLE = 'memory_available';
/**
* Fetches an entry from the cache.
*
* @param string $id The id of the cache entry to fetch.
*
* @return mixed The cached data or FALSE, if no cache entry exists for the given id.
*/
public function fetch($id);
/**
* Tests if an entry exists in the cache.
*
* @param string $id The cache id of the entry to check for.
*
* @return bool TRUE if a cache entry exists for the given cache id, FALSE otherwise.
*/
public function contains($id);
/**
* Puts data into the cache.
*
* If a cache entry with the given id already exists, its data will be replaced.
*
* @param string $id The cache id.
* @param mixed $data The cache entry/data.
* @param int $lifeTime The lifetime in number of seconds for this cache entry.
* If zero (the default), the entry never expires (although it may be deleted from the cache
* to make place for other entries).
*
* @return bool TRUE if the entry was successfully stored in the cache, FALSE otherwise.
*/
public function save($id, $data, $lifeTime = 0);
/**
* Deletes a cache entry.
*
* @param string $id The cache id.
*
* @return bool TRUE if the cache entry was successfully deleted, FALSE otherwise.
* Deleting a non-existing entry is considered successful.
*/
public function delete($id);
/**
* Retrieves cached information from the data store.
*
* The server's statistics array has the following values:
*
* - <b>hits</b>
* Number of keys that have been requested and found present.
*
* - <b>misses</b>
* Number of items that have been requested and not found.
*
* - <b>uptime</b>
* Time that the server is running.
*
* - <b>memory_usage</b>
* Memory used by this server to store items.
*
* - <b>memory_available</b>
* Memory allowed to use for storage.
*
* @since 2.2
*
* @return array|null An associative array with server's statistics if available, NULL otherwise.
*/
public function getStats();
}

View File

@@ -0,0 +1,312 @@
<?php
/*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This software consists of voluntary contributions made by many individuals
* and is licensed under the MIT license. For more information, see
* <http://www.doctrine-project.org>.
*/
namespace Doctrine\Common\Cache;
/**
* Base class for cache provider implementations.
*
* @since 2.2
* @author Benjamin Eberlei <kontakt@beberlei.de>
* @author Guilherme Blanco <guilhermeblanco@hotmail.com>
* @author Jonathan Wage <jonwage@gmail.com>
* @author Roman Borschel <roman@code-factory.org>
* @author Fabio B. Silva <fabio.bat.silva@gmail.com>
*/
abstract class CacheProvider implements Cache, FlushableCache, ClearableCache, MultiGetCache, MultiPutCache
{
const DOCTRINE_NAMESPACE_CACHEKEY = 'DoctrineNamespaceCacheKey[%s]';
/**
* The namespace to prefix all cache ids with.
*
* @var string
*/
private $namespace = '';
/**
* The namespace version.
*
* @var integer|null
*/
private $namespaceVersion;
/**
* Sets the namespace to prefix all cache ids with.
*
* @param string $namespace
*
* @return void
*/
public function setNamespace($namespace)
{
$this->namespace = (string) $namespace;
$this->namespaceVersion = null;
}
/**
* Retrieves the namespace that prefixes all cache ids.
*
* @return string
*/
public function getNamespace()
{
return $this->namespace;
}
/**
* {@inheritdoc}
*/
public function fetch($id)
{
return $this->doFetch($this->getNamespacedId($id));
}
/**
* {@inheritdoc}
*/
public function fetchMultiple(array $keys)
{
if (empty($keys)) {
return array();
}
// note: the array_combine() is in place to keep an association between our $keys and the $namespacedKeys
$namespacedKeys = array_combine($keys, array_map(array($this, 'getNamespacedId'), $keys));
$items = $this->doFetchMultiple($namespacedKeys);
$foundItems = array();
// no internal array function supports this sort of mapping: needs to be iterative
// this filters and combines keys in one pass
foreach ($namespacedKeys as $requestedKey => $namespacedKey) {
if (isset($items[$namespacedKey]) || array_key_exists($namespacedKey, $items)) {
$foundItems[$requestedKey] = $items[$namespacedKey];
}
}
return $foundItems;
}
/**
* {@inheritdoc}
*/
public function saveMultiple(array $keysAndValues, $lifetime = 0)
{
$namespacedKeysAndValues = array();
foreach ($keysAndValues as $key => $value) {
$namespacedKeysAndValues[$this->getNamespacedId($key)] = $value;
}
return $this->doSaveMultiple($namespacedKeysAndValues, $lifetime);
}
/**
* {@inheritdoc}
*/
public function contains($id)
{
return $this->doContains($this->getNamespacedId($id));
}
/**
* {@inheritdoc}
*/
public function save($id, $data, $lifeTime = 0)
{
return $this->doSave($this->getNamespacedId($id), $data, $lifeTime);
}
/**
* {@inheritdoc}
*/
public function delete($id)
{
return $this->doDelete($this->getNamespacedId($id));
}
/**
* {@inheritdoc}
*/
public function getStats()
{
return $this->doGetStats();
}
/**
* {@inheritDoc}
*/
public function flushAll()
{
return $this->doFlush();
}
/**
* {@inheritDoc}
*/
public function deleteAll()
{
$namespaceCacheKey = $this->getNamespaceCacheKey();
$namespaceVersion = $this->getNamespaceVersion() + 1;
if ($this->doSave($namespaceCacheKey, $namespaceVersion)) {
$this->namespaceVersion = $namespaceVersion;
return true;
}
return false;
}
/**
* Prefixes the passed id with the configured namespace value.
*
* @param string $id The id to namespace.
*
* @return string The namespaced id.
*/
private function getNamespacedId($id)
{
$namespaceVersion = $this->getNamespaceVersion();
return sprintf('%s[%s][%s]', $this->namespace, $id, $namespaceVersion);
}
/**
* Returns the namespace cache key.
*
* @return string
*/
private function getNamespaceCacheKey()
{
return sprintf(self::DOCTRINE_NAMESPACE_CACHEKEY, $this->namespace);
}
/**
* Returns the namespace version.
*
* @return integer
*/
private function getNamespaceVersion()
{
if (null !== $this->namespaceVersion) {
return $this->namespaceVersion;
}
$namespaceCacheKey = $this->getNamespaceCacheKey();
$this->namespaceVersion = $this->doFetch($namespaceCacheKey) ?: 1;
return $this->namespaceVersion;
}
/**
* Default implementation of doFetchMultiple. Each driver that supports multi-get should owerwrite it.
*
* @param array $keys Array of keys to retrieve from cache
* @return array Array of values retrieved for the given keys.
*/
protected function doFetchMultiple(array $keys)
{
$returnValues = array();
foreach ($keys as $key) {
if (false !== ($item = $this->doFetch($key)) || $this->doContains($key)) {
$returnValues[$key] = $item;
}
}
return $returnValues;
}
/**
* Fetches an entry from the cache.
*
* @param string $id The id of the cache entry to fetch.
*
* @return mixed|false The cached data or FALSE, if no cache entry exists for the given id.
*/
abstract protected function doFetch($id);
/**
* Tests if an entry exists in the cache.
*
* @param string $id The cache id of the entry to check for.
*
* @return bool TRUE if a cache entry exists for the given cache id, FALSE otherwise.
*/
abstract protected function doContains($id);
/**
* Default implementation of doSaveMultiple. Each driver that supports multi-put should override it.
*
* @param array $keysAndValues Array of keys and values to save in cache
* @param int $lifetime The lifetime. If != 0, sets a specific lifetime for these
* cache entries (0 => infinite lifeTime).
*
* @return bool TRUE if the operation was successful, FALSE if it wasn't.
*/
protected function doSaveMultiple(array $keysAndValues, $lifetime = 0)
{
$success = true;
foreach ($keysAndValues as $key => $value) {
if (!$this->doSave($key, $value, $lifetime)) {
$success = false;
}
}
return $success;
}
/**
* Puts data into the cache.
*
* @param string $id The cache id.
* @param string $data The cache entry/data.
* @param int $lifeTime The lifetime. If != 0, sets a specific lifetime for this
* cache entry (0 => infinite lifeTime).
*
* @return bool TRUE if the entry was successfully stored in the cache, FALSE otherwise.
*/
abstract protected function doSave($id, $data, $lifeTime = 0);
/**
* Deletes a cache entry.
*
* @param string $id The cache id.
*
* @return bool TRUE if the cache entry was successfully deleted, FALSE otherwise.
*/
abstract protected function doDelete($id);
/**
* Flushes all cache entries.
*
* @return bool TRUE if the cache entries were successfully flushed, FALSE otherwise.
*/
abstract protected function doFlush();
/**
* Retrieves cached information from the data store.
*
* @since 2.2
*
* @return array|null An associative array with server's statistics if available, NULL otherwise.
*/
abstract protected function doGetStats();
}

Some files were not shown because too many files have changed in this diff Show More