Compare commits

..

1198 Commits
v2.1.2 ... 2.3

Author SHA1 Message Date
James Brooks
7ed480dd64 Merge pull request #4203 from fiveai/fix-api-search-with-pagination
Fix API search with pagination when specifying page
2021-03-29 11:54:58 +01:00
Seb Dangerfield
c040fc334c Ensure only allowed searchable columns are used in DB Query 2021-01-15 18:38:29 +00:00
Seb Dangerfield
48fdf79a8f Test API Pagination and searching 2021-01-15 17:10:19 +00:00
James Brooks
fe3675ff33 Apply fixes from StyleCI (#4072) 2020-08-01 09:18:12 +01:00
James Brooks
94b4fe2d39 Merge pull request #3601 from CachetHQ/l10n_2.3
New Crowdin translations
2020-08-01 09:17:48 +01:00
Cachet Bot
23cd590815 New translations pagination.php (Afrikaans) 2020-07-16 18:01:00 +01:00
Cachet Bot
748962b1c6 New translations forms.php (Swedish) 2020-04-27 09:12:19 +01:00
Cachet Bot
6f0ccb7e76 New translations forms.php (Russian) 2020-04-27 09:12:16 +01:00
Cachet Bot
0c637cc683 New translations forms.php (Vietnamese) 2020-04-27 09:11:44 +01:00
Cachet Bot
ec26e01e8d New translations validation.php (Portuguese, Brazilian) 2020-04-27 09:11:41 +01:00
Cachet Bot
9caecd3268 New translations forms.php (Danish) 2020-04-27 09:11:27 +01:00
Cachet Bot
f7ab99483c New translations forms.php (Romanian) 2020-04-27 09:11:13 +01:00
Cachet Bot
b9c9d28b59 New translations pagination.php (Afrikaans) 2020-04-27 09:11:03 +01:00
Cachet Bot
1d32adb0e6 New translations dashboard.php (Norwegian) 2020-04-27 09:10:47 +01:00
Cachet Bot
e36abd5ce4 New translations forms.php (Polish) 2020-04-27 09:10:41 +01:00
Cachet Bot
735c722918 New translations dashboard.php (Korean) 2020-04-27 09:10:15 +01:00
Cachet Bot
a588cfbd0a New translations validation.php (Czech) 2020-02-18 13:00:12 +00:00
Cachet Bot
8f0e56873e New translations setup.php (Chinese Simplified) 2020-01-13 06:50:15 +00:00
Cachet Bot
dfcf9bd392 New translations forms.php (Chinese Simplified) 2020-01-13 06:50:13 +00:00
Cachet Bot
52c93a0dfe New translations dashboard.php (Chinese Simplified) 2020-01-13 06:50:12 +00:00
Cachet Bot
28a896bf02 New translations cachet.php (Chinese Simplified) 2020-01-13 06:50:11 +00:00
Cachet Bot
06faecf3a7 New translations dashboard.php (Chinese Simplified) 2019-12-10 14:40:22 +00:00
James Brooks
5dfeaa3b6a Merge pull request #3845 from tomecho/2.3-3844-fix
add is_object check for feed result, fixes #3844
2019-11-05 21:43:26 +00:00
Tom Peck
18f5c29a16 add is_object check for feed result, fixes #3844 2019-11-05 15:43:46 -05:00
Cachet Bot
3681d277a4 New translations forms.php (Portuguese, Brazilian) 2019-11-02 10:50:13 +00:00
James Brooks
6752596ba8 Merge pull request #3712 from sigv/bugfix/2.3/gravatar-lowercase
Lowercase email for Gravatar avatars
2019-08-14 07:23:52 +01:00
Cachet Bot
d02ec7f150 New translations cachet.php (Russian) 2019-08-02 23:40:12 +01:00
Valters Jansons
300961cad4 Lowercase email for Gravatar avatars
The Gravatar docs explicitly say that e-mail addresses have
to be lowercased before hashing. In the `2.4` branch this was
already resolved in `0f4c14ac0820562a3155d6f60ea4a7770d19084b`
back in 2016 so it is safe to backport that change to the
latest stable branch for a maintenance patch release.
2019-07-16 21:58:20 +03:00
Cachet Bot
12b6888feb New translations setup.php (Japanese) 2019-07-16 10:50:30 +01:00
Cachet Bot
dde38b08d3 New translations dashboard.php (Japanese) 2019-07-16 10:50:29 +01:00
Cachet Bot
0bdf3f35aa New translations cachet.php (Japanese) 2019-07-16 10:50:27 +01:00
Cachet Bot
1a053ff5b8 New translations forms.php (Polish) 2019-07-11 13:21:54 +01:00
Cachet Bot
7f54029bad New translations forms.php (Norwegian) 2019-07-11 13:21:49 +01:00
Cachet Bot
f50a2c717e New translations forms.php (Italian) 2019-07-11 13:21:46 +01:00
Cachet Bot
a4ab01d9dc New translations forms.php (German) 2019-07-11 13:21:41 +01:00
Cachet Bot
dfa1650936 New translations forms.php (Indonesian) 2019-07-11 13:21:36 +01:00
Cachet Bot
b3f4eb261a New translations forms.php (Swedish) 2019-07-11 13:21:25 +01:00
Cachet Bot
552c029682 New translations forms.php (Zulu) 2019-07-11 13:21:21 +01:00
Cachet Bot
ce833c52bc New translations cachet.php (Zulu) 2019-07-11 13:21:19 +01:00
Cachet Bot
61acfd5dab New translations forms.php (Romanian) 2019-07-11 13:21:13 +01:00
Cachet Bot
72f6b7185d New translations forms.php (Portuguese) 2019-07-11 13:21:07 +01:00
Cachet Bot
39e670edb5 New translations validation.php (Portuguese, Brazilian) 2019-07-11 13:21:05 +01:00
Cachet Bot
0f99a14bd6 New translations forms.php (Spanish) 2019-07-11 13:21:03 +01:00
Cachet Bot
18cccd9a76 New translations forms.php (Russian) 2019-07-11 13:20:57 +01:00
Cachet Bot
f15709850d New translations forms.php (Chinese Simplified) 2019-07-11 13:20:53 +01:00
Cachet Bot
a24604b169 New translations forms.php (Chinese Traditional) 2019-07-11 13:20:49 +01:00
Cachet Bot
5cb438a30b New translations forms.php (French) 2019-07-11 13:20:30 +01:00
Cachet Bot
b43974eb48 New translations forms.php (Danish) 2019-07-11 13:20:26 +01:00
Cachet Bot
c020fd50b7 New translations validation.php (Dutch) 2019-07-11 13:20:23 +01:00
Cachet Bot
b76acbeee1 New translations forms.php (Dutch) 2019-07-11 13:20:22 +01:00
Cachet Bot
f46371bde0 New translations dashboard.php (Czech) 2019-06-25 10:20:15 +01:00
Cachet Bot
5853b43da1 New translations dashboard.php (Czech) 2019-06-25 10:10:14 +01:00
Cachet Bot
d2f3572ffc New translations forms.php (Czech) 2019-06-25 10:00:12 +01:00
Cachet Bot
8b98141c61 New translations cachet.php (Czech) 2019-06-25 10:00:10 +01:00
James Brooks
59ef9023d5 Merge pull request #3645 from anthonybocci/feature/3618-setup-assets-path
Allow Cachet setup not to be at server's root
2019-06-23 08:14:14 +01:00
Cachet Bot
1c371e9fe3 New translations setup.php (Czech) 2019-06-20 15:20:21 +01:00
Cachet Bot
cb518d0d14 New translations validation.php (Czech) 2019-06-20 15:20:20 +01:00
Cachet Bot
64dd4cbf9c New translations pagination.php (Czech) 2019-06-20 15:20:19 +01:00
Cachet Bot
c0513da918 New translations forms.php (Czech) 2019-06-20 15:20:18 +01:00
Cachet Bot
393669beae New translations dashboard.php (Czech) 2019-06-20 15:20:16 +01:00
Cachet Bot
1dfc3683ce New translations forms.php (Czech) 2019-06-20 15:10:16 +01:00
Cachet Bot
99d95a8e11 New translations dashboard.php (Czech) 2019-06-20 15:10:14 +01:00
Cachet Bot
48e8bc84f8 New translations cachet.php (Czech) 2019-06-20 15:00:16 +01:00
Cachet Bot
3e065f6c9c New translations cachet.php (Czech) 2019-06-20 14:30:26 +01:00
Cachet Bot
249de039f6 New translations cachet.php (Czech) 2019-06-20 14:00:18 +01:00
Cachet Bot
cba2eece5f New translations cachet.php (Czech) 2019-06-20 13:50:26 +01:00
Anthony Bocci
fbf141c39d Allow Cachet setup not to be at server's root
Cachet may be installed at the root of its vhost or in a subdirectory,
for example in "/" or under "/status".

The URI we found pointing to some assets were usually not prefixed with
the path, so if Cachet was installed under "/status" the asset
URI pointed to the server root like "/my-asset.js".
It is a problem because that means the behaviour is broken in this case.
The problem was present from the setup, it was not possible to fill the
setup since the path to the scripts and CSS weres wrong.

The "asset" helper is now used and resolves the URI.

See: CachetHQ#3618
2019-06-19 11:20:04 +02:00
Cachet Bot
b639d1e5ab New translations cachet.php (Czech) 2019-06-18 08:50:13 +01:00
Graham Campbell
168e36f224 Updated with the latest cloudflare ips (#3650) 2019-06-15 18:04:26 +01:00
Graham Campbell
87b5b67be4 Upgraded deps (#3616) 2019-05-22 14:24:33 +01:00
James Brooks
f79eef0e88 Merge pull request #3615 from CachetHQ/extra-spaces
Removed extra spaces
2019-05-22 13:56:30 +01:00
Graham Campbell
30978bd125 Removed extra spaces 2019-05-22 13:44:45 +01:00
James Brooks
22b6135541 Bump version for dev 2019-05-14 13:27:46 +01:00
James Brooks
cc2f4de125 Fix version 2019-05-14 13:27:19 +01:00
James Brooks
baea4e9a03 Bump version 2019-05-14 13:25:42 +01:00
James Brooks
1bc48e0c60 Fix view import 2019-05-14 13:25:32 +01:00
Cachet Bot
0d5cfb17d4 New translations setup.php (Portuguese, Brazilian) 2019-05-14 01:50:12 +01:00
Cachet Bot
429719585f New translations dashboard.php (Portuguese, Brazilian) 2019-05-14 01:50:11 +01:00
Cachet Bot
63a2d9445b New translations dashboard.php (Portuguese, Brazilian) 2019-05-14 01:40:12 +01:00
Cachet Bot
967961787c New translations cachet.php (Portuguese, Brazilian) 2019-05-14 01:40:10 +01:00
Cachet Bot
e281597260 New translations cachet.php (Portuguese, Brazilian) 2019-05-14 01:30:09 +01:00
Cachet Bot
c6b4d9ed5e New translations cachet.php (Portuguese, Brazilian) 2019-05-14 01:20:10 +01:00
Cachet Bot
31eb7086a2 New translations dashboard.php (Portuguese, Brazilian) 2019-05-14 01:10:11 +01:00
Cachet Bot
ae874c704e New translations forms.php (Portuguese, Brazilian) 2019-05-14 01:00:15 +01:00
Cachet Bot
7b2b90a78d New translations cachet.php (Portuguese, Brazilian) 2019-05-14 01:00:13 +01:00
James Brooks
1d6b117a55 Bump for dev 2019-05-13 20:33:18 +01:00
James Brooks
7a08cfd00a Release v2.3.17 2019-05-13 20:32:54 +01:00
James Brooks
52fda22acc Apply fixes from StyleCI (#3599) 2019-05-13 20:31:04 +01:00
James Brooks
9531a909d4 Prevent calling of DashboardComposer 2019-05-13 20:30:39 +01:00
James Brooks
5fcc0ce2f6 Don't need to call all() 2019-05-13 20:30:28 +01:00
James Brooks
843eabbcc3 Fixes #3598 2019-05-13 20:29:47 +01:00
Graham Campbell
16f057500b Bumped version for dev (#3588) 2019-05-13 14:31:09 +01:00
Graham Campbell
e477de77be Release v2.3.16 (#3585) 2019-05-12 23:47:56 +01:00
Graham Campbell
e7066864e2 Cachet 2.3 is known to work on PHP 7.0 and 7.1 (#3584) 2019-05-12 20:01:52 +01:00
Graham Campbell
16932219a7 Upgraded deps (#3582) 2019-05-12 19:16:31 +01:00
James Brooks
512e1a6661 Apply fixes from StyleCI (#3565) 2019-04-25 13:10:55 +01:00
James Brooks
0e5bb00f44 Merge pull request #3564 from CachetHQ/l10n_2.3
New Crowdin translations
2019-04-25 13:10:05 +01:00
Cachet Bot
6aed3531dd New translations forms.php (German) 2019-04-25 10:21:43 +01:00
James Brooks
6e79575a1c Merge pull request #3530 from CachetHQ/l10n_2.3
New Crowdin translations
2019-04-01 08:18:00 +01:00
Cachet Bot
61a371520d New translations dashboard.php (German) 2019-03-28 08:10:26 +00:00
James Brooks
1f46e06e80 Apply fixes from StyleCI (#3511) 2019-03-11 20:42:33 +00:00
James Brooks
0e82925f95 Merge pull request #3510 from CachetHQ/l10n_2.3
New Crowdin translations
2019-03-11 20:42:15 +00:00
Cachet Bot
c3cfeeb14c New translations forms.php (Swedish) 2019-03-11 09:00:13 +00:00
James Brooks
7738c73860 Apply fixes from StyleCI (#3505) 2019-03-09 08:50:34 +00:00
James Brooks
d8eb86e4d2 Merge pull request #3501 from CachetHQ/l10n_2.3
New Crowdin translations
2019-03-09 08:49:51 +00:00
Cachet Bot
48ab04c425 New translations forms.php (Romanian) 2019-03-06 20:50:11 +00:00
James Brooks
035164fae6 2.3 is not compatible with PHP7 2019-02-01 22:37:23 +00:00
James Brooks
d4bcdf0e29 Apply fixes from StyleCI (#3436) 2019-01-26 17:06:21 +00:00
James Brooks
f41aa311c5 Merge pull request #3401 from CachetHQ/l10n_2.3
New Crowdin translations
2019-01-26 17:05:46 +00:00
Cachet Bot
ef7236c16b New translations setup.php (Slovenian) 2019-01-26 11:40:20 +00:00
Cachet Bot
84915404b9 New translations forms.php (Slovenian) 2019-01-26 11:40:19 +00:00
Cachet Bot
6dfadc2f94 New translations dashboard.php (Slovenian) 2019-01-26 11:40:18 +00:00
Cachet Bot
7f6effff96 New translations validation.php (Slovenian) 2019-01-26 11:40:16 +00:00
Cachet Bot
63589167f3 New translations pagination.php (Slovenian) 2019-01-26 11:40:15 +00:00
Cachet Bot
9e96f28ddf New translations cachet.php (Slovenian) 2019-01-26 11:40:14 +00:00
Cachet Bot
6d920b2111 New translations setup.php (Mongolian) 2019-01-26 11:40:13 +00:00
Cachet Bot
760a034c0c New translations forms.php (Mongolian) 2019-01-26 11:40:12 +00:00
Cachet Bot
0a9d1b313a New translations dashboard.php (Mongolian) 2019-01-26 11:40:11 +00:00
Cachet Bot
e9020d3e08 New translations validation.php (Mongolian) 2019-01-26 11:40:10 +00:00
Cachet Bot
d61c9d190f New translations pagination.php (Mongolian) 2019-01-26 11:40:09 +00:00
Cachet Bot
520785b5ca New translations cachet.php (Mongolian) 2019-01-26 11:40:08 +00:00
Cachet Bot
dd0052a50f New translations setup.php (German) 2019-01-15 13:10:13 +00:00
Cachet Bot
cd48270cad New translations cachet.php (German) 2019-01-15 13:10:11 +00:00
Cachet Bot
79b837d65f New translations setup.php (Dutch) 2019-01-03 18:00:13 +00:00
Cachet Bot
5f639b718f New translations dashboard.php (Dutch) 2019-01-03 18:00:12 +00:00
Cachet Bot
eb18e7d982 New translations cachet.php (Dutch) 2019-01-03 18:00:11 +00:00
Cachet Bot
cd70023bbe New translations forms.php (Dutch) 2019-01-03 18:00:10 +00:00
Cachet Bot
4277ec77e4 New translations cachet.php (Dutch) 2019-01-03 17:20:11 +00:00
James Brooks
1f1cf5a242 Merge pull request #3388 from CachetHQ/l10n_2.3
New Crowdin translations
2019-01-01 10:59:41 +00:00
Cachet Bot
495f118116 New translations cachet.php (Dutch) 2018-12-31 09:30:07 +00:00
James Brooks
171588c3a5 Merge pull request #3386 from CachetHQ/l10n_2.3
New Crowdin translations
2018-12-30 17:06:44 +00:00
Cachet Bot
72def0eb60 New translations forms.php (Afrikaans) 2018-12-30 11:00:09 +00:00
Cachet Bot
79a8026191 New translations dashboard.php (Afrikaans) 2018-12-30 11:00:08 +00:00
James Brooks
11bb77b944 Merge pull request #3380 from CachetHQ/l10n_2.3
New Crowdin translations
2018-12-29 18:56:41 +00:00
Cachet Bot
3f932a2ec2 Apply fixes from StyleCI 2018-12-29 17:50:13 +00:00
Cachet Bot
9f0a11eeb4 New translations forms.php (Dutch) 2018-12-29 17:50:07 +00:00
Cachet Bot
34f5775bd8 New translations dashboard.php (German) 2018-12-29 12:40:07 +00:00
Cachet Bot
2a4a7d72a2 New translations dashboard.php (German) 2018-12-29 12:30:08 +00:00
James Brooks
2dd7fba3e1 Merge pull request #3359 from CachetHQ/l10n_2.3
New Crowdin translations
2018-12-27 22:07:36 +00:00
Cachet Bot
ac91ba5d67 New translations setup.php (Swedish) 2018-12-10 23:50:10 +00:00
Cachet Bot
2a04e8907c New translations cachet.php (Swedish) 2018-12-10 23:50:08 +00:00
Cachet Bot
c66f66a6f4 New translations cachet.php (Swedish) 2018-12-10 23:40:08 +00:00
James Brooks
589f82af84 Merge pull request #3335 from CachetHQ/l10n_2.3
New Crowdin translations
2018-11-23 11:20:01 +00:00
Cachet Bot
ef91bacc35 Apply fixes from StyleCI 2018-11-19 17:41:38 +00:00
Cachet Bot
84f1f2fe0b New translations forms.php (German) 2018-11-19 17:41:33 +00:00
Cachet Bot
525563c3c0 New translations forms.php (French) 2018-11-19 17:41:30 +00:00
Cachet Bot
4b8bc99b5e Apply fixes from StyleCI 2018-11-19 17:41:28 +00:00
Cachet Bot
66a300cade New translations forms.php (Indonesian) 2018-11-19 17:41:22 +00:00
Cachet Bot
68f80c2f95 New translations forms.php (Dutch) 2018-11-19 17:41:05 +00:00
Cachet Bot
a087b2a21a New translations forms.php (Chinese Simplified) 2018-11-19 17:41:03 +00:00
Cachet Bot
f155bfa419 New translations forms.php (Danish) 2018-11-19 17:41:01 +00:00
Cachet Bot
255922804c New translations forms.php (Chinese Traditional) 2018-11-19 17:40:56 +00:00
Cachet Bot
7191bdacf8 New translations forms.php (Swedish) 2018-11-19 17:40:49 +00:00
Cachet Bot
491b07d498 New translations forms.php (Spanish) 2018-11-19 17:40:46 +00:00
Cachet Bot
467453c29d New translations forms.php (Russian) 2018-11-19 17:40:44 +00:00
Cachet Bot
8d42f0f97b New translations forms.php (Zulu) 2018-11-19 17:40:39 +00:00
Cachet Bot
fc170bea0a New translations cachet.php (Zulu) 2018-11-19 17:40:37 +00:00
Cachet Bot
d455f56243 New translations forms.php (Italian) 2018-11-19 17:40:32 +00:00
Cachet Bot
cef1d82d8c New translations forms.php (Norwegian) 2018-11-19 17:40:29 +00:00
Cachet Bot
e7caa3ca37 Apply fixes from StyleCI 2018-11-19 17:40:26 +00:00
Cachet Bot
2a320477e3 New translations forms.php (Romanian) 2018-11-19 17:40:19 +00:00
Cachet Bot
1c593bb2f1 New translations forms.php (Portuguese, Brazilian) 2018-11-19 17:40:17 +00:00
Cachet Bot
e557e5eb9b New translations forms.php (Portuguese) 2018-11-19 17:40:14 +00:00
Cachet Bot
33ed227c97 New translations forms.php (Polish) 2018-11-19 17:40:10 +00:00
James Brooks
f4dc5d09ab Merge pull request #3278 from CachetHQ/l10n_2.3
New Crowdin translations
2018-11-13 14:24:58 +00:00
Cachet Bot
d86d2e8201 New translations cachet.php (Japanese) 2018-11-05 07:00:07 +00:00
Cachet Bot
9ac9b5898e Apply fixes from StyleCI 2018-10-18 16:50:16 +00:00
Cachet Bot
1eea552d6e New translations forms.php (Russian) 2018-10-18 17:50:07 +01:00
Cachet Bot
3fd9bfe00d New translations setup.php (Estonian) 2018-10-15 12:40:15 +01:00
Cachet Bot
282ee9802d New translations forms.php (Estonian) 2018-10-15 12:40:14 +01:00
Cachet Bot
ce7104d679 New translations dashboard.php (Estonian) 2018-10-15 12:40:13 +01:00
Cachet Bot
bcdaec1d3a New translations validation.php (Estonian) 2018-10-15 12:40:12 +01:00
Cachet Bot
53e1837368 New translations pagination.php (Estonian) 2018-10-15 12:40:11 +01:00
Cachet Bot
b8324c3e7c New translations cachet.php (Estonian) 2018-10-15 12:40:09 +01:00
James Brooks
7ea832de8e Merge pull request #3248 from CachetHQ/l10n_2.3
New Crowdin translations
2018-10-15 12:39:05 +01:00
Cachet Bot
368045b418 Apply fixes from StyleCI 2018-10-09 11:01:37 +00:00
Cachet Bot
0bfaeaa4fc New translations forms.php (French) 2018-10-09 12:01:31 +01:00
Cachet Bot
3f9ba0ee97 New translations forms.php (Dutch) 2018-10-09 12:01:24 +01:00
Cachet Bot
045bbeeba0 New translations forms.php (German) 2018-10-09 12:01:23 +01:00
Cachet Bot
5cce6d4184 New translations forms.php (Indonesian) 2018-10-09 12:01:21 +01:00
Cachet Bot
9f1dd6fedc Apply fixes from StyleCI 2018-10-09 11:01:18 +00:00
Cachet Bot
ddb2972a4a New translations forms.php (Danish) 2018-10-09 12:01:03 +01:00
Cachet Bot
ba84e3ee23 New translations forms.php (Chinese Traditional) 2018-10-09 12:00:57 +01:00
Cachet Bot
400c94d06d New translations forms.php (Chinese Simplified) 2018-10-09 12:00:54 +01:00
Cachet Bot
ebe31e2070 New translations forms.php (Swedish) 2018-10-09 12:00:50 +01:00
Cachet Bot
7b29049dd7 New translations forms.php (Russian) 2018-10-09 12:00:45 +01:00
Cachet Bot
ee73222638 New translations forms.php (Spanish) 2018-10-09 12:00:42 +01:00
Cachet Bot
6f1cba91df New translations forms.php (Zulu) 2018-10-09 12:00:40 +01:00
Cachet Bot
b313c45cd2 New translations cachet.php (Zulu) 2018-10-09 12:00:38 +01:00
Cachet Bot
3e35d29d8f New translations forms.php (Romanian) 2018-10-09 12:00:31 +01:00
Cachet Bot
8ffa6c7996 New translations forms.php (Norwegian) 2018-10-09 12:00:29 +01:00
Cachet Bot
07750e9365 New translations forms.php (Italian) 2018-10-09 12:00:21 +01:00
Cachet Bot
63a79d9d19 New translations forms.php (Portuguese, Brazilian) 2018-10-09 12:00:17 +01:00
Cachet Bot
12efe8113e New translations forms.php (Portuguese) 2018-10-09 12:00:14 +01:00
Cachet Bot
d8c6be3f9e New translations forms.php (Polish) 2018-10-09 12:00:11 +01:00
Cachet Bot
8bffaa5c9a Apply fixes from StyleCI 2018-09-28 08:40:21 +00:00
Cachet Bot
6bf9221d74 New translations forms.php (Norwegian) 2018-09-28 09:40:13 +01:00
Cachet Bot
fa5875da76 New translations cachet.php (Afrikaans) 2018-09-20 13:40:05 +01:00
Cachet Bot
34a36bc6c1 New translations cachet.php (Afrikaans) 2018-09-20 13:30:05 +01:00
James Brooks
f8a35d71b4 Merge pull request #3198 from CachetHQ/l10n_2.3
New Crowdin translations
2018-08-07 08:51:02 +01:00
James Brooks
8a8edea07a Merge pull request #3209 from CachetHQ/update-deps
Update deps
2018-08-06 18:55:38 +01:00
Cachet Bot
e3973414cd Apply fixes from StyleCI 2018-08-04 08:50:14 +00:00
Cachet Bot
9bb670cb95 New translations forms.php (Dutch) 2018-08-04 09:50:07 +01:00
James Brooks
127996f08f Update deps. Closes #3207 2018-08-03 20:58:20 +01:00
Cachet Bot
a6768da7bb Apply fixes from StyleCI
[ci skip] [skip ci]
2018-08-03 18:00:48 +00:00
Cachet Bot
123f05bd84 New translations forms.php (Spanish) 2018-08-03 19:00:08 +01:00
Cachet Bot
ecc91abcae Apply fixes from StyleCI
[ci skip] [skip ci]
2018-07-27 23:40:13 +00:00
Cachet Bot
bb9def5821 New translations setup.php (French) 2018-07-28 00:40:07 +01:00
Cachet Bot
11cbbb42fb New translations forms.php (French) 2018-07-28 00:40:06 +01:00
Cachet Bot
b361618ec0 New translations dashboard.php (French) 2018-07-28 00:30:06 +01:00
Cachet Bot
ee288e0505 New translations cachet.php (French) 2018-07-28 00:30:05 +01:00
Cachet Bot
7c5e214b1c Apply fixes from StyleCI
[ci skip] [skip ci]
2018-07-25 14:51:56 +00:00
Cachet Bot
0e1d52b3bc New translations forms.php (Chinese Simplified) 2018-07-25 15:51:07 +01:00
James Brooks
77d576fd39 Merge pull request #3189 from CachetHQ/l10n_2.3
New Crowdin translations
2018-07-21 09:12:41 +01:00
James Brooks
73fb33d03e Update VERSION 2018-07-21 09:11:04 +01:00
Cachet Bot
2746001cdb Apply fixes from StyleCI
[ci skip] [skip ci]
2018-07-17 13:00:28 +00:00
Cachet Bot
036da9248d New translations forms.php (French) 2018-07-17 14:00:19 +01:00
James Brooks
2d72914205 Merge pull request #3184 from CachetHQ/l10n_2.3
New Crowdin translations
2018-07-17 07:52:46 +01:00
Cachet Bot
237ae7dcdc Apply fixes from StyleCI
[ci skip] [skip ci]
2018-07-13 02:30:14 +00:00
Cachet Bot
8408b92d0c New translations forms.php (Russian) 2018-07-13 03:30:06 +01:00
James Brooks
2da10d1694 Apply fixes from StyleCI (#3182)
[ci skip] [skip ci]
2018-07-12 08:36:35 +01:00
James Brooks
7ac2987809 Merge pull request #3181 from CachetHQ/l10n_2.3
New Crowdin translations
2018-07-12 08:36:03 +01:00
Cachet Bot
5f1c3c92c4 New translations forms.php (French) 2018-07-11 22:52:28 +01:00
Cachet Bot
48f68994ba New translations setup.php (Finnish) 2018-07-11 22:52:27 +01:00
Cachet Bot
adfa39f336 New translations forms.php (Finnish) 2018-07-11 22:52:26 +01:00
Cachet Bot
357389908f New translations validation.php (Finnish) 2018-07-11 22:52:25 +01:00
Cachet Bot
a2252707af New translations pagination.php (Finnish) 2018-07-11 22:52:24 +01:00
Cachet Bot
5057dee219 New translations cachet.php (Finnish) 2018-07-11 22:52:23 +01:00
Cachet Bot
430a80535c New translations dashboard.php (Finnish) 2018-07-11 22:52:20 +01:00
Cachet Bot
5c815756fe New translations forms.php (Dutch) 2018-07-11 22:52:19 +01:00
Cachet Bot
b1547b9d74 New translations forms.php (German) 2018-07-11 22:52:18 +01:00
Cachet Bot
42a2825a70 New translations cachet.php (Greek) 2018-07-11 22:52:17 +01:00
Cachet Bot
3dd7d9b41d New translations forms.php (Indonesian) 2018-07-11 22:52:16 +01:00
Cachet Bot
7552177585 New translations validation.php (Indonesian) 2018-07-11 22:52:14 +01:00
Cachet Bot
6120d9627e New translations setup.php (Hungarian) 2018-07-11 22:52:13 +01:00
Cachet Bot
22a7523347 New translations forms.php (Hungarian) 2018-07-11 22:52:12 +01:00
Cachet Bot
b4c052c5ad New translations dashboard.php (Hungarian) 2018-07-11 22:52:11 +01:00
Cachet Bot
0af0e01d31 New translations validation.php (Hungarian) 2018-07-11 22:52:10 +01:00
Cachet Bot
04ca418b32 New translations pagination.php (Hungarian) 2018-07-11 22:52:09 +01:00
Cachet Bot
8ca56c0a47 New translations cachet.php (Hungarian) 2018-07-11 22:52:08 +01:00
Cachet Bot
dccca87e2e New translations forms.php (Hebrew) 2018-07-11 22:52:07 +01:00
Cachet Bot
63b15530f0 New translations dashboard.php (Hebrew) 2018-07-11 22:52:06 +01:00
Cachet Bot
008b7ce3e3 New translations validation.php (Hebrew) 2018-07-11 22:52:05 +01:00
Cachet Bot
e173c616fc New translations pagination.php (Hebrew) 2018-07-11 22:52:04 +01:00
Cachet Bot
63e629df99 New translations cachet.php (Hebrew) 2018-07-11 22:52:04 +01:00
Cachet Bot
c930ecc568 New translations setup.php (Greek) 2018-07-11 22:52:03 +01:00
Cachet Bot
c542fe762c New translations forms.php (Greek) 2018-07-11 22:52:02 +01:00
Cachet Bot
5a6dfce84e New translations dashboard.php (Greek) 2018-07-11 22:52:01 +01:00
Cachet Bot
1fc399085c New translations pagination.php (Greek) 2018-07-11 22:52:00 +01:00
Cachet Bot
dfced9e81c New translations setup.php (Hebrew) 2018-07-11 22:51:59 +01:00
Cachet Bot
e6412e9be5 New translations setup.php (Catalan) 2018-07-11 22:51:57 +01:00
Cachet Bot
6c67e01297 New translations forms.php (Catalan) 2018-07-11 22:51:57 +01:00
Cachet Bot
e4a2ef3df7 New translations dashboard.php (Catalan) 2018-07-11 22:51:56 +01:00
Cachet Bot
560be25f99 New translations pagination.php (Catalan) 2018-07-11 22:51:55 +01:00
Cachet Bot
61a71166b3 New translations cachet.php (Catalan) 2018-07-11 22:51:54 +01:00
Cachet Bot
359cd934c0 New translations setup.php (Arabic) 2018-07-11 22:51:53 +01:00
Cachet Bot
4b45eed503 New translations forms.php (Arabic) 2018-07-11 22:51:52 +01:00
Cachet Bot
73a14d5980 New translations dashboard.php (Arabic) 2018-07-11 22:51:51 +01:00
Cachet Bot
c614bd8e2a New translations validation.php (Arabic) 2018-07-11 22:51:50 +01:00
Cachet Bot
bd26724f4a New translations cachet.php (Chinese Simplified) 2018-07-11 22:51:49 +01:00
Cachet Bot
d7650d1815 New translations pagination.php (Arabic) 2018-07-11 22:51:48 +01:00
Cachet Bot
9975ecab54 New translations setup.php (Albanian) 2018-07-11 22:51:48 +01:00
Cachet Bot
a508a326ca New translations forms.php (Albanian) 2018-07-11 22:51:47 +01:00
Cachet Bot
5d836619c6 New translations dashboard.php (Albanian) 2018-07-11 22:51:46 +01:00
Cachet Bot
4ff927968b New translations pagination.php (Albanian) 2018-07-11 22:51:45 +01:00
Cachet Bot
4a9e2be6ee New translations cachet.php (Albanian) 2018-07-11 22:51:44 +01:00
Cachet Bot
3f92f85cda New translations dashboard.php (Afrikaans) 2018-07-11 22:51:42 +01:00
Cachet Bot
6138a9c4ef New translations cachet.php (Arabic) 2018-07-11 22:51:41 +01:00
Cachet Bot
210ac14e73 New translations validation.php (Dutch) 2018-07-11 22:51:40 +01:00
Cachet Bot
e5b17f1ce7 New translations dashboard.php (Chinese Simplified) 2018-07-11 22:51:39 +01:00
Cachet Bot
3a31fb01d6 New translations setup.php (Danish) 2018-07-11 22:51:38 +01:00
Cachet Bot
ff97806361 New translations forms.php (Danish) 2018-07-11 22:51:37 +01:00
Cachet Bot
b12fdb61cb New translations dashboard.php (Danish) 2018-07-11 22:51:36 +01:00
Cachet Bot
75a12767e2 New translations validation.php (Danish) 2018-07-11 22:51:35 +01:00
Cachet Bot
b4df0d7aae New translations cachet.php (Danish) 2018-07-11 22:51:34 +01:00
Cachet Bot
b4a618f362 New translations setup.php (Czech) 2018-07-11 22:51:33 +01:00
Cachet Bot
0af3fbc86c New translations forms.php (Czech) 2018-07-11 22:51:32 +01:00
Cachet Bot
8ed5ea3174 New translations dashboard.php (Czech) 2018-07-11 22:51:31 +01:00
Cachet Bot
6f98fefb85 New translations validation.php (Czech) 2018-07-11 22:51:30 +01:00
Cachet Bot
4b0a1da1b9 New translations cachet.php (Czech) 2018-07-11 22:51:29 +01:00
Cachet Bot
89779d9e3c New translations setup.php (Chinese Traditional) 2018-07-11 22:51:28 +01:00
Cachet Bot
8b4ab5f09b New translations forms.php (Chinese Traditional) 2018-07-11 22:51:27 +01:00
Cachet Bot
c077c692ed New translations dashboard.php (Chinese Traditional) 2018-07-11 22:51:26 +01:00
Cachet Bot
dea9ebbfc9 New translations validation.php (Chinese Traditional) 2018-07-11 22:51:25 +01:00
Cachet Bot
0542cda408 New translations cachet.php (Chinese Traditional) 2018-07-11 22:51:24 +01:00
Cachet Bot
6041431d12 New translations setup.php (Chinese Simplified) 2018-07-11 22:51:23 +01:00
Cachet Bot
6703854224 New translations forms.php (Chinese Simplified) 2018-07-11 22:51:22 +01:00
Cachet Bot
aa8618c163 New translations pagination.php (Czech) 2018-07-11 22:51:21 +01:00
Cachet Bot
c040a42ee7 New translations validation.php (Italian) 2018-07-11 22:51:20 +01:00
Cachet Bot
983e1a781f New translations dashboard.php (Thai) 2018-07-11 22:51:19 +01:00
Cachet Bot
b5256a9558 New translations validation.php (Thai) 2018-07-11 22:51:18 +01:00
Cachet Bot
6058cad6e0 New translations pagination.php (Thai) 2018-07-11 22:51:17 +01:00
Cachet Bot
cb42bde85c New translations cachet.php (Thai) 2018-07-11 22:51:16 +01:00
Cachet Bot
e9104d6182 New translations setup.php (Swedish) 2018-07-11 22:51:15 +01:00
Cachet Bot
1153c0da76 New translations forms.php (Swedish) 2018-07-11 22:51:14 +01:00
Cachet Bot
4e1b1fe4ef New translations dashboard.php (Swedish) 2018-07-11 22:51:13 +01:00
Cachet Bot
0078f1dd1e New translations cachet.php (Swedish) 2018-07-11 22:51:12 +01:00
Cachet Bot
6ed0d2d4c2 New translations forms.php (Thai) 2018-07-11 22:51:11 +01:00
Cachet Bot
4b9a5e8e69 New translations validation.php (Spanish) 2018-07-11 22:51:09 +01:00
Cachet Bot
375c831391 New translations forms.php (Russian) 2018-07-11 22:51:08 +01:00
Cachet Bot
126c088863 New translations validation.php (Russian) 2018-07-11 22:51:07 +01:00
Cachet Bot
9f226eea9c New translations forms.php (Spanish) 2018-07-11 22:51:05 +01:00
Cachet Bot
4ad72633ea New translations setup.php (Thai) 2018-07-11 22:51:04 +01:00
Cachet Bot
2b18410a99 New translations pagination.php (Turkish) 2018-07-11 22:51:03 +01:00
Cachet Bot
2e353fc707 New translations forms.php (Zulu) 2018-07-11 22:51:02 +01:00
Cachet Bot
cb8d4282e4 New translations cachet.php (Zulu) 2018-07-11 22:51:01 +01:00
Cachet Bot
d7fd04b183 New translations setup.php (Vietnamese) 2018-07-11 22:51:00 +01:00
Cachet Bot
3f6b825692 New translations forms.php (Vietnamese) 2018-07-11 22:50:59 +01:00
Cachet Bot
7e95648ff9 New translations dashboard.php (Vietnamese) 2018-07-11 22:50:58 +01:00
Cachet Bot
1dfd481d95 New translations validation.php (Vietnamese) 2018-07-11 22:50:57 +01:00
Cachet Bot
a8f04914fa New translations pagination.php (Vietnamese) 2018-07-11 22:50:56 +01:00
Cachet Bot
1093d2169d New translations cachet.php (Turkish) 2018-07-11 22:50:56 +01:00
Cachet Bot
4098bfe641 New translations cachet.php (Vietnamese) 2018-07-11 22:50:55 +01:00
Cachet Bot
5c51806417 New translations forms.php (Ukrainian) 2018-07-11 22:50:54 +01:00
Cachet Bot
b616842ec0 New translations dashboard.php (Ukrainian) 2018-07-11 22:50:53 +01:00
Cachet Bot
6c693ea4d5 New translations validation.php (Ukrainian) 2018-07-11 22:50:52 +01:00
Cachet Bot
c6d9b62248 New translations pagination.php (Ukrainian) 2018-07-11 22:50:51 +01:00
Cachet Bot
2770036621 New translations cachet.php (Ukrainian) 2018-07-11 22:50:50 +01:00
Cachet Bot
54943af362 New translations setup.php (Turkish) 2018-07-11 22:50:49 +01:00
Cachet Bot
00eba028e5 New translations forms.php (Turkish) 2018-07-11 22:50:48 +01:00
Cachet Bot
421d8c5d05 New translations dashboard.php (Turkish) 2018-07-11 22:50:47 +01:00
Cachet Bot
c28e86c3fa New translations validation.php (Turkish) 2018-07-11 22:50:46 +01:00
Cachet Bot
a6706b7f3f New translations setup.php (Ukrainian) 2018-07-11 22:50:46 +01:00
Cachet Bot
d2fae69bf2 New translations forms.php (Romanian) 2018-07-11 22:50:44 +01:00
Cachet Bot
9abe4962a9 New translations cachet.php (Persian) 2018-07-11 22:50:43 +01:00
Cachet Bot
e009ae4754 New translations forms.php (Norwegian) 2018-07-11 22:50:42 +01:00
Cachet Bot
4213a9a2ca New translations dashboard.php (Norwegian) 2018-07-11 22:50:41 +01:00
Cachet Bot
5da83aed92 New translations validation.php (Norwegian) 2018-07-11 22:50:40 +01:00
Cachet Bot
a159600919 New translations cachet.php (Norwegian) 2018-07-11 22:50:39 +01:00
Cachet Bot
1b0e583a8a New translations setup.php (Korean) 2018-07-11 22:50:38 +01:00
Cachet Bot
1c496338cd New translations forms.php (Korean) 2018-07-11 22:50:38 +01:00
Cachet Bot
f7353c0c64 New translations dashboard.php (Korean) 2018-07-11 22:50:37 +01:00
Cachet Bot
090f4167f2 New translations pagination.php (Persian) 2018-07-11 22:50:36 +01:00
Cachet Bot
3fbf056056 New translations validation.php (Korean) 2018-07-11 22:50:35 +01:00
Cachet Bot
3a554d25ba New translations cachet.php (Korean) 2018-07-11 22:50:34 +01:00
Cachet Bot
dbd0fd57f2 New translations setup.php (Japanese) 2018-07-11 22:50:33 +01:00
Cachet Bot
226596d47b New translations forms.php (Japanese) 2018-07-11 22:50:32 +01:00
Cachet Bot
fa8f957631 New translations dashboard.php (Japanese) 2018-07-11 22:50:31 +01:00
Cachet Bot
e465295e48 New translations validation.php (Japanese) 2018-07-11 22:50:30 +01:00
Cachet Bot
94b5ad7b09 New translations pagination.php (Japanese) 2018-07-11 22:50:29 +01:00
Cachet Bot
9512346c0c New translations cachet.php (Japanese) 2018-07-11 22:50:28 +01:00
Cachet Bot
985119e125 New translations forms.php (Italian) 2018-07-11 22:50:27 +01:00
Cachet Bot
11b5df1499 New translations pagination.php (Korean) 2018-07-11 22:50:26 +01:00
Cachet Bot
76aa95389f New translations validation.php (Persian) 2018-07-11 22:50:25 +01:00
Cachet Bot
f346449714 New translations forms.php (Persian) 2018-07-11 22:50:22 +01:00
Cachet Bot
a2da594586 New translations setup.php (Portuguese, Brazilian) 2018-07-11 22:50:21 +01:00
Cachet Bot
6b3bb85d53 New translations forms.php (Portuguese, Brazilian) 2018-07-11 22:50:20 +01:00
Cachet Bot
5d28ea4e69 New translations dashboard.php (Portuguese, Brazilian) 2018-07-11 22:50:19 +01:00
Cachet Bot
f724248b1f New translations validation.php (Portuguese, Brazilian) 2018-07-11 22:50:18 +01:00
Cachet Bot
a70ecd9e6d New translations cachet.php (Portuguese, Brazilian) 2018-07-11 22:50:17 +01:00
Cachet Bot
828ea1c2d3 New translations setup.php (Portuguese) 2018-07-11 22:50:17 +01:00
Cachet Bot
c1f65347e5 New translations forms.php (Portuguese) 2018-07-11 22:50:16 +01:00
Cachet Bot
61abbcc367 New translations dashboard.php (Persian) 2018-07-11 22:50:15 +01:00
Cachet Bot
4bf980bc1a New translations dashboard.php (Portuguese) 2018-07-11 22:50:14 +01:00
Cachet Bot
b88354d261 New translations cachet.php (Portuguese) 2018-07-11 22:50:12 +01:00
Cachet Bot
5fb88b1936 New translations forms.php (Polish) 2018-07-11 22:50:11 +01:00
Cachet Bot
e0b2368342 New translations validation.php (Polish) 2018-07-11 22:50:10 +01:00
Cachet Bot
fc87437edc New translations setup.php (Persian) 2018-07-11 22:50:08 +01:00
Cachet Bot
7786f54ad3 New translations validation.php (Portuguese) 2018-07-11 22:50:08 +01:00
Cachet Bot
ee0d56d22b New translations cachet.php (Afrikaans) 2018-07-11 22:50:06 +01:00
James Brooks
51eb5917b6 Merge pull request #3175 from CachetHQ/l10n_2.3
New Crowdin translations
2018-07-11 22:34:12 +01:00
Cachet Bot
6433c48a5f Apply fixes from StyleCI
[ci skip] [skip ci]
2018-07-11 03:10:14 +00:00
Cachet Bot
d3af0d37be New translations setup.php (Danish) 2018-07-11 04:10:06 +01:00
Cachet Bot
0430086750 New translations forms.php (Danish) 2018-07-11 04:10:05 +01:00
Cachet Bot
e43516460b New translations dashboard.php (Danish) 2018-07-11 04:00:06 +01:00
Cachet Bot
036787f3e3 New translations cachet.php (Danish) 2018-07-11 04:00:05 +01:00
Cachet Bot
b20272d14a Apply fixes from StyleCI
[ci skip] [skip ci]
2018-07-10 16:16:19 +00:00
Cachet Bot
5c11c1ff72 New translations cachet.php (Norwegian) 2018-07-10 16:50:07 +01:00
Cachet Bot
5bde0dddff New translations setup.php (Zulu) 2018-07-10 14:35:34 +01:00
Cachet Bot
beee77d2e3 New translations validation.php (German) 2018-07-10 14:35:33 +01:00
Cachet Bot
4c6106e3a6 New translations pagination.php (German) 2018-07-10 14:35:31 +01:00
Cachet Bot
c4e7010cfc New translations cachet.php (German) 2018-07-10 14:35:31 +01:00
Cachet Bot
0b505b31c6 New translations setup.php (French) 2018-07-10 14:35:30 +01:00
Cachet Bot
87b31b2b54 New translations forms.php (French) 2018-07-10 14:35:29 +01:00
Cachet Bot
c0da527878 New translations dashboard.php (French) 2018-07-10 14:35:28 +01:00
Cachet Bot
539deaaea8 New translations validation.php (French) 2018-07-10 14:35:26 +01:00
Cachet Bot
c04a845c54 New translations pagination.php (French) 2018-07-10 14:35:26 +01:00
Cachet Bot
09347fc120 New translations cachet.php (French) 2018-07-10 14:35:25 +01:00
Cachet Bot
3c2ec3dbe6 New translations setup.php (Finnish) 2018-07-10 14:35:24 +01:00
Cachet Bot
843f69b9e1 New translations dashboard.php (German) 2018-07-10 14:35:23 +01:00
Cachet Bot
5c54286fb1 New translations forms.php (Finnish) 2018-07-10 14:35:21 +01:00
Cachet Bot
32fd6535c1 New translations validation.php (Finnish) 2018-07-10 14:35:19 +01:00
Cachet Bot
622a103b7b New translations pagination.php (Finnish) 2018-07-10 14:35:18 +01:00
Cachet Bot
b8a3614649 New translations cachet.php (Finnish) 2018-07-10 14:35:17 +01:00
Cachet Bot
98ac8383c9 New translations setup.php (English) 2018-07-10 14:35:16 +01:00
Cachet Bot
747c94ebd7 New translations forms.php (English) 2018-07-10 14:35:16 +01:00
Cachet Bot
4c1a7abb7a New translations dashboard.php (English) 2018-07-10 14:35:15 +01:00
Cachet Bot
0a5691a4c2 New translations validation.php (English) 2018-07-10 14:35:14 +01:00
Cachet Bot
9aa16286a5 New translations pagination.php (English) 2018-07-10 14:35:13 +01:00
Cachet Bot
d4a693f8fb New translations cachet.php (English) 2018-07-10 14:35:12 +01:00
Cachet Bot
0ea5990af6 New translations setup.php (Dutch) 2018-07-10 14:35:11 +01:00
Cachet Bot
22cdc45074 New translations dashboard.php (Finnish) 2018-07-10 14:35:10 +01:00
Cachet Bot
61ea95a403 New translations forms.php (Dutch) 2018-07-10 14:35:09 +01:00
Cachet Bot
0dcf3f958f New translations forms.php (German) 2018-07-10 14:35:08 +01:00
Cachet Bot
b672f42635 New translations cachet.php (Greek) 2018-07-10 14:35:07 +01:00
Cachet Bot
7f6c7f7a71 New translations forms.php (Indonesian) 2018-07-10 14:35:06 +01:00
Cachet Bot
54ed6eda60 New translations dashboard.php (Indonesian) 2018-07-10 14:35:05 +01:00
Cachet Bot
877b25cfbb New translations validation.php (Indonesian) 2018-07-10 14:35:03 +01:00
Cachet Bot
8048c02286 New translations pagination.php (Indonesian) 2018-07-10 14:35:01 +01:00
Cachet Bot
082367793c New translations cachet.php (Indonesian) 2018-07-10 14:35:00 +01:00
Cachet Bot
518d28f07b New translations setup.php (Hungarian) 2018-07-10 14:34:59 +01:00
Cachet Bot
a01ccbf953 New translations forms.php (Hungarian) 2018-07-10 14:34:58 +01:00
Cachet Bot
a69c72ef40 New translations dashboard.php (Hungarian) 2018-07-10 14:34:57 +01:00
Cachet Bot
87b51835cc New translations validation.php (Hungarian) 2018-07-10 14:34:56 +01:00
Cachet Bot
edecc98cbf New translations pagination.php (Hungarian) 2018-07-10 14:34:55 +01:00
Cachet Bot
a1a78df602 New translations setup.php (German) 2018-07-10 14:34:54 +01:00
Cachet Bot
2b5127505f New translations cachet.php (Hungarian) 2018-07-10 14:34:53 +01:00
Cachet Bot
cd029e0a79 New translations forms.php (Hebrew) 2018-07-10 14:34:52 +01:00
Cachet Bot
4a0e12645c New translations dashboard.php (Hebrew) 2018-07-10 14:34:51 +01:00
Cachet Bot
18c12cf9b0 New translations validation.php (Hebrew) 2018-07-10 14:34:50 +01:00
Cachet Bot
a2b6141b55 New translations pagination.php (Hebrew) 2018-07-10 14:34:49 +01:00
Cachet Bot
3305628b16 New translations cachet.php (Hebrew) 2018-07-10 14:34:48 +01:00
Cachet Bot
81b6fd95e9 New translations setup.php (Greek) 2018-07-10 14:34:48 +01:00
Cachet Bot
cf2a9454c8 New translations forms.php (Greek) 2018-07-10 14:34:47 +01:00
Cachet Bot
d220823d8e New translations dashboard.php (Greek) 2018-07-10 14:34:45 +01:00
Cachet Bot
81d4cf89e6 New translations validation.php (Greek) 2018-07-10 14:34:44 +01:00
Cachet Bot
e0a5e4df9b New translations pagination.php (Greek) 2018-07-10 14:34:43 +01:00
Cachet Bot
090a80992a New translations setup.php (Hebrew) 2018-07-10 14:34:43 +01:00
Cachet Bot
a659db17ae New translations setup.php (Indonesian) 2018-07-10 14:34:42 +01:00
Cachet Bot
67d8a1ca35 New translations dashboard.php (Dutch) 2018-07-10 14:34:41 +01:00
Cachet Bot
220d1a1fe5 New translations pagination.php (Dutch) 2018-07-10 14:34:40 +01:00
Cachet Bot
d8bc1cd517 New translations setup.php (Catalan) 2018-07-10 14:34:39 +01:00
Cachet Bot
e7768a1cec New translations forms.php (Catalan) 2018-07-10 14:34:38 +01:00
Cachet Bot
4b1bd76ff6 New translations dashboard.php (Catalan) 2018-07-10 14:34:37 +01:00
Cachet Bot
37e778585a New translations validation.php (Catalan) 2018-07-10 14:34:36 +01:00
Cachet Bot
2646963a2e New translations pagination.php (Catalan) 2018-07-10 14:34:35 +01:00
Cachet Bot
ebe162fe71 New translations cachet.php (Catalan) 2018-07-10 14:34:34 +01:00
Cachet Bot
071159ffa1 New translations setup.php (Arabic) 2018-07-10 14:34:33 +01:00
Cachet Bot
b9549829c2 New translations forms.php (Arabic) 2018-07-10 14:34:32 +01:00
Cachet Bot
8c6be5006d New translations dashboard.php (Arabic) 2018-07-10 14:34:31 +01:00
Cachet Bot
cae3a54b50 New translations validation.php (Arabic) 2018-07-10 14:34:30 +01:00
Cachet Bot
0b3e29e8dd New translations cachet.php (Chinese Simplified) 2018-07-10 14:34:29 +01:00
Cachet Bot
a5d690abdd New translations pagination.php (Arabic) 2018-07-10 14:34:29 +01:00
Cachet Bot
31137c71d4 New translations setup.php (Albanian) 2018-07-10 14:34:28 +01:00
Cachet Bot
76963a186c New translations forms.php (Albanian) 2018-07-10 14:34:27 +01:00
Cachet Bot
3c2d85188b New translations dashboard.php (Albanian) 2018-07-10 14:34:26 +01:00
Cachet Bot
db407e81ea New translations validation.php (Albanian) 2018-07-10 14:34:25 +01:00
Cachet Bot
9dda8d5ae7 New translations pagination.php (Albanian) 2018-07-10 14:34:24 +01:00
Cachet Bot
ad637fbb81 New translations cachet.php (Albanian) 2018-07-10 14:34:23 +01:00
Cachet Bot
6805e75f63 New translations setup.php (Afrikaans) 2018-07-10 14:34:22 +01:00
Cachet Bot
bc5ae22165 New translations forms.php (Afrikaans) 2018-07-10 14:34:21 +01:00
Cachet Bot
6696465d45 New translations dashboard.php (Afrikaans) 2018-07-10 14:34:20 +01:00
Cachet Bot
58bb80efc9 New translations validation.php (Afrikaans) 2018-07-10 14:34:19 +01:00
Cachet Bot
e6b7b41f24 New translations cachet.php (Arabic) 2018-07-10 14:34:18 +01:00
Cachet Bot
682ac8ac5d New translations validation.php (Dutch) 2018-07-10 14:34:17 +01:00
Cachet Bot
9687384709 New translations pagination.php (Chinese Simplified) 2018-07-10 14:34:16 +01:00
Cachet Bot
347f443d4e New translations dashboard.php (Chinese Simplified) 2018-07-10 14:34:14 +01:00
Cachet Bot
548d9f8c3a New translations cachet.php (Dutch) 2018-07-10 14:34:13 +01:00
Cachet Bot
eeb85c1815 New translations setup.php (Danish) 2018-07-10 14:34:12 +01:00
Cachet Bot
1112c17306 New translations forms.php (Danish) 2018-07-10 14:34:10 +01:00
Cachet Bot
aa421830bb New translations dashboard.php (Danish) 2018-07-10 14:34:09 +01:00
Cachet Bot
99982566b8 New translations validation.php (Danish) 2018-07-10 14:34:08 +01:00
Cachet Bot
115b5b7013 New translations pagination.php (Danish) 2018-07-10 14:34:07 +01:00
Cachet Bot
65a263a2dd New translations cachet.php (Danish) 2018-07-10 14:34:06 +01:00
Cachet Bot
98e0a7b7b4 New translations setup.php (Czech) 2018-07-10 14:34:05 +01:00
Cachet Bot
7581d96c54 New translations forms.php (Czech) 2018-07-10 14:34:03 +01:00
Cachet Bot
8e7c0f3f0d New translations dashboard.php (Czech) 2018-07-10 14:34:02 +01:00
Cachet Bot
50c5b23f96 New translations validation.php (Chinese Simplified) 2018-07-10 14:34:01 +01:00
Cachet Bot
d77c53b5eb New translations validation.php (Czech) 2018-07-10 14:34:00 +01:00
Cachet Bot
cda30429be New translations cachet.php (Czech) 2018-07-10 14:33:59 +01:00
Cachet Bot
8cfb1282d3 New translations forms.php (Chinese Traditional) 2018-07-10 14:33:58 +01:00
Cachet Bot
9faa4b77cd New translations dashboard.php (Chinese Traditional) 2018-07-10 14:33:57 +01:00
Cachet Bot
6a5c5776a9 New translations validation.php (Chinese Traditional) 2018-07-10 14:33:56 +01:00
Cachet Bot
c63a76c86d New translations cachet.php (Chinese Traditional) 2018-07-10 14:33:54 +01:00
Cachet Bot
89718f5fbc New translations setup.php (Chinese Simplified) 2018-07-10 14:33:54 +01:00
Cachet Bot
8e84278a24 New translations forms.php (Chinese Simplified) 2018-07-10 14:33:53 +01:00
Cachet Bot
16470d548e New translations pagination.php (Czech) 2018-07-10 14:33:52 +01:00
Cachet Bot
320203262f New translations pagination.php (Afrikaans) 2018-07-10 14:33:51 +01:00
Cachet Bot
ae3b2e44b5 New translations cachet.php (Italian) 2018-07-10 14:33:50 +01:00
Cachet Bot
755b8143cb New translations validation.php (Italian) 2018-07-10 14:33:49 +01:00
Cachet Bot
4667948949 New translations dashboard.php (Thai) 2018-07-10 14:33:48 +01:00
Cachet Bot
0f7bee9c61 New translations validation.php (Thai) 2018-07-10 14:33:47 +01:00
Cachet Bot
10430ddad3 New translations pagination.php (Thai) 2018-07-10 14:33:46 +01:00
Cachet Bot
6e06e6a4dd New translations cachet.php (Thai) 2018-07-10 14:33:45 +01:00
Cachet Bot
393a1119da New translations forms.php (Swedish) 2018-07-10 14:33:44 +01:00
Cachet Bot
47fb5b2789 New translations dashboard.php (Swedish) 2018-07-10 14:33:43 +01:00
Cachet Bot
00caff7ecf New translations cachet.php (Swedish) 2018-07-10 14:33:41 +01:00
Cachet Bot
e1fccf1b26 New translations forms.php (Thai) 2018-07-10 14:33:40 +01:00
Cachet Bot
1a1e914d59 New translations setup.php (Spanish) 2018-07-10 14:33:39 +01:00
Cachet Bot
f2e995513f New translations dashboard.php (Spanish) 2018-07-10 14:33:38 +01:00
Cachet Bot
e780735987 New translations validation.php (Spanish) 2018-07-10 14:33:35 +01:00
Cachet Bot
1eaa4594af New translations pagination.php (Spanish) 2018-07-10 14:33:35 +01:00
Cachet Bot
9d51a34bd4 New translations cachet.php (Spanish) 2018-07-10 14:33:34 +01:00
Cachet Bot
d1681beae4 New translations setup.php (Russian) 2018-07-10 14:33:33 +01:00
Cachet Bot
0254d3df00 New translations forms.php (Russian) 2018-07-10 14:33:32 +01:00
Cachet Bot
2d15c27191 New translations dashboard.php (Russian) 2018-07-10 14:33:31 +01:00
Cachet Bot
17f12a0cb7 New translations validation.php (Russian) 2018-07-10 14:33:30 +01:00
Cachet Bot
e17400be21 New translations pagination.php (Russian) 2018-07-10 14:33:29 +01:00
Cachet Bot
62d7cb615d New translations cachet.php (Russian) 2018-07-10 14:33:28 +01:00
Cachet Bot
89759bb0ea New translations forms.php (Spanish) 2018-07-10 14:33:27 +01:00
Cachet Bot
7ee6cc91e7 New translations setup.php (Romanian) 2018-07-10 14:33:26 +01:00
Cachet Bot
bf2809bf50 New translations setup.php (Thai) 2018-07-10 14:33:26 +01:00
Cachet Bot
fcbd5b68b2 New translations pagination.php (Turkish) 2018-07-10 14:33:25 +01:00
Cachet Bot
1b1490f8bd New translations forms.php (Zulu) 2018-07-10 14:33:24 +01:00
Cachet Bot
019cafbbf5 New translations dashboard.php (Zulu) 2018-07-10 14:33:23 +01:00
Cachet Bot
a5a66e0de6 New translations validation.php (Zulu) 2018-07-10 14:33:22 +01:00
Cachet Bot
018aa8b0f0 New translations pagination.php (Zulu) 2018-07-10 14:33:21 +01:00
Cachet Bot
abcfdcdd0e New translations cachet.php (Zulu) 2018-07-10 14:33:20 +01:00
Cachet Bot
ceb95c30c4 New translations setup.php (Vietnamese) 2018-07-10 14:33:19 +01:00
Cachet Bot
08f9936e1d New translations forms.php (Vietnamese) 2018-07-10 14:33:19 +01:00
Cachet Bot
1647c4fc45 New translations dashboard.php (Vietnamese) 2018-07-10 14:33:18 +01:00
Cachet Bot
0eaf24febf New translations validation.php (Vietnamese) 2018-07-10 14:33:16 +01:00
Cachet Bot
544a6900bb New translations pagination.php (Vietnamese) 2018-07-10 14:33:15 +01:00
Cachet Bot
b6cbf817ab New translations cachet.php (Turkish) 2018-07-10 14:33:14 +01:00
Cachet Bot
1dab6c0f08 New translations cachet.php (Vietnamese) 2018-07-10 14:33:13 +01:00
Cachet Bot
9dfd47b1e9 New translations forms.php (Ukrainian) 2018-07-10 14:33:12 +01:00
Cachet Bot
0f26675767 New translations dashboard.php (Ukrainian) 2018-07-10 14:33:10 +01:00
Cachet Bot
24f2bb7fd4 New translations validation.php (Ukrainian) 2018-07-10 14:33:09 +01:00
Cachet Bot
4be32a6112 New translations pagination.php (Ukrainian) 2018-07-10 14:33:08 +01:00
Cachet Bot
0b23c86dd2 New translations cachet.php (Ukrainian) 2018-07-10 14:33:08 +01:00
Cachet Bot
22a6e70cfd New translations setup.php (Turkish) 2018-07-10 14:33:07 +01:00
Cachet Bot
8e6569b63d New translations forms.php (Turkish) 2018-07-10 14:33:06 +01:00
Cachet Bot
2c8c13cd82 New translations dashboard.php (Turkish) 2018-07-10 14:33:05 +01:00
Cachet Bot
3aabf285a9 New translations validation.php (Turkish) 2018-07-10 14:33:04 +01:00
Cachet Bot
d07e58d3db New translations setup.php (Ukrainian) 2018-07-10 14:33:03 +01:00
Cachet Bot
0d88d80d48 New translations pagination.php (Italian) 2018-07-10 14:33:02 +01:00
Cachet Bot
ea638ef2ae New translations forms.php (Romanian) 2018-07-10 14:33:01 +01:00
Cachet Bot
b31d30dd10 New translations validation.php (Romanian) 2018-07-10 14:33:00 +01:00
Cachet Bot
a5494b6559 New translations cachet.php (Persian) 2018-07-10 14:32:59 +01:00
Cachet Bot
909a67fe93 New translations setup.php (Norwegian) 2018-07-10 14:32:58 +01:00
Cachet Bot
2a8a4027d6 New translations forms.php (Norwegian) 2018-07-10 14:32:57 +01:00
Cachet Bot
27bc034691 New translations dashboard.php (Norwegian) 2018-07-10 14:32:56 +01:00
Cachet Bot
433093a012 New translations validation.php (Norwegian) 2018-07-10 14:32:55 +01:00
Cachet Bot
fde7ad65f6 New translations pagination.php (Norwegian) 2018-07-10 14:32:54 +01:00
Cachet Bot
172228fdb3 New translations cachet.php (Norwegian) 2018-07-10 14:32:53 +01:00
Cachet Bot
d287b10bc1 New translations setup.php (Korean) 2018-07-10 14:32:52 +01:00
Cachet Bot
db8fddf378 New translations forms.php (Korean) 2018-07-10 14:32:51 +01:00
Cachet Bot
fc45fb60ec New translations dashboard.php (Korean) 2018-07-10 14:32:50 +01:00
Cachet Bot
b11b5f2cf9 New translations pagination.php (Persian) 2018-07-10 14:32:49 +01:00
Cachet Bot
951250f1d1 New translations validation.php (Korean) 2018-07-10 14:32:48 +01:00
Cachet Bot
c9bdbf38d8 New translations cachet.php (Korean) 2018-07-10 14:32:47 +01:00
Cachet Bot
7449d44bc8 New translations setup.php (Japanese) 2018-07-10 14:32:46 +01:00
Cachet Bot
db5ce4397b New translations forms.php (Japanese) 2018-07-10 14:32:45 +01:00
Cachet Bot
3256ad8660 New translations dashboard.php (Japanese) 2018-07-10 14:32:44 +01:00
Cachet Bot
486198872a New translations validation.php (Japanese) 2018-07-10 14:32:43 +01:00
Cachet Bot
de12ccf291 New translations pagination.php (Japanese) 2018-07-10 14:32:42 +01:00
Cachet Bot
e1f5aa0639 New translations cachet.php (Japanese) 2018-07-10 14:32:40 +01:00
Cachet Bot
a70db4c031 New translations setup.php (Italian) 2018-07-10 14:32:40 +01:00
Cachet Bot
c1daf0ae0a New translations forms.php (Italian) 2018-07-10 14:32:39 +01:00
Cachet Bot
fad9e5fd92 New translations dashboard.php (Italian) 2018-07-10 14:32:38 +01:00
Cachet Bot
c224b5d05b New translations pagination.php (Korean) 2018-07-10 14:32:37 +01:00
Cachet Bot
78cc258d96 New translations dashboard.php (Romanian) 2018-07-10 14:32:36 +01:00
Cachet Bot
c87c37ad73 New translations validation.php (Persian) 2018-07-10 14:32:35 +01:00
Cachet Bot
ab02399ca6 New translations forms.php (Persian) 2018-07-10 14:32:34 +01:00
Cachet Bot
c3cf0b9e81 New translations pagination.php (Romanian) 2018-07-10 14:32:33 +01:00
Cachet Bot
2e5ead7886 New translations cachet.php (Romanian) 2018-07-10 14:32:32 +01:00
Cachet Bot
5a444d2c03 New translations forms.php (Portuguese, Brazilian) 2018-07-10 14:32:31 +01:00
Cachet Bot
34cf7428df New translations dashboard.php (Portuguese, Brazilian) 2018-07-10 14:32:30 +01:00
Cachet Bot
e3fa11d917 New translations validation.php (Portuguese, Brazilian) 2018-07-10 14:32:29 +01:00
Cachet Bot
6153d08880 New translations forms.php (Portuguese) 2018-07-10 14:32:27 +01:00
Cachet Bot
521c69b39e New translations dashboard.php (Persian) 2018-07-10 14:32:26 +01:00
Cachet Bot
9caf55d92e New translations dashboard.php (Portuguese) 2018-07-10 14:32:25 +01:00
Cachet Bot
357a1b4e86 New translations cachet.php (Portuguese) 2018-07-10 14:32:24 +01:00
Cachet Bot
c3ad824def New translations setup.php (Polish) 2018-07-10 14:32:23 +01:00
Cachet Bot
abeb6fd917 New translations forms.php (Polish) 2018-07-10 14:32:22 +01:00
Cachet Bot
be794d4ef2 New translations dashboard.php (Polish) 2018-07-10 14:32:21 +01:00
Cachet Bot
fe8ff219ef New translations validation.php (Polish) 2018-07-10 14:32:20 +01:00
Cachet Bot
e01993e5b8 New translations pagination.php (Polish) 2018-07-10 14:32:19 +01:00
Cachet Bot
6138ba99b8 New translations cachet.php (Polish) 2018-07-10 14:32:18 +01:00
Cachet Bot
6efe83c6b4 New translations setup.php (Persian) 2018-07-10 14:32:17 +01:00
Cachet Bot
1b152eb0fe New translations validation.php (Portuguese) 2018-07-10 14:32:17 +01:00
Cachet Bot
62012f4dab New translations cachet.php (Afrikaans) 2018-07-10 14:32:15 +01:00
James Brooks
5c39be5b2c Update deps 2018-07-06 08:29:21 +01:00
James Brooks
1e73861e15 Make file like 2.4 2018-07-04 21:12:30 +01:00
Cachet Bot
4099a8f4e6 Update Crowdin configuration file 2018-07-04 21:01:54 +01:00
James Brooks
163f57397d Update deps 2018-06-17 09:46:48 +01:00
James Brooks
494badb00a Merge pull request #3069 from CachetHQ/fix-component-group-status
Fix the component group status
2018-06-17 09:43:58 +01:00
James Brooks
84bea58f99 Merge branch '2.3' into fix-component-group-status 2018-06-14 21:02:26 +01:00
James Brooks
d7ffbeef0c Don't run tests on HHVM 2018-06-14 21:02:08 +01:00
James Brooks
4aff0ddec0 Fix the component group status. Closes #2731 2018-06-14 07:31:22 +01:00
James Brooks
749c83169c Merge pull request #3016 from hensur/stylesheet-fix-23
Backport stylesheet fix #3014 to 2.3
2018-04-19 08:47:32 +01:00
Henning Surmeier
58a212c2e4 Backport stylesheet fix #3014 to 2.3 2018-04-18 16:27:19 +02:00
James Brooks
0c72e5eec8 Apply fixes from StyleCI (#2962)
[ci skip] [skip ci]
2018-03-26 19:18:30 +01:00
James Brooks
83bc743d79 Merge pull request #2960 from anthonybocci/metric-points-prefix-table-2925
Use the table prefix on metric_points
2018-03-26 19:18:07 +01:00
Anthony Bocci
35dcc8c928 Use the table prefix on metric_points
In the '.env' file, a 'DB_PREFIX' sets the prefix that should be used
on every table name. When writing an SQL query the 'DB_PREFIX' value
has to be prefixed to the table name.

The repository PgSqlRepository, MySqlRepository and SqliteRepository,
located in 'app/Repositories/Metric/' did not apply this prefix on
the 'metric_points' table. The problem occured only when we set a
'DB_PREFIX' not null, the rest of the application worked correctly but
the part about 'metric_points' couldn't work, saying the table was
inexistant.

A method was added in the repository AbstractMetricRepository to get
the 'metric_points' table name with the prefix if there is one.
This method is used in the three repositories to get the right table
name.

Note: This problem was present in 2.3, but was already fixed in 2.4 so
there is no need to apply this commit on the 2.4 branch.

See: CachetHQ/Cachet/#2955
2018-03-23 20:56:41 +01:00
James Brooks
93d1f8784a Merge pull request #2864 from snowflakeOps/2.3
use a better and smaller image for open graph (e.g for slack)
2018-01-11 21:33:49 +00:00
Markus Ritzmann
0450f2f330 #2853 use a better and smaller image for og 2018-01-11 16:49:01 +01:00
James Brooks
595b152db5 Merge pull request #2671 from checkitonus/bug/invalid-template-23
Quick check to make sure the template exists
2017-09-30 11:38:19 +01:00
Graham Campbell
cc15d078bf Removed old links 2017-09-10 18:24:01 +01:00
Graham Campbell
3b568bbc07 Mail password non-required 2017-09-10 18:11:23 +01:00
Graham Campbell
ae4c414a82 Upgraded exceptions package 2017-09-10 17:54:18 +01:00
Graham Campbell
5358cf5e1e Upgraded deps 2017-09-10 17:20:07 +01:00
Andrew Judd
6dedacad57 Removing a helper method 2017-07-30 08:48:45 -04:00
Andrew Judd
29c9211935 Quick check to make sure the template exists 2017-07-29 11:13:41 -04:00
James Brooks
7d47546650 Switch to dev 2017-07-17 21:50:00 +01:00
James Brooks
f5a9941903 Update deps again 2017-07-17 21:49:42 +01:00
James Brooks
52b7bf74b9 Update version 2017-07-17 21:46:30 +01:00
James Brooks
6a59d5ac4d Update deps 2017-07-17 21:44:45 +01:00
James Brooks
19b7b0c3b2 Require predis/predis. Fixes #2611 2017-07-17 21:44:43 +01:00
Graham Campbell
d4507e0722 Back to dev 2017-06-28 23:42:10 +01:00
Graham Campbell
47bc73f9e9 Release v2.3.12 2017-06-28 23:41:31 +01:00
Graham Campbell
81fc6479d5 Revert to original travis config 2017-06-28 22:53:06 +01:00
Graham Campbell
c9ca99990c Update .travis.yml 2017-06-28 22:49:07 +01:00
Graham Campbell
e0d35d6e64 Merge branch '2.3' of https://github.com/CachetHQ/Cachet into 2.3 2017-06-28 22:39:55 +01:00
Graham Campbell
813be34f25 Upgraded dependencies 2017-06-28 22:39:41 +01:00
Graham Campbell
900723105b Update .travis.yml 2017-06-28 22:38:44 +01:00
Graham Campbell
8012a201b9 Update .travis.yml 2017-06-28 22:00:28 +01:00
Graham Campbell
706e7765e1 Update .travis.yml 2017-06-28 21:52:45 +01:00
Guido Hendriks
bcff3d0730 Improve testCreateSubscriberWithSubscriptions test case (#2487) 2017-06-28 21:45:27 +01:00
James Brooks
db5bf005bc Apply fixes from StyleCI (#2606)
[ci skip] [skip ci]
2017-06-28 20:52:41 +01:00
James Brooks
dac88efce6 Merge pull request #2601 from Daniel15/2.3-with-patches
Backport API endpoint to get system status to v2.3
2017-06-28 20:52:08 +01:00
James Brooks
38ef2630ee Add system status to /status endpoint 2017-06-20 17:18:38 +10:00
James Brooks
c215ad4111 Implement the system status api endpoint. Closes #1936 2017-06-20 17:09:03 +10:00
James Brooks
c899839a7f Back to dev 2017-04-12 23:05:32 +01:00
James Brooks
2e5e8b1545 Bump version to 2.3.11 2017-04-12 23:05:09 +01:00
James Brooks
7e556d5dba Apply fixes from StyleCI (#2486)
[ci skip] [skip ci]
2017-04-12 23:04:21 +01:00
James Brooks
331e176fbc Updated deps 2017-03-25 11:42:25 +00:00
James Brooks
bde0abe472 Fix handling of individual component subscriptions via API 2016-09-21 18:35:58 +01:00
James Brooks
f2bf2eff68 Test creating a subscriber returns subscriptions 2016-09-21 18:17:22 +01:00
James Brooks
50ab96fc4f Load subscriptions when creating a subscriber 2016-09-21 18:16:08 +01:00
James Brooks
3cbee1302e Update deps 2016-09-21 18:08:56 +01:00
Graham Campbell
8d74923e3f Back to dev 2016-08-11 12:16:50 +01:00
Graham Campbell
dbf6fe528c Release v2.3.10 2016-08-11 12:16:14 +01:00
Graham Campbell
2a9d1b4897 Backport new command tests 2016-08-11 12:09:28 +01:00
Graham Campbell
c2192d7ef7 Backport readme changes 2016-08-11 12:03:28 +01:00
Graham Campbell
1b580360ac Updated deps 2016-08-10 21:04:17 +01:00
James Brooks
15407ad9a3 Remove dump and die 2016-08-10 20:28:32 +01:00
James Brooks
14127de3ca Back to dev 2016-08-07 22:05:34 +01:00
James Brooks
57988f0009 Release v2.3.9 2016-08-07 22:05:16 +01:00
Graham Campbell
7ac7344b5e Updated dep 2016-08-07 22:01:00 +01:00
James Brooks
472dcfe85a Merge pull request #2036 from CachetHQ/analysis-8KggM3
Applied fixes from StyleCI

[ci skip] [skip ci]
2016-08-07 21:10:17 +01:00
James Brooks
77409abc5a Applied fixes from StyleCI
[ci skip] [skip ci]
2016-08-07 16:10:12 -04:00
James Brooks
7548ae7e58 Disable fixedStepSize 2016-08-07 21:09:47 +01:00
James Brooks
074d3457c6 Fix Italian translation issues. Closes #2034 2016-08-07 19:45:13 +01:00
James Brooks
205748b182 Improve metric labels 2016-08-07 19:22:19 +01:00
James Brooks
1f4bee67d6 Back to dev 2016-08-05 07:52:10 +01:00
James Brooks
2f0df5ab7b Bump version 2016-08-05 07:51:44 +01:00
James Brooks
8fe75f7112 Update deps 2016-08-05 07:51:25 +01:00
Graham Campbell
b3ee389ca5 Merge pull request #2021 from CachetHQ/require-xml
Require the ext-xml extension
2016-08-02 11:13:29 +01:00
James Brooks
a40bfd12b7 Removed blank line 2016-08-02 11:02:31 +01:00
James Brooks
8d86c5e072 Ignore SQLite databases when backing up the db 2016-08-02 11:00:39 +01:00
James Brooks
20ca9ceade Require the ext-xml extension 2016-08-02 10:55:33 +01:00
Graham Campbell
6c22c52e3a Updated the aws sdk 2016-07-29 12:51:06 -04:00
James Brooks
ecfa9b1f01 Built in production 2016-07-29 12:04:57 -04:00
James Brooks
380048dd53 Updated Chart.js and rebuilt assets 2016-07-29 11:42:08 -04:00
Graham Campbell
ac57936b62 Merge pull request #2015 from CachetHQ/metrics-y-step-size
Set the step size to the metrics places
2016-07-28 15:39:58 -04:00
James Brooks
962b008fb2 Updated deps 2016-07-28 15:19:58 -04:00
James Brooks
5b1dd8ad00 Set the step size to the metrics places. Fixes #2012 2016-07-28 15:17:20 -04:00
James Brooks
c1d8203602 Added missing setup translations. Closes #2010 2016-07-28 15:06:16 -04:00
James Brooks
dc73f62803 Fixes issues with updating using dashboard api. Closes #2014 2016-07-28 10:47:59 -04:00
Graham Campbell
fdbde63143 Back to dev 2016-07-25 22:58:23 +01:00
Graham Campbell
9a9ec833eb Released 2.3.7 2016-07-25 22:57:05 +01:00
James Brooks
136cce2d6d Merge pull request #2008 from CachetHQ/analysis-XZnLDb
Applied fixes from StyleCI

[ci skip] [skip ci]
2016-07-25 21:52:31 +01:00
Graham Campbell
880a2d9cd9 Applied fixes from StyleCI
[ci skip] [skip ci]
2016-07-25 16:52:26 -04:00
James Brooks
aea18a51c2 Sync languages 2016-07-25 21:42:49 +01:00
Graham Campbell
84bedf5c60 Merge pull request #2007 from CachetHQ/revert-1976-cli
Revert "Don't use settings caching in cli"
2016-07-25 19:32:16 +01:00
Graham Campbell
309a3f96ef Revert "Don't use settings caching in cli" 2016-07-25 19:25:05 +01:00
Graham Campbell
acd1ac496d Merge pull request #2003 from CachetHQ/analysis
Run the new static analysis checks in the tests
2016-07-24 14:58:03 +01:00
Graham Campbell
8c273b8579 Run the new static analysis checks in the tests 2016-07-24 14:48:59 +01:00
Graham Campbell
b30a774bed Merge pull request #2002 from CachetHQ/imports
Added missing imports
2016-07-24 14:48:03 +01:00
Graham Campbell
3ea1428c23 Added missing imports 2016-07-24 14:47:02 +01:00
James Brooks
d6ab5efd14 Fixes #1998 2016-07-22 11:08:49 +01:00
James Brooks
a94be2efca Update deps 2016-07-22 09:19:58 +01:00
Graham Campbell
f8505a866d Back to dev 2016-07-18 19:34:29 +01:00
Graham Campbell
27235abab2 Released 2.3.6 2016-07-18 19:34:06 +01:00
Graham Campbell
f70bc7a42f Merge pull request #1986 from CachetHQ/deps
Updated dependencies
2016-07-18 18:51:37 +01:00
Graham Campbell
6cf622ae21 Updated dependencies 2016-07-18 18:46:43 +01:00
James Brooks
dd1a14a438 Back to dev 2016-07-17 16:38:52 +01:00
James Brooks
387818dbb2 Bump version 2016-07-17 16:38:24 +01:00
James Brooks
5d70d244ce Update feed package. Fixes #1973 2016-07-17 16:37:55 +01:00
James Brooks
ddc846d959 Back to dev 2016-07-16 09:54:54 +01:00
James Brooks
6fb6641499 Bump version 2016-07-16 09:54:28 +01:00
James Brooks
d5eb087eca Merge pull request #1976 from CachetHQ/cli
Don't use settings caching in cli
2016-07-15 07:48:26 +01:00
Graham Campbell
fd25edb2f0 Don't use settings caching in cli 2016-07-14 21:31:07 -07:00
Graham Campbell
5879a2cb1a Updated the exceptions package 2016-07-14 11:11:21 -07:00
Graham Campbell
df5b9b89e6 Updated dependencies 2016-07-13 18:25:27 -07:00
James Brooks
47a5569f02 Improve how we work out system status with scheduled maintenance 2016-07-13 14:19:35 +01:00
James Brooks
ca4a72c518 Merge pull request #1960 from PeterDaveHello/bump-node-dependencies
bump nodejs package dependencies
2016-07-13 13:57:49 +01:00
Peter Dave Hello
6e45b5ae88 bump nodejs package dependencies 2016-07-13 20:57:16 +08:00
James Brooks
99dbc2cd6c Merge pull request #1959 from PeterDaveHello/fix-file-permission
remove executable permission from the files don't need it
2016-07-12 09:31:22 +01:00
Peter Dave Hello
2f2ed53b58 remove executable permission from the files don't need it 2016-07-12 16:28:28 +08:00
James Brooks
7e1ead91ed Merge pull request #1958 from PeterDaveHello/image-optimize
optimize png images using zopflipng
2016-07-12 09:23:02 +01:00
Peter Dave Hello
28578474b9 optimize png images using zopflipng 2016-07-12 16:20:14 +08:00
James Brooks
d4e332bf55 Merge pull request #1956 from PeterDaveHello/patch-1
Update README.md
2016-07-12 09:15:37 +01:00
Peter Dave Hello
13f0f67a7b Update README.md
Use svg instead of png to get localized percentage badge for better image quality.
2016-07-12 16:14:54 +08:00
James Brooks
709cac9332 Merge pull request #1953 from CachetHQ/fix-setup
fix setup env writing
2016-07-11 19:03:48 +01:00
Joseph Cohen
e17196d4c9 fix setup env writing 2016-07-11 13:00:00 -05:00
James Brooks
80be140c1f Update ISSUE_TEMPLATE 2016-07-11 09:50:33 +01:00
James Brooks
4f9af8bca0 Remove blank line 2016-07-10 17:04:08 +01:00
James Brooks
af3b7836ff Back to dev 2016-07-10 10:39:42 +01:00
James Brooks
cc4a960ea6 Release v2.3.3 2016-07-10 10:39:19 +01:00
James Brooks
467d29ca11 Use numeric validation for metric points. Fixes #1950 2016-07-10 10:37:00 +01:00
James Brooks
ac1355771c Merge pull request #1947 from CachetHQ/set-locale
Set Date locale
2016-07-08 19:43:04 +01:00
James Brooks
c41adc1019 Override date locale again. Fixes #1727 2016-07-08 19:42:20 +01:00
James Brooks
5b74b2d625 Merge pull request #1949 from CachetHQ/dashboard-api-bus
The dashboard API needs to use the Command Bus
2016-07-08 18:39:38 +01:00
James Brooks
d7835f68ed Merge pull request #1948 from CachetHQ/analysis-zO37Lk
Applied fixes from StyleCI

[ci skip] [skip ci]
2016-07-08 17:42:17 +01:00
James Brooks
a1f1a2b969 Applied fixes from StyleCI
[ci skip] [skip ci]
2016-07-08 12:42:13 -04:00
James Brooks
77394995e4 The dashboard API needs to use the Command Bus. Fixes #1927 2016-07-08 17:42:01 +01:00
James Brooks
9953557497 Back to dev 2016-07-06 21:54:50 +01:00
James Brooks
4dc175b2be Correct dev version 2016-07-06 21:53:15 +01:00
James Brooks
4a2fe00c89 Bump version 2016-07-06 21:52:32 +01:00
James Brooks
db55283b85 Merge pull request #1940 from CachetHQ/analysis-86V7RW
Applied fixes from StyleCI

[ci skip] [skip ci]
2016-07-06 19:14:04 +01:00
James Brooks
5c6440e890 Sync languages 2016-07-06 19:14:21 +01:00
James Brooks
6b299b0a90 Applied fixes from StyleCI
[ci skip] [skip ci]
2016-07-06 14:14:00 -04:00
James Brooks
9b5d4aa7c4 Merge pull request #1939 from CachetHQ/metric-repository-prefix
Metric repository now knows prefixes
2016-07-06 19:03:42 +01:00
James Brooks
1fdda03199 Metric repository now knows prefixes. Fixes #1938 2016-07-06 18:42:31 +01:00
James Brooks
7c846d06ff Updated deps 2016-07-06 18:32:04 +01:00
James Brooks
e34e4381d4 Update VERSION 2016-07-06 18:24:58 +01:00
Graham Campbell
b255f71958 Merge pull request #1934 from odannyc/patch-1
Misspelled 'email'
2016-07-02 10:59:51 +01:00
Danny Carrillo
9560b2a0dc Misspelled 'email' 2016-07-01 13:55:28 -07:00
James Brooks
f8491ceead Back to dev 2016-06-27 22:10:37 +01:00
James Brooks
823fe6e9e2 Bump version 2016-06-27 22:10:13 +01:00
James Brooks
b7e9c07a05 Merge pull request #1924 from CachetHQ/analysis-zDyveB
Applied fixes from StyleCI

[ci skip] [skip ci]
2016-06-27 21:18:57 +01:00
James Brooks
a9d83e1337 Applied fixes from StyleCI
[ci skip] [skip ci]
2016-06-27 16:18:52 -04:00
James Brooks
86cfcb501a Added /admin route redirect to /dashboard 2016-06-27 21:18:44 +01:00
James Brooks
8f68b2a347 Re-compiled assets 2016-06-27 18:39:31 +01:00
Graham Campbell
1423a9bbd0 Updated dependencies 2016-06-27 15:48:35 +01:00
James Brooks
39d302175c Merge pull request #1919 from travelton/group-dashboard-components
Component Grouping in Dashboard
2016-06-27 15:41:01 +01:00
Travis Swientek
fffb4d964c Component Grouping in Dashboard, Spelling Adjustment. 2016-06-27 09:05:34 -05:00
James Brooks
7ba12960dd Added missing events to EventServiceProvider 2016-06-27 12:22:18 +01:00
James Brooks
440f45ed4a Merge pull request #1920 from juniorb2ss/2.3
Fix language name.
2016-06-24 17:42:11 +01:00
Carlos Eduardo
549eaa3382 Fix language name.
Correct name of slugs portuguese.
2016-06-24 12:27:10 -03:00
James Brooks
5305f71c2b Updated deps 2016-06-20 13:49:55 +01:00
James Brooks
bf749c54ee Move helpers.php out of Http namespace 2016-06-17 09:16:23 +01:00
James Brooks
f1e2c1ef68 Merge pull request #1911 from CachetHQ/fix-lastpass
Help password managers
2016-06-15 08:54:50 +01:00
James Brooks
4ab9807cbe Help password managers. Fixes #1910 2016-06-15 08:54:13 +01:00
James Brooks
9f9c9a10c5 Merge pull request #1886 from CachetHQ/wizard-smtp
Wizard email configuration
2016-06-13 20:06:51 +01:00
Joseph Cohen
a5ed3c40a9 Fix write env to work with nulls and change from to address 2016-06-13 20:06:40 +01:00
James Brooks
1fe4789760 Fix spacing 2016-06-13 20:06:39 +01:00
James Brooks
9c1e94c550 Put mail log to bottom 2016-06-13 20:06:39 +01:00
Joseph Cohen
958c9eadc7 Add mail data to wizard 2016-06-13 20:06:39 +01:00
Joseph Cohen
ca3f516457 Add mail driver to the wizard 2016-06-13 20:06:28 +01:00
Graham Campbell
04215fc37a Back to dev 2016-06-11 00:47:41 +01:00
Graham Campbell
8d90357f40 Released 2.3.0 RC6 2016-06-11 00:47:07 +01:00
Graham Campbell
46add8d841 Merge branch '2.2' into 2.3
# Conflicts:
#	VERSION
#	composer.json
#	composer.lock
2016-06-11 00:46:01 +01:00
Graham Campbell
1e695d51b5 Added the aws sdk as a dependency 2016-06-11 00:45:26 +01:00
Graham Campbell
65f864d743 Back to dev 2016-06-11 00:40:45 +01:00
Graham Campbell
bc51aac622 Released 2.2.4 2016-06-11 00:40:10 +01:00
Graham Campbell
3c39ccd5df Updated dependencies 2016-06-11 00:32:51 +01:00
Graham Campbell
cd4a96983e Updated laravel 2016-06-11 00:21:03 +01:00
Graham Campbell
c0d3602a91 Updated dependencies 2016-06-11 00:19:19 +01:00
James Brooks
08175b89e9 Merge pull request #1905 from CachetHQ/analysis-qMPD92
Applied fixes from StyleCI

[ci skip] [skip ci]
2016-06-10 17:27:37 +01:00
James Brooks
ece696d7db Merge pull request #1904 from CachetHQ/analysis-z327Ep
Applied fixes from StyleCI

[ci skip] [skip ci]
2016-06-10 17:27:33 +01:00
James Brooks
e7052f5aff Applied fixes from StyleCI
[ci skip] [skip ci]
2016-06-10 12:27:33 -04:00
James Brooks
ff97327803 Applied fixes from StyleCI
[ci skip] [skip ci]
2016-06-10 12:27:29 -04:00
James Brooks
8dda99c499 Compiled assets 2016-06-10 17:27:26 +01:00
James Brooks
947aa27e40 Move dashboard version check into version api endpoint 2016-06-10 17:27:21 +01:00
James Brooks
1425c15ee8 Don't rely on jQuery to be ready 2016-06-10 17:13:42 +01:00
James Brooks
cdbd2db8e9 Re-compile assets 2016-06-10 13:46:28 +01:00
James Brooks
ef02d77439 Remove the login background 2016-06-10 13:42:13 +01:00
Graham Campbell
88ce241785 Updated dependencies 2016-06-10 08:53:26 +01:00
Graham Campbell
b64dd1e87e Properly fixed metric updating
// cc @jbrooksuk
2016-06-07 11:11:17 +01:00
Graham Campbell
a0b9856d61 Updated deps 2016-06-07 11:07:02 +01:00
James Brooks
d6552982a3 Order by id if order is all the same 2016-06-07 08:54:56 +01:00
James Brooks
42eac92737 Pass update order as null from the dashboard 2016-06-07 08:53:41 +01:00
Graham Campbell
a2cee97f33 Rebuilt assets 2016-06-07 00:13:41 +01:00
Graham Campbell
0541a662ff Fixed path 2016-06-07 00:12:17 +01:00
Graham Campbell
6c9b7a6fde Updated dependencies 2016-06-06 20:32:49 +01:00
James Brooks
ff9a2802f8 Back to dev 2016-06-06 11:20:10 +01:00
James Brooks
06ca0ffb21 Released v2.2.3 2016-06-06 11:19:28 +01:00
James Brooks
80e5655be9 Merge pull request #1895 from CachetHQ/str-include
Fix the Str import. Fixes #1749
2016-06-06 11:18:26 +01:00
James Brooks
0b7ca97e53 Fix the Str include 2016-06-06 11:03:09 +01:00
James Brooks
812160839f Support a Redis passwords 2016-06-05 16:52:18 +01:00
James Brooks
27e46d77e6 Publish the cache table migration 2016-06-05 10:16:50 +01:00
James Brooks
a10d12e589 Merge pull request #1869 from CachetHQ/update-login-page
Updated login page
2016-06-04 15:55:40 +01:00
James Brooks
ac7652f3aa Remove unused divs 2016-06-04 15:55:01 +01:00
James Brooks
c63fedefe9 Updated login page 2016-06-04 14:57:16 +01:00
Graham Campbell
c17ef87651 Merge pull request #1891 from CachetHQ/deps
Updated dependencies
2016-06-03 17:23:47 +01:00
Graham Campbell
846f77b054 Updated dependencies 2016-06-03 17:20:14 +01:00
Graham Campbell
d5c29a6c4b Merge pull request #1890 from CachetHQ/fixes
Fixed the integrations
2016-06-03 17:11:00 +01:00
Graham Campbell
31861f020f Fixed typo 2016-06-03 17:10:24 +01:00
Graham Campbell
abf83361e8 Fixed the integrations 2016-06-03 17:07:36 +01:00
James Brooks
3e8801d8d4 Merge pull request #1887 from CachetHQ/analysis-XkYWW1
Applied fixes from StyleCI

[ci skip] [skip ci]
2016-06-03 14:00:33 +01:00
James Brooks
bbc9eb1f81 Applied fixes from StyleCI
[ci skip] [skip ci]
2016-06-03 09:00:29 -04:00
James Brooks
c8b602d349 Handle failing to fetch blog posts. Fixes #1878 2016-06-03 14:00:23 +01:00
James Brooks
715eb02844 Use default_view or view. Fixes #1842 2016-06-03 13:54:26 +01:00
James Brooks
c8f7e92124 Only test the seed command 2016-06-03 10:44:02 +01:00
James Brooks
eae44ee6cb Fix redirecting back to the correct settings page 2016-06-03 10:16:44 +01:00
James Brooks
3fde593a86 Standardise the error message 2016-06-03 10:15:08 +01:00
James Brooks
1527ec8ddc Test all app: commands 2016-06-02 18:40:51 +01:00
Graham Campbell
c90584bda5 Merge pull request #1879 from CachetHQ/deps
Updated dependencies
2016-06-02 10:46:20 +01:00
Graham Campbell
aea3b40c54 Updated dependencies 2016-06-02 10:43:40 +01:00
Graham Campbell
d394e108bd Fix the feed package 2016-06-02 10:37:47 +01:00
Graham Campbell
0df9f01ffe Updated dependencies 2016-06-02 10:30:38 +01:00
James Brooks
9745bb7543 Merge pull request #1876 from CachetHQ/metric-ordering-api
Set an order on metrics via the API
2016-06-02 10:16:35 +01:00
James Brooks
cab030237b Set an order on metrics via the API. Closes #1874 2016-06-02 10:16:23 +01:00
James Brooks
439ac9fe44 Updated dependencies 2016-06-02 09:21:33 +01:00
James Brooks
7eef9467aa Don't go resetting the threshold value 2016-06-02 09:09:03 +01:00
James Brooks
15387b1da8 Allow searching incidents by component_id. Closes #1873 2016-06-02 08:46:59 +01:00
James Brooks
c33d297fa4 Merge pull request #1871 from CachetHQ/analysis-8jlox9
Applied fixes from StyleCI

[ci skip]
2016-06-01 11:50:39 +01:00
James Brooks
c8af103498 Applied fixes from StyleCI
[ci skip]
2016-06-01 06:50:35 -04:00
James Brooks
0e2610eee0 Fix indentation of setting 2016-06-01 11:50:27 +01:00
James Brooks
e201a6ed06 Seed with Patreon page component 2016-06-01 11:50:27 +01:00
James Brooks
1e4d616b88 Merge pull request #1870 from CachetHQ/analysis-8wOpew
Applied fixes from StyleCI

[ci skip]
2016-06-01 11:49:11 +01:00
James Brooks
2de01671e9 Applied fixes from StyleCI
[ci skip]
2016-06-01 06:49:07 -04:00
James Brooks
dd26a3af34 Fix default settings for enable_subscribers 2016-06-01 11:48:59 +01:00
Graham Campbell
4b41395144 Tweak 2016-06-01 11:42:25 +01:00
James Brooks
2dacc71e8a Set the default show_support setting 2016-06-01 08:04:16 +01:00
James Brooks
4869c7ee21 Merge pull request #1867 from CachetHQ/analysis-8maVvE
Applied fixes from StyleCI

[ci skip]
2016-05-31 20:19:00 +01:00
James Brooks
9293dcf0df Applied fixes from StyleCI
[ci skip]
2016-05-31 15:18:56 -04:00
James Brooks
150057ef50 Sync languages 2016-05-31 20:18:39 +01:00
James Brooks
c81f18c3bc Back to dev 2016-05-31 19:31:56 +01:00
James Brooks
42aa437ac2 Released 2.3.0 RC5 2016-05-31 19:31:34 +01:00
James Brooks
6a780314fb Rebuild assets 2016-05-31 19:29:28 +01:00
James Brooks
ffae9cf3d4 Merge pull request #1866 from CachetHQ/analysis-zRP0lp
Applied fixes from StyleCI

[ci skip]
2016-05-31 19:27:14 +01:00
James Brooks
091f59c241 Applied fixes from StyleCI
[ci skip]
2016-05-31 14:27:10 -04:00
James Brooks
288fa6180b Publish the css-inliner config 2016-05-31 19:27:00 +01:00
James Brooks
7ecb546a86 Merge pull request #1865 from CachetHQ/dashboard-feed
Dashboard feed
2016-05-31 19:25:30 +01:00
James Brooks
f7c8dd6254 Merge pull request #1864 from CachetHQ/analysis-XN4p11
Applied fixes from StyleCI

[ci skip]
2016-05-31 19:12:36 +01:00
James Brooks
2adc9d032a Applied fixes from StyleCI
[ci skip]
2016-05-31 14:12:32 -04:00
James Brooks
f53075ec4f Add Patreon link and latest Cachet blog posts to dashboard 2016-05-31 19:12:23 +01:00
James Brooks
0190813012 Dashboard RSS 2016-05-31 18:02:10 +01:00
Graham Campbell
20d187d642 Back to dev 2016-05-29 19:28:42 +01:00
Graham Campbell
91bd9288f5 Released 2.3.0 RC4 2016-05-29 19:28:10 +01:00
Graham Campbell
24df32e9a9 Fixed bad caching 2016-05-29 19:20:56 +01:00
Graham Campbell
fb75ad6902 Include our user agent 2016-05-29 19:17:22 +01:00
Graham Campbell
aa87274378 Another fix 2016-05-29 18:49:40 +01:00
Graham Campbell
696a1126c7 Fixed lang file 2016-05-29 18:47:33 +01:00
Graham Campbell
7c4787a1a7 Merge pull request #1815 from CachetHQ/backers-credits-dashboard
Added credits page
2016-05-29 18:44:52 +01:00
Graham Campbell
74d24b6809 Link the images 2016-05-29 18:40:29 +01:00
Graham Campbell
22226c666f Force size 2016-05-29 18:34:08 +01:00
Graham Campbell
b3244a4639 Fixed import 2016-05-29 18:27:04 +01:00
Graham Campbell
6cf3c4c109 Merge pull request #1861 from CachetHQ/analysis-z4waDG
Applied fixes from StyleCI

[ci skip]
2016-05-29 18:24:17 +01:00
Graham Campbell
8f47bd4a4f Applied fixes from StyleCI
[ci skip]
2016-05-29 13:24:13 -04:00
Graham Campbell
c03f01ca44 Added credits 2016-05-29 18:14:40 +01:00
Graham Campbell
ab0ed775e1 Merge pull request #1860 from CachetHQ/tests
Cleanup travis test config
2016-05-29 12:09:48 +01:00
Graham Campbell
5a600c0e17 Removed old badge 2016-05-29 12:00:59 +01:00
Graham Campbell
601a863fc4 Cleanup tests 2016-05-29 12:00:02 +01:00
Graham Campbell
366eab9cae Merge pull request #1859 from CachetHQ/typo
Fixed typo
2016-05-29 11:13:14 +01:00
Graham Campbell
021c2890d2 Fixed typo 2016-05-29 10:57:45 +01:00
Graham Campbell
2eff325a23 Back to dev 2016-05-28 22:02:11 +01:00
Graham Campbell
d7e70c1870 Released 2.3.0 RC3 2016-05-28 22:01:44 +01:00
Graham Campbell
0311d59e78 Updated dependencies 2016-05-28 20:27:19 +01:00
Graham Campbell
6a6c8d866e Merge pull request #1843 from CachetHQ/improve-emails
Improve email designs, use theme colours
2016-05-28 18:36:55 +01:00
Graham Campbell
11d82a22c3 Merge pull request #1856 from CachetHQ/fix-flash-msg
Fix login flash messages #1850
2016-05-28 18:36:26 +01:00
Joseph Cohen
dcfe55e881 Fix login flash messages #1850 2016-05-28 12:34:52 -05:00
Graham Campbell
494d1a021c Merge pull request #1855 from CachetHQ/proxies
Synced the trusted proxies
2016-05-28 18:32:42 +01:00
Graham Campbell
d95557d683 Synced the trusted proxies 2016-05-28 18:31:41 +01:00
Joe Cohen
48ccc02799 Applied fixes from StyleCI
[ci skip]
2016-05-28 12:30:39 -05:00
Joseph Cohen
f3440389be Improve email content and subject, fix component notification presenter 2016-05-28 12:30:39 -05:00
James Brooks
bad9b1d550 Improve email designs, use theme colours 2016-05-28 12:30:39 -05:00
Graham Campbell
e1d07fdc99 Updated the throttle package again 2016-05-28 16:28:53 +01:00
Graham Campbell
e69395a5ad Merge pull request #1852 from CachetHQ/tests
Added more service provider tests
2016-05-28 16:27:35 +01:00
Graham Campbell
1c10cba5fc Added more service provider tests 2016-05-28 16:19:33 +01:00
Graham Campbell
3a1042e6ae Tweaked the metric repo binding 2016-05-28 16:19:17 +01:00
Graham Campbell
a2a008b108 Updated the throttle package 2016-05-28 16:18:28 +01:00
Graham Campbell
11f8ba81fd Merge pull request #1851 from CachetHQ/throttling
Fix crap login throttling
2016-05-28 15:52:25 +01:00
Graham Campbell
e8d216b671 Enabled the new displayer 2016-05-28 15:50:03 +01:00
Graham Campbell
167d076edc Fix crap login throttling 2016-05-28 15:45:38 +01:00
James Brooks
5c5634d355 We no longer need to pass the app_name in 2016-05-27 11:35:59 +01:00
Graham Campbell
1eea34e832 Updated laravel 2016-05-27 08:57:12 +01:00
James Brooks
3873fd90ba Make sure subscribers are enabled before displaying add subscriber 2016-05-26 11:51:25 +01:00
James Brooks
38a659b08c Back to dev 2016-05-26 11:44:40 +01:00
James Brooks
55b6961a4b Released 2.3.0 RC2 2016-05-26 11:43:39 +01:00
James Brooks
2b87629dca Fix issues with localizations not applying properly 2016-05-26 11:35:00 +01:00
James Brooks
48c4240c38 Removed un-needed equality param 2016-05-26 11:28:52 +01:00
James Brooks
f84793bfab Remove strong tag 2016-05-26 11:22:23 +01:00
James Brooks
0200ac848f Reduce indentation 2016-05-26 11:20:07 +01:00
James Brooks
787bb74b3b Fix trailing "email" string 2016-05-26 11:19:54 +01:00
James Brooks
8f58cdd182 Merge pull request #1831 from CachetHQ/reduce-size-settings-controller
Moved banner handling into a separate method as it's big
2016-05-26 08:43:20 +01:00
James Brooks
8f0691f3bd Merge pull request #1835 from CachetHQ/subscribers
Remove subscribers modal
2016-05-26 08:42:57 +01:00
James Brooks
a81ce21721 Merge pull request #1836 from CachetHQ/lang
Fixed English translations
2016-05-26 08:41:50 +01:00
Graham Campbell
1e0992be6c Restored the validation translations 2016-05-26 08:18:02 +01:00
Graham Campbell
00706ad744 Fixed uppercase letter 2016-05-26 08:16:49 +01:00
Joseph Cohen
31d47cfb35 Remove subscribers modal 2016-05-26 00:50:23 -05:00
James Brooks
7e29f7d363 Moved banner handling into a separate method as it's big 2016-05-25 22:16:41 +01:00
Graham Campbell
71a1ab091f Updated laravel 2016-05-25 21:55:26 +01:00
James Brooks
9e020e5d59 Merge pull request #1830 from CachetHQ/default-enable-subscibers
Enable subscribers by default
2016-05-25 21:20:45 +01:00
James Brooks
5e10f1c777 Enable subscribers by default 2016-05-25 21:20:24 +01:00
Graham Campbell
a2aa116204 Merge pull request #1829 from CachetHQ/fix-config-seeding
Fix clearing of configs when seeding
2016-05-25 20:30:30 +01:00
Graham Campbell
ac65cc56bb I prefer clear 2016-05-25 20:26:58 +01:00
James Brooks
9e3f07742b Fix clearing of configs when seeding 2016-05-25 20:00:33 +01:00
James Brooks
b120c37cbc Fix colour of p and strong tags 2016-05-25 19:23:11 +01:00
James Brooks
6211e7a1f8 Drop the "| Cachet" extra from the site title 2016-05-25 12:23:22 +01:00
Graham Campbell
5d23f83db6 Modified english translations next/previous 2016-05-25 12:21:17 +01:00
Graham Campbell
a2ea9bf10b Merge pull request #1826 from CachetHQ/controller
Avoid the deprecated controller method
2016-05-25 12:17:38 +01:00
Graham Campbell
d6495dec96 Avoid the deprecated controller method 2016-05-25 12:15:42 +01:00
Graham Campbell
5cbe3ba708 Back to dev 2016-05-25 11:39:32 +01:00
Graham Campbell
375d2330de Released 2.3.0 RC1 2016-05-25 11:39:07 +01:00
Graham Campbell
e39a3cde16 Merge pull request #1823 from CachetHQ/settings-cache
Refactored settings caching
2016-05-25 11:34:02 +01:00
Graham Campbell
13d0ff320a Another attempt 2016-05-25 11:28:03 +01:00
Graham Campbell
72577a04b7 Fixed headers 2016-05-25 11:23:48 +01:00
James Brooks
0bf2039e60 Fix some bits 2016-05-25 11:14:16 +01:00
Graham Campbell
414efb0ce7 Fixed typo 2016-05-25 10:59:11 +01:00
Graham Campbell
0500d63654 Merge pull request #1825 from CachetHQ/analysis-X017pj
Applied fixes from StyleCI

[ci skip]
2016-05-25 10:58:44 +01:00
Graham Campbell
3a86862e4f Applied fixes from StyleCI
[ci skip]
2016-05-25 05:58:40 -04:00
Graham Campbell
8df65b2dc3 Finished off the subscriber 2016-05-25 10:58:14 +01:00
Graham Campbell
c3bc8fdd2d Refactor settings caching 2016-05-25 10:55:49 +01:00
Graham Campbell
200cd62dc9 Resolve via class name 2016-05-25 10:55:33 +01:00
Graham Campbell
527e5872df Fixed typo 2016-05-25 10:55:22 +01:00
Graham Campbell
ebaf4e9395 WIP 2016-05-25 10:33:06 +01:00
Graham Campbell
d0afcbffe4 Updated dependencies (#1824) 2016-05-25 10:31:05 +01:00
Graham Campbell
2e9d56d053 Fixed typo 2016-05-25 09:55:07 +01:00
James Brooks
90419e70cf Merge pull request #1821 from CachetHQ/analysis-Xa67jZ
Applied fixes from StyleCI

[ci skip]
2016-05-25 09:52:48 +01:00
Graham Campbell
0566133c12 Cleaned up the release class and provider (#1820) 2016-05-25 09:52:44 +01:00
James Brooks
8e824eb5e0 Applied fixes from StyleCI
[ci skip]
2016-05-25 04:45:43 -04:00
James Brooks
5534cdbdde Sync languages 2016-05-25 09:45:20 +01:00
James Brooks
2db0b011e6 Rebuild assets 2016-05-25 09:28:02 +01:00
gellu
962b40f0e9 Fixed undefined component variable (#1808) 2016-05-24 20:04:47 +01:00
Graham Campbell
96450c476c Merge pull request #1811 from CachetHQ/subscribe-multiple-subscribers
Subscribe multiple subscribers at one time
2016-05-24 20:03:45 +01:00
James Brooks
ba09b3f7cd Merge pull request #1818 from CachetHQ/settings
Renamed "Config" to "Settings"
2016-05-24 18:35:23 +01:00
Graham Campbell
053e3e9477 Renamed "Config" to "Settings" 2016-05-24 17:48:13 +01:00
Graham Campbell
ff939e356e Merge pull request #1816 from CachetHQ/caching
Settings Caching
2016-05-24 17:43:15 +01:00
Graham Campbell
e4d5c53d69 Derp fix 2016-05-24 17:20:23 +01:00
Graham Campbell
4549c51959 Deal with cases when we have no settings properly 2016-05-24 17:12:08 +01:00
Graham Campbell
20e4ae5ff8 Scaled things back 2016-05-24 17:00:48 +01:00
Graham Campbell
77f455651d Work on config caching 2016-05-24 16:44:21 +01:00
Graham Campbell
7a3c231f68 Merge pull request #1812 from CachetHQ/fix-subscriber-dates
Fix subscriber dates
2016-05-24 15:13:04 +01:00
Graham Campbell
0ec77d7652 Merge pull request #1813 from CachetHQ/dashboard-component-status-bug
Fixes toggling of component status box
2016-05-24 15:12:47 +01:00
James Brooks
4f886e15ed Fixes toggling of component status box. Fixes #1792 2016-05-24 15:07:36 +01:00
James Brooks
d3454d8126 Merge pull request #1810 from CachetHQ/allow-user-level-editing
Edit the user level from edit user page
2016-05-24 14:57:42 +01:00
James Brooks
ccc0ebb7d5 Fixes #1805. Subscribers no longer have subscribed_at dates 2016-05-24 14:52:13 +01:00
James Brooks
f6bfb10500 Outdent the template 2016-05-24 14:49:09 +01:00
James Brooks
e241f38dd7 Subscribe multiple subscribers at one time 2016-05-24 14:47:34 +01:00
James Brooks
fb0dd82fe2 Edit the user level from edit user page. Closes #1809 2016-05-24 14:39:59 +01:00
James Brooks
6997e0c451 Merge pull request #1803 from CachetHQ/rename-next-prev
Use only Previous and Next links
2016-05-23 08:20:07 +01:00
James Brooks
2e73d071c9 Use only Previous and Next links. Closes #1801 2016-05-23 08:05:32 +01:00
Graham Campbell
f86f6bbc08 Merge pull request #1799 from CachetHQ/deps
Updated dependencies
2016-05-20 17:51:03 +01:00
Graham Campbell
6c872e60fc Updated dependencies 2016-05-20 17:40:31 +01:00
James Brooks
23f77a7e72 Merge pull request #1798 from CachetHQ/backup
Cleanup the backup process
2016-05-20 15:54:47 +01:00
Graham Campbell
25dd45f47c Cleanup the backup process 2016-05-20 14:49:41 +01:00
Graham Campbell
2680bafd69 Merge pull request #1797 from CachetHQ/specify-component-group-components-order
Order components within group
2016-05-20 14:38:47 +01:00
James Brooks
08c1f105c2 Order components within group. Fixes #1793 2016-05-20 14:31:08 +01:00
James Brooks
c152892610 Merge pull request #1796 from CachetHQ/jbrooksuk-patch-1
Remove Paypal button in favour of Patreon link
2016-05-20 14:03:10 +01:00
James Brooks
d54ead2868 Remove Paypal button in favour of Patreon link 2016-05-20 13:21:49 +01:00
James Brooks
81ae63b2c0 Merge pull request #1795 from vinkla/patch-2
Remove npm dependencies
2016-05-20 12:56:52 +01:00
Vincent Klaiber
9f17c34f50 Remove npm dependencies
This closes #1794
2016-05-20 13:48:39 +02:00
Graham Campbell
d0be61ad96 Updated dependencies 2016-05-13 00:27:00 +01:00
James Brooks
89f99ef663 Merge pull request #1781 from CachetHQ/drop-bower
Remove Bower dependency
2016-05-11 20:38:39 +01:00
James Brooks
9f4270f4a5 Remove Bower dependency. Closes #1780 2016-05-11 20:11:46 +01:00
James Brooks
bda3484cac Merge pull request #1777 from CachetHQ/values
Use pluck rather than lists
2016-05-09 22:04:05 +01:00
James Brooks
aec2ef0198 Use pluck rather than lists 2016-05-09 20:43:24 +01:00
Joe Cohen
651edcc7c5 Merge pull request #1754 from CachetHQ/fix-spanish-cachet-translations
Fix translations in the cachet.php file
2016-05-09 14:08:47 -05:00
James Brooks
d975cd8ca1 Fix spanish translations 2016-05-09 13:30:07 -05:00
James Brooks
c315d04d5d Merge pull request #1773 from CachetHQ/remove-setup-key-generate
Setup doesn't need to generate the key anymore
2016-05-08 17:47:08 +01:00
James Brooks
e77562d469 Setup doesn't need to generate the key anymore 2016-05-08 17:46:29 +01:00
James Brooks
088fd6631d Merge pull request #1771 from CachetHQ/subscribers-api-specify-components
Specify components to subscribe to via API
2016-05-08 16:54:45 +01:00
James Brooks
cc102847f9 Specify components to subscribe to via API. Closes #1685 2016-05-08 16:26:59 +01:00
James Brooks
b88a102629 Merge pull request #1768 from CachetHQ/default-settings
Allow us to set better default settings
2016-05-08 16:24:57 +01:00
James Brooks
452eb653a5 Allow us to set better default settings. Closes #1755 2016-05-08 16:06:11 +01:00
James Brooks
1584883f39 Merge pull request #1767 from TheoBearman/2.3
Moving 'Automatically localise your status page to your visitor's language?' to its correct home
2016-05-07 21:12:30 +01:00
Theo Bearman
595a720d8b Moving 'Automatically localise your status page to your visitor's language?' to its correct home - Fixes #1765 2016-05-07 17:24:58 +01:00
Graham Campbell
2a0decc7c6 Merge pull request #1763 from CachetHQ/composer
Updated packages
2016-05-07 09:27:10 +01:00
James Brooks
d10386821e Updated lockfile 2016-05-07 08:52:26 +01:00
Graham Campbell
8da8e83e48 Updated packages 2016-05-06 22:46:51 +01:00
Graham Campbell
80bb601813 Merge pull request #1732 from CachetHQ/database-backups
Database backups
2016-05-06 21:56:26 +01:00
James Brooks
21b60e0708 Take a backup before calling app commands. Closes #1730 2016-05-06 21:11:57 +01:00
Graham Campbell
0fd88a6ba7 Merge pull request #1761 from CachetHQ/cleanup-subscribers-component-deletions
When removing a component, clean up the subscriptions
2016-05-06 14:12:39 +01:00
Graham Campbell
8da7bde2a5 Merge pull request #1760 from CachetHQ/update-deps
Update dependencies
2016-05-06 14:11:59 +01:00
James Brooks
ceb119b226 When removing a component, clean up the subscriptions. Closes #1739 2016-05-06 13:54:00 +01:00
James Brooks
6790d85a87 Update dependencies 2016-05-06 13:46:46 +01:00
Graham Campbell
873f61fde6 Merge pull request #1759 from CachetHQ/powered-by-change
Change the powered by text
2016-05-06 13:00:54 +01:00
James Brooks
f716c7fd1d Change the powered by text. Closes #1758 2016-05-06 12:50:30 +01:00
James Brooks
50ac69b234 Merge pull request #1757 from CachetHQ/fix-pgsql-metrics
Fixes metrics repository in PGSQL
2016-05-05 18:13:59 +01:00
James Brooks
712b1078f2 Fixes metrics repository in PGSQL. Closes #1741 2016-05-05 17:59:30 +01:00
James Brooks
893e61e319 Merge pull request #1756 from CachetHQ/command-bus-db-transactions
Command bus DB transactions
2016-05-05 17:47:59 +01:00
James Brooks
bfd0ccd652 Commands now use db transactions. Fixes #1745 2016-05-05 16:47:41 +01:00
James Brooks
3feb93c074 Remove dump and die call 2016-05-05 16:46:37 +01:00
James Brooks
a5ce958b92 Merge pull request #1753 from CachetHQ/configure-automatic-localization
Allow configuring of automatic localization
2016-05-05 11:22:24 +01:00
James Brooks
47e1dff5c5 Allow configuring of automatic localization. Closes #1747 2016-05-05 10:50:14 +01:00
James Brooks
9ddf9e3e1a Merge pull request #1751 from CachetHQ/fix-component-group-api
Fix component group api
2016-05-05 10:49:44 +01:00
James Brooks
9747cb9204 Added missing docblock 2016-05-05 10:24:01 +01:00
James Brooks
bd35db8d87 Default collapsed value to 0 (always open) 2016-05-05 10:23:18 +01:00
James Brooks
23ff795809 Don't pass through default order value when updating group 2016-05-05 10:23:02 +01:00
Graham Campbell
48d2721605 Updated dependencies 2016-05-04 21:52:01 +01:00
Graham Campbell
9d78092121 Merge pull request #1750 from CachetHQ/fix-str
Fixed a bad import
2016-05-04 20:08:21 +01:00
Graham Campbell
a0b1501b2a Fixed a bad import 2016-05-04 16:38:09 +01:00
Graham Campbell
c4e724e0e6 Rebuilt assets 2016-05-01 16:24:16 +01:00
James Brooks
792a8f6a07 Bower has changed the rules in which a name must follow 2016-05-01 16:06:24 +01:00
Graham Campbell
684b480338 Merge pull request #1738 from CachetHQ/fix-subscribers
Fix subscribers
2016-05-01 16:05:41 +01:00
Joe Cohen
f1b61c7ef1 Applied fixes from StyleCI 2016-05-01 16:04:43 +01:00
Joseph Cohen
05bb91d2d9 Global subscribers and fix notifications 2016-05-01 16:04:43 +01:00
Joseph Cohen
5abd25c408 Redirect subscribers to manage 2016-05-01 16:04:43 +01:00
Graham Campbell
e1a8e2220d Merge branch '2.2' into 2.3
# Conflicts:
#	VERSION
#	public/build/dist/js/all-a62567215d.js
#	public/build/rev-manifest.json
2016-04-29 17:05:53 +01:00
Graham Campbell
9d9d3b2e6c Bumped version 2016-04-29 16:58:35 +01:00
Graham Campbell
f79fadab80 Released 2.2.2 2016-04-29 16:58:08 +01:00
Graham Campbell
e3dc7594e5 Updated dependencies 2016-04-29 16:54:08 +01:00
Graham Campbell
200771cdab Merge pull request #1733 from CachetHQ/2.2-rebuild-assets
Rebuild assets
2016-04-29 16:48:22 +01:00
James Brooks
56760c7445 Rebuild assets 2016-04-29 16:45:06 +01:00
Graham Campbell
df373e93ef Merge branch '2.2' into 2.3
# Conflicts:
#	composer.lock
2016-04-27 14:58:20 +01:00
Graham Campbell
65ebfde315 Merge pull request #1729 from CachetHQ/fix-removal-customizations
Fixes removal of Customization values
2016-04-27 14:50:31 +01:00
Graham Campbell
4f7c50f7f4 Updated laravel 2016-04-27 14:49:37 +01:00
James Brooks
de232ab2b5 Fixes removal of Customization values 2016-04-27 14:47:47 +01:00
James Brooks
067018cf47 Use the Str facade 2016-04-27 14:37:17 +01:00
Graham Campbell
97e5fa07fa Updated dependencies 2016-04-27 09:41:39 +01:00
James Brooks
dec48a92f3 Merge pull request #1726 from alprs/fix-always_show_scrollbar
Always show vertical scrollbar
2016-04-27 09:28:58 +01:00
Andreas Lutro
0672fe046e Always show vertical scrollbar 2016-04-27 10:14:14 +02:00
James Brooks
b78009bee4 Merge pull request #1725 from alprs/fix-settings_localization_error
Fix a PHP error in settings -> localization
2016-04-27 08:56:56 +01:00
James Brooks
5907f54201 Merge pull request #1722 from alprs/fix-view_signup_notfound
Fix location of signup template
2016-04-27 08:56:07 +01:00
Andreas Lutro
555865d761 Fix a PHP error in settings -> localization
$langs is a nested array, not an array of strings.

Fixes #1723
2016-04-27 09:34:59 +02:00
Andreas Lutro
c0561ad8c0 fix location of signup template
fixes #1668
2016-04-27 09:00:05 +02:00
Graham Campbell
28e7af7107 Merge pull request #1582 from CachetHQ/metric-point-enhancement
Refactoring metric point storage
2016-04-25 20:42:11 +01:00
James Brooks
f9bc46b460 Refactored the way we store metrics 2016-04-25 20:42:00 +01:00
James Brooks
3730ca8811 Rebuild assets 2016-04-25 16:03:48 +01:00
James Brooks
69716730ac Update dependencies 2016-04-25 16:03:40 +01:00
Graham Campbell
ef8049c21d Updated laravel 2016-04-25 15:56:50 +01:00
Graham Campbell
cf80bf31f3 Synced with laravel/laravel 2016-04-25 15:25:52 +01:00
Graham Campbell
28bf01396c Merge branch '2.2'
# Conflicts:
#	VERSION
2016-04-23 11:04:10 +01:00
Graham Campbell
cf900e1390 Back to dev 2016-04-23 11:03:33 +01:00
Graham Campbell
df31b4d20e Released 2.2.1 2016-04-23 11:02:55 +01:00
Graham Campbell
a9185b7876 Bumped version 2016-04-23 11:00:30 +01:00
Graham Campbell
f383d50f16 Merge pull request #1718 from CachetHQ/js
Fixed chart.js and rebuilt assets
2016-04-23 10:53:06 +01:00
Graham Campbell
369073e636 Fixed chart.js and rebuilt assets 2016-04-23 10:52:16 +01:00
Graham Campbell
eb6a638a59 Updated dependencies 2016-04-23 10:24:21 +01:00
James Brooks
9a743ab425 Include default_view_name in metric results 2016-04-22 15:50:14 +01:00
James Brooks
36d89a9ad8 Specify use of the master branch 2016-04-22 15:30:59 +01:00
James Brooks
7dfe1b6fab Use sync as the default queue driver 2016-04-21 19:33:10 +01:00
James Brooks
ebc6525b65 Use query method rather than querying where 1 = 1 2016-04-21 18:53:12 +01:00
James Brooks
c5ae146683 A word 2016-04-21 17:05:25 +01:00
James Brooks
70daa9d3fa Round metric graphs to metric.places — closes #1704 2016-04-21 15:23:46 +01:00
James Brooks
95d3d427a4 Stop using the TwigBridge facade 2016-04-21 15:00:19 +01:00
James Brooks
8de387a92d Merge pull request #1699 from CachetHQ/tags-on-components-api
Add tag names array to components API
2016-04-21 12:51:48 +01:00
James Brooks
5e6055c9bd Merge pull request #1709 from CachetHQ/analysis-z3w4mr
Applied fixes from StyleCI
2016-04-21 12:33:20 +01:00
James Brooks
c4338aaaeb Applied fixes from StyleCI 2016-04-21 07:33:16 -04:00
James Brooks
ca06352bda Sync language files. Dutch, French, German, Spanish are 100% 2016-04-21 12:33:02 +01:00
Graham Campbell
edf78d7248 Merge pull request #1707 from CachetHQ/deps
Updated deps
2016-04-20 10:19:04 +01:00
Graham Campbell
d0d40c93d3 Updated deps 2016-04-20 10:14:15 +01:00
James Brooks
11730ed932 Merge pull request #1705 from rkgrep/lang-subsets
Use Google Fonts subsets for localizations
2016-04-19 13:55:33 +01:00
Roman Kinyakin
0c4737aca1 Use Google Fonts subsets for localizations 2016-04-19 18:08:40 +06:00
Graham Campbell
159390f989 Updated deps 2016-04-18 18:28:49 +01:00
James Brooks
5de8521ac8 Merge pull request #1702 from berlic/fix-component-tooltip
fix hidden (overlayed) tooltip
2016-04-18 09:48:23 +01:00
Konstantin Suvorov
d957474618 fix hidden tooltip
use 'body' as tooltip container
2016-04-18 11:38:04 +03:00
James Brooks
7c56785fcc Merge pull request #1703 from CachetHQ/analysis-8nNE05
Applied fixes from StyleCI
2016-04-17 17:37:29 +01:00
James Brooks
debc187874 Applied fixes from StyleCI 2016-04-17 12:18:24 -04:00
James Brooks
6ccac55e1d Sync languages 2016-04-17 17:17:29 +01:00
James Brooks
ed77a6753c Add tag names array to components api. Closes #1697 2016-04-17 03:16:06 +01:00
James Brooks
6e7df6e1f7 Added attributes to prevent bad default data in groups. Closes #1683 2016-04-16 12:19:16 +01:00
James Brooks
4f867dabe6 Updated dependencies 2016-04-15 18:57:14 +01:00
Graham Campbell
106a917dbc Merge pull request #1693 from CachetHQ/https
Serve analytics over https
2016-04-07 16:47:26 +01:00
Graham Campbell
2cf5b9710a Serve analytics over https 2016-04-07 15:15:26 +01:00
James Brooks
c60e7e906d Fix issue with go squared analytics setting 2016-04-06 20:12:29 +01:00
James Brooks
7521678e5f Requesting more info from issues 2016-04-06 17:10:25 +01:00
James Brooks
d828e961bd Added Installations and Donations sections 2016-04-06 10:13:30 +01:00
James Brooks
fef84f8559 Publish the sessions table 2016-04-05 15:30:57 +01:00
Graham Campbell
39b112dacc Updated dependencies 2016-04-02 15:28:58 +01:00
James Brooks
6054a6509c Updated dependencies 2016-04-02 09:49:40 +01:00
James Brooks
6f3a38d708 Fixes #1673 - Use previously sent data 2016-03-31 18:49:53 +01:00
James Brooks
8e0fa710ee Merge pull request #1680 from CachetHQ/unsafe-customization-settings
Allow unsafe code for Customization tab
2016-03-31 18:34:08 +01:00
James Brooks
309c6d345b Fixes #1677 2016-03-31 18:33:39 +01:00
James Brooks
6a466d2c9c Merge pull request #1678 from CachetHQ/maintenance
Fixed editing maintenance scheduled time
2016-03-31 14:09:32 +01:00
Graham Campbell
7a81d3b6ef Fixed editing maintenance scheduled time
Closes #1669.
2016-03-31 13:29:36 +01:00
Graham Campbell
b0a4820e80 Back to dev 2016-03-27 12:00:40 +01:00
Graham Campbell
fe569a6fbc Released 2.2.0 2016-03-27 12:00:15 +01:00
Graham Campbell
b556eac851 Merge pull request #1664 from CachetHQ/updates
Updated dependencies
2016-03-26 18:02:14 +00:00
Graham Campbell
84aea0e869 Merge pull request #1660 from CachetHQ/dashboard-component-group-order
Fixes #1659
2016-03-26 18:02:03 +00:00
Graham Campbell
841e102971 Updated dependencies 2016-03-26 17:59:51 +00:00
James Brooks
7f65e1e48c Fixes #1659 2016-03-25 18:11:14 +00:00
Graham Campbell
99a5a85248 Back to dev 2016-03-24 15:57:05 +00:00
Graham Campbell
6cc1eb2c0f 2.2.0-RC1 2016-03-24 15:56:22 +00:00
Graham Campbell
3d77a7a2cd Merge pull request #1655 from CachetHQ/sync
Sync with laravel
2016-03-24 15:36:45 +00:00
Graham Campbell
53dd12e339 Updated storage path config calls 2016-03-24 15:29:11 +00:00
Graham Campbell
0c3d388f5a Synced mail config 2016-03-24 15:26:04 +00:00
Graham Campbell
f73788fab3 Tweaked the model factory 2016-03-24 15:25:58 +00:00
Graham Campbell
b5bac7690e Synced up db stuff 2016-03-24 15:25:48 +00:00
Graham Campbell
1438783c07 Sync with laravel 2016-03-24 15:21:02 +00:00
James Brooks
bca7c5340a Set default component group view to 1 2016-03-24 14:10:46 +00:00
Graham Campbell
794d3733c1 Merge pull request #1654 from CachetHQ/revert
Revert broken scroll bars implementation
2016-03-24 14:03:56 +00:00
Graham Campbell
f63f63bb43 Rebuilt css 2016-03-24 14:03:23 +00:00
Graham Campbell
10c821c466 Revert broken scroll bars implementation
This reverts commit 06284ecd13.

Closes #1626.
Closes #1640.
2016-03-24 13:59:40 +00:00
Graham Campbell
85094805f2 Merge pull request #1653 from CachetHQ/updates
Updates
2016-03-24 13:58:35 +00:00
Graham Campbell
adab5487fd Rebuilt assets 2016-03-24 13:53:55 +00:00
Graham Campbell
263933c589 Updated dependencies 2016-03-24 13:53:48 +00:00
Graham Campbell
120fcf3b37 Tweaked composer.json 2016-03-24 13:53:37 +00:00
James Brooks
d5542f7555 Merge pull request #1645 from CachetHQ/github-markdown-css
Implement Github Markdown CSS
2016-03-23 16:23:26 +00:00
James Brooks
82e4411b45 Allow setting of DB_SCHEMA and DB_PREFIX. Closes #1649 2016-03-23 10:12:56 +00:00
James Brooks
62bba0ffa6 Rebuilt assets 2016-03-22 20:23:22 +00:00
James Brooks
f5e45ce938 Merge pull request #1648 from CachetHQ/navbar
Navbar
2016-03-22 20:21:31 +00:00
James Brooks
d342cdb6ad Finished basic navbar 2016-03-22 20:18:51 +00:00
James Brooks
9b69ed417e Merge pull request #1644 from CachetHQ/analysis-qgOQA6
Applied fixes from StyleCI
2016-03-21 20:28:23 +00:00
James Brooks
e689f206cb Applied fixes from StyleCI 2016-03-21 16:28:18 -04:00
James Brooks
8f80498c2e Implement Github Markdown CSS. Closes #1643 2016-03-21 20:28:01 +00:00
James Brooks
4d07d2c8b1 Working on a new navbar and minor design tweaks for the status page 2016-03-21 17:38:50 +00:00
James Brooks
ac31067333 Sync the session config 2016-03-21 16:38:40 +00:00
James Brooks
c293c39118 Sync up the database config 2016-03-21 16:38:39 +00:00
James Brooks
b8d148e79d Remove Stripe service 2016-03-21 16:38:39 +00:00
James Brooks
b29cc6824c Merge pull request #1639 from CachetHQ/analysis-zOMoVR
Applied fixes from StyleCI
2016-03-20 16:26:43 +00:00
James Brooks
7d73bc8b23 Applied fixes from StyleCI 2016-03-20 12:26:38 -04:00
James Brooks
22dbf290b4 Sync language files 2016-03-20 16:26:21 +00:00
James Brooks
dcec1e2e95 Show last updated for components. Closes #1627 2016-03-20 16:23:21 +00:00
James Brooks
a64b5c1046 Merge pull request #1638 from CachetHQ/update-deps
Update dependencies. Closes #1633
2016-03-20 16:14:08 +00:00
James Brooks
a5b0b2a1b5 Update dependencies. Closes #1633 2016-03-20 16:13:37 +00:00
James Brooks
6643d417b7 Merge pull request #1637 from CachetHQ/fix-acceptable-middleware
We don't need to pass "accepts:"
2016-03-20 14:54:39 +00:00
James Brooks
9ad20d013b We don't need to pass "accepts:". Fixes #1636 2016-03-20 12:07:07 +00:00
James Brooks
37c8e5924f Merge pull request #1632 from CachetHQ/fix-change-profile-password
Change others password
2016-03-18 09:15:03 +00:00
James Brooks
ea62a22998 Fixes #1630 - change others password 2016-03-18 09:00:25 +00:00
James Brooks
fa744b1b97 Merge pull request #1628 from fabian/chartjs2
Improvements for new Chart.js
2016-03-17 12:38:32 +00:00
Fabian Vogler
15907a6112 Set Chart.js animation duration
Animate lines after loading

https://github.com/CachetHQ/Cachet/pull/1625#issuecomment-197856024
2016-03-17 13:32:06 +01:00
Fabian Vogler
b58b6d8375 Increase Chart.js point hit detection radius
Default was 1

https://github.com/CachetHQ/Cachet/pull/1625#issuecomment-197819293
2016-03-17 12:11:27 +01:00
James Brooks
ffa1fdbf1a Rebuilt assets 2016-03-17 09:20:55 +00:00
James Brooks
5b646f9618 Merge pull request #1625 from fabian/chartjs2
Upgrade to Chart.js 2.0-beta2
2016-03-17 09:18:23 +00:00
Fabian Vogler
cbff8d50fa Add border color for metrics 2016-03-17 09:49:25 +01:00
Fabian Vogler
cc37fcfa78 Upgrade to Chart.js 2.0-beta2 2016-03-17 09:21:05 +01:00
James Brooks
71d6e692eb Merge pull request #1624 from CachetHQ/fix-component-group-collapsed-migration
Fixes #1608
2016-03-16 19:49:50 +00:00
James Brooks
045667dce8 Fixes #1608 2016-03-16 19:43:19 +00:00
Joe Cohen
93dcf5b68a Merge pull request #1623 from CachetHQ/missing-important
Add missing in important outline buttons
2016-03-16 13:42:20 -06:00
Joseph Cohen
1b383e1d57 Add missing in important outline buttons 2016-03-16 13:29:44 -06:00
James Brooks
83c03cc3c7 Merge pull request #1622 from CachetHQ/fix-scheduled-templates
Scheduled maintenance templates now work
2016-03-16 17:55:59 +00:00
James Brooks
419fa31d6e Fixes #1620 2016-03-16 17:40:26 +00:00
James Brooks
17bb3f66e8 Merge pull request #1621 from CachetHQ/truncate-incident-templates
Truncate incident templates
2016-03-16 09:41:52 +00:00
James Brooks
97ba43a898 Show incident template counts in the sidebar 2016-03-16 09:27:44 +00:00
James Brooks
51bbcc2a7d Always truncate incident templates 2016-03-16 09:26:39 +00:00
James Brooks
8e8a78ca10 Updated dashboard translations 2016-03-16 09:15:43 +00:00
James Brooks
dd062c673f Fix lost translations 2016-03-16 09:09:09 +00:00
James Brooks
4cb57c5f1e Rebuild assets 2016-03-16 09:05:41 +00:00
Graham Campbell
bf1ef04ce2 Merge pull request #1619 from CachetHQ/fix-subscribe-button
Fix status page subscribe button style
2016-03-15 23:43:31 +00:00
Joseph Cohen
4a86604bcc Fix status page subscribe button style 2016-03-15 16:29:48 -06:00
Joseph Cohen
6610c1a50c Rebuild assets 2016-03-15 15:31:43 -06:00
James Brooks
957d7e5722 Merge pull request #1618 from CachetHQ/fresh-look
New backoffice theme
2016-03-15 21:30:15 +00:00
Joseph Cohen
9844d0cff4 New backoffice theme 2016-03-15 15:15:40 -06:00
James Brooks
141ffeb474 Merge pull request #1616 from CachetHQ/sync-langs
Sync the language files
2016-03-15 17:50:16 +00:00
James Brooks
31614d0c4d Merge pull request #1615 from CachetHQ/analysis-8L3QVl
Applied fixes from StyleCI
2016-03-15 17:26:20 +00:00
James Brooks
3817fc2cc6 Applied fixes from StyleCI 2016-03-15 13:26:15 -04:00
James Brooks
3a278c1f5b Sync the language files 2016-03-15 17:25:56 +00:00
James Brooks
6c8a6b2822 Merge pull request #1612 from ManneW/ManneW-release-notes-1
Added section about release notes to README.md
2016-03-14 13:49:15 +00:00
Emanuel Winblad
0d4c7a7e28 Added section about release notes to README.md
A section for Release Notes has been added as a sub-item to the section "Installation, Upgrades and Documentation".
2016-03-14 14:21:19 +01:00
Graham Campbell
97b23cd002 Merge pull request #1609 from CachetHQ/fix-pg-change
Default to 2
2016-03-13 17:21:33 +00:00
James Brooks
97ec85ba2a Default to 2 2016-03-13 11:39:15 +00:00
Graham Campbell
cdfaadf986 Updated dependencies 2016-03-13 11:02:36 +00:00
James Brooks
9919853d07 Merge pull request #1604 from CachetHQ/auto-expand-component-groups
Auto expand component groups
2016-03-10 16:01:04 +00:00
James Brooks
a0477b03e3 Option to auto-expand groups when components are down. Closes #1602 2016-03-10 15:01:13 +00:00
James Brooks
d4d31efeb7 Show the y-axis scale bars. Closes #1600 2016-03-10 08:54:22 +00:00
James Brooks
5fd3f379fc Rebuilt assets 2016-03-09 11:33:36 +00:00
James Brooks
b2fca4c55a Reduce the border-radius on .pager links 2016-03-09 11:33:31 +00:00
James Brooks
1a7b97b8b2 Remove unused _variables.scss 2016-03-09 11:29:44 +00:00
James Brooks
247016b61d Updated dependencies 2016-03-09 11:26:27 +00:00
James Brooks
13f1e6a713 Fix docblocks 2016-03-09 11:25:41 +00:00
James Brooks
f9e332cac7 Merge pull request #1579 from CachetHQ/basic-api-searching
Implement very basic API searching
2016-03-08 20:20:52 +00:00
James Brooks
0b3483fb8a Implement very basic API searching. Closes #1348 2016-03-08 18:55:04 +00:00
James Brooks
9379ab131c Merge pull request #1596 from CachetHQ/custom-headers-footers
Custom headers footers
2016-03-08 15:16:36 +00:00
James Brooks
5fa698f5b7 Custom headers and footers! Closes #1594 2016-03-08 15:00:29 +00:00
James Brooks
83991c132a Merge branch 'master' of github.com:CachetHQ/Cachet 2016-03-08 12:57:01 +00:00
Graham Campbell
6e7190b6bd Merge pull request #1593 from CachetHQ/deps
Updated dependencies
2016-03-08 09:19:30 +00:00
Graham Campbell
9791118581 Updated dependencies 2016-03-08 08:56:25 +00:00
James Brooks
186ea7e8c3 Updated dependencies 2016-03-07 11:58:10 +00:00
James Brooks
3184df7d6c Merge pull request #1580 from CachetHQ/scrolling-components-list
Scrolls the component list
2016-03-05 13:53:42 +00:00
James Brooks
06284ecd13 Closes #1500 2016-03-05 13:53:29 +00:00
James Brooks
4150f8c032 Fixes #1586 2016-03-05 13:38:06 +00:00
James Brooks
8051186de3 Merge pull request #1583 from CachetHQ/typehint-routers
Typehint router classes
2016-03-02 15:30:10 +00:00
James Brooks
d9c97d3ef5 Typehint all of the routers 2016-03-02 12:18:30 +00:00
James Brooks
73d59e082d Added cachet:seed command to docs 2016-02-29 22:12:41 +00:00
James Brooks
57273dd96f Added contributing help for non-developers, designers and developers 2016-02-29 22:10:40 +00:00
James Brooks
b4e023b7ce Added short description 2016-02-29 22:01:59 +00:00
James Brooks
924e74d3c8 Added Packagist badge 2016-02-29 22:00:58 +00:00
James Brooks
335d326a73 Updated node packages 2016-02-29 21:58:09 +00:00
James Brooks
d572a67855 Update bower assets. Rebuild. 2016-02-29 21:48:22 +00:00
James Brooks
328608dfff Colour the panel message arrows. Closes #1567 2016-02-29 21:40:40 +00:00
James Brooks
be78216ff3 Added a version endpoint 2016-02-29 21:31:25 +00:00
James Brooks
24a29f2251 Merge branch 'master' of github.com:CachetHQ/Cachet 2016-02-29 21:24:30 +00:00
James Brooks
d4655112ca Don't override existing data when updating metrics 2016-02-29 21:24:11 +00:00
James Brooks
f30710c5a8 Fixes #1574 - default display_chart to true 2016-02-29 21:23:58 +00:00
James Brooks
eee94086db Fix French not being German! 2016-02-29 20:45:35 +00:00
James Brooks
ca152ecbc0 Merge pull request #1573 from CachetHQ/analysis-8L3RaG
Applied fixes from StyleCI
2016-02-29 20:45:30 +00:00
James Brooks
fce4823d2c Applied fixes from StyleCI 2016-02-29 15:45:25 -05:00
James Brooks
a20b95b87c Updated dependencies 2016-02-29 20:34:09 +00:00
James Brooks
640571a6bc Moved CONTRIBUTING doc back to root 2016-02-29 20:32:49 +00:00
James Brooks
2ad0085370 Merge pull request #1568 from CachetHQ/meta-updates
Updated meta content for inline-previewing
2016-02-26 11:51:24 +00:00
James Brooks
053d3191c8 Updated meta content for inline-previewing 2016-02-26 11:35:53 +00:00
Graham Campbell
6b6f5ee09d Merge pull request #1566 from CachetHQ/remove-chmod
Remove chmod script
2016-02-26 10:43:33 +00:00
James Brooks
481296ad21 Remove chmod script 2016-02-26 10:10:25 +00:00
James Brooks
55d4a639d9 Merge pull request #1565 from CachetHQ/move-contributing-doc
Move the CONTRIBUTING.md file into .github
2016-02-26 08:34:48 +00:00
James Brooks
b19c9fc885 Move the CONTRIBUTING.md file into .github 2016-02-26 08:21:33 +00:00
Graham Campbell
a2abd43fd2 Merge pull request #1404 from CachetHQ/native-throttling
Native throttling
2016-02-25 21:40:40 +00:00
Graham Campbell
1ab9d95b9c Native throttling 2016-02-25 21:26:46 +00:00
Graham Campbell
08b490a3cc Merge pull request #1550 from CachetHQ/fix-api-paging
Start fixing sorting on API
2016-02-25 19:14:37 +00:00
Joseph Cohen
919c7127e7 Fixes API sorting and filtering. Closes #1489 2016-02-25 18:58:42 +00:00
Graham Campbell
98550c31c9 Merge pull request #1553 from CachetHQ/update-cors
Update cors
2016-02-25 17:51:18 +00:00
James Brooks
4deff42aff Updated laravel-cors. Closes #1485 2016-02-25 17:50:51 +00:00
Graham Campbell
e8cbd81ad0 Merge pull request #1561 from CachetHQ/deps
Updated dependencies
2016-02-25 17:45:03 +00:00
Graham Campbell
54a8fbd185 Updated dependencies 2016-02-25 17:35:37 +00:00
James Brooks
49c6a7806b Rebuilt assets 2016-02-24 13:51:08 +00:00
James Brooks
251e90433e Merge pull request #1554 from CachetHQ/tweaks
Tweaks
2016-02-24 13:50:13 +00:00
James Brooks
3f7d1f588b Remove unused styles 2016-02-24 13:39:17 +00:00
James Brooks
9a3b073fc6 Split up component groups to make it more obvious 2016-02-24 13:36:27 +00:00
James Brooks
f92761437d Move position of "About This Site". Don't double wrap text. 2016-02-24 13:20:33 +00:00
James Brooks
f186907d8b Seed with app_about data 2016-02-24 13:16:58 +00:00
James Brooks
718bd99c24 Merge pull request #1549 from CachetHQ/model-factory-change
Make the model factories more dynamic
2016-02-24 12:34:28 +00:00
James Brooks
5c0f39759e Make the model factories more dynamic 2016-02-24 12:14:33 +00:00
Graham Campbell
bc9607a735 Merge pull request #1543 from CachetHQ/paginate-metric-points-api
Paginate the points API for metrics
2016-02-22 16:58:56 +00:00
James Brooks
01e40c4684 Paginate the points API for metrics 2016-02-22 14:53:34 +00:00
Graham Campbell
69fe2d7b3a Merge pull request #1539 from CachetHQ/deps
Updated dependencies
2016-02-21 16:09:27 +00:00
Graham Campbell
363dd5358f Updated dependencies 2016-02-21 16:04:25 +00:00
Graham Campbell
3487194415 Merge pull request #1470 from CachetHQ/view-subscriptions
Subscription changes
2016-02-21 15:55:17 +00:00
James Brooks
08dc9e0be9 Merge pull request #1538 from CachetHQ/remove-badger-dependency
Remove JamesForks/badger dependency
2016-02-21 10:52:01 +00:00
James Brooks
781b2238c6 Remove JamesForks/badger dependency. Closes #1537 2016-02-21 10:25:30 +00:00
Joseph Cohen
e51504b3ec Add manage link to email notifications 2016-02-20 21:32:14 +00:00
James Brooks
af0e578a44 Manage my subscriptions page 2016-02-20 21:32:13 +00:00
James Brooks
140970ac37 Changed subscribers page description 2016-02-20 21:32:12 +00:00
James Brooks
0b78332a20 Display what subscriptions (if any) a subscriber has 2016-02-20 21:32:11 +00:00
James Brooks
c9f08a3e6e Show the verified subscriber count in the sidebar 2016-02-20 21:32:09 +00:00
Graham Campbell
52a1f42426 Merge branch '2.1'
# Conflicts:
#	VERSION
2016-02-20 21:31:04 +00:00
Graham Campbell
7bbba6e897 Bumped version 2016-02-20 21:29:33 +00:00
Graham Campbell
dc1022e6f3 Merge pull request #1536 from CachetHQ/merge
Merge from 2.1, and updates
2016-02-20 21:19:32 +00:00
Graham Campbell
63eaaa325e Updated dependencies 2016-02-20 21:18:26 +00:00
Graham Campbell
819738cc77 Updated badger 2016-02-20 21:14:42 +00:00
Graham Campbell
d096e603d4 Merge branch '2.1' into merge
# Conflicts:
#	composer.json
#	composer.lock
2016-02-20 21:14:25 +00:00
James Brooks
8d1c244e02 Merge pull request #1430 from CachetHQ/component-shields
Added Component badges/shields
2016-02-20 14:00:10 +00:00
James Brooks
37898bee60 Added Component badges/shields. Closes #1313 2016-02-20 13:14:29 +00:00
James Brooks
7b05d1d1b6 Merge pull request #1524 from CachetHQ/issue-template
Create ISSUE_TEMPLATE
2016-02-20 12:22:02 +00:00
James Brooks
625b7d9a81 Create ISSUE_TEMPLATE 2016-02-20 11:58:54 +00:00
James Brooks
cb08443b27 Merge pull request #1525 from CachetHQ/change-metric-points-value-column
Change metric_points.value to DECIMAL(15,3)
2016-02-20 11:54:40 +00:00
James Brooks
026d296d8f Change metric_points.value to DECIMAL(15,3). Closes #1508 2016-02-18 08:53:16 +00:00
Graham Campbell
37af01483a Merge pull request #1519 from CachetHQ/merge
Merge branch '2.1'
2016-02-17 20:22:26 +00:00
Graham Campbell
726f5e851d Merge branch '2.1' 2016-02-17 20:08:56 +00:00
Graham Campbell
73fa0951f7 Merge pull request #1514 from CachetHQ/version
Bumped version to target 2.2
2016-02-17 17:34:13 +00:00
Graham Campbell
4e3879a949 Updated composer.lock hashes 2016-02-17 17:33:53 +00:00
Graham Campbell
7f55829035 Bumped version to target 2.2 2016-02-17 17:28:29 +00:00
Graham Campbell
63dd826377 Merge pull request #1512 from CachetHQ/ajax-charts
Load metrics via AJAX
2016-02-17 17:27:09 +00:00
James Brooks
2565774fea Load metrics via AJAX. Fixes #819 2016-02-17 17:08:15 +00:00
693 changed files with 38763 additions and 7848 deletions

View File

@@ -1,4 +0,0 @@
{
"directory": "vendor/bower_components",
"interactive": false
}

View File

@@ -9,10 +9,11 @@ DB_DATABASE=cachet
DB_USERNAME=homestead
DB_PASSWORD=secret
DB_PORT=null
DB_PREFIX=null
CACHE_DRIVER=file
SESSION_DRIVER=file
QUEUE_DRIVER=database
QUEUE_DRIVER=sync
CACHET_EMOJI=false
MAIL_DRIVER=smtp

2
.gitattributes vendored
View File

@@ -1,3 +1,5 @@
* text=auto
*.css linguist-vendored
*.scss linguist-vendored
/.github export-ignore
/tests export-ignore

20
.github/ISSUE_TEMPLATE vendored Normal file
View File

@@ -0,0 +1,20 @@
Before submitting your issue, please make sure that you've checked the checkboxes below.
- [ ] I am running the [latest release](https://github.com/CachetHQ/Cachet/releases/latest) version of Cachet.
- [ ] I am running at least PHP 5.5.9. *You can check this by running `php -v`.*
- [ ] I have ran `rm -rf bootstrap/cache/*`.
### Expected behaviour
*Please describe what you're expecting to see happen.*
### Actual behaviour
*Please describe what you're actually seeing happen.*
### Steps to reproduce
*If your issue requires any specific steps to reproduce, please outline them here.*
1. First step
2. Second step

View File

@@ -1,21 +1,18 @@
language: php
sudo: false
dist: trusty
php:
- 5.5.9
- 5.5
- 5.6
- 7.0
- hhvm
- 7.1
sudo: false
before_install: cp .env.example .env
install:
- travis_retry composer install --no-interaction --no-scripts --prefer-source
install: travis_retry composer install --no-interaction --no-scripts --prefer-source
script:
- if [ "$TRAVIS_PHP_VERSION" != "5.6" ] || [ "$TRAVIS_PULL_REQUEST" != false ]; then vendor/bin/phpunit; fi
- if [ "$TRAVIS_PHP_VERSION" == "5.6" ] && [ "$TRAVIS_PULL_REQUEST" == false ]; then vendor/bin/phpunit --coverage-clover build/logs/clover.xml; fi
after_script:
- if [ "$TRAVIS_PHP_VERSION" == "5.6" ] && [ "$TRAVIS_PULL_REQUEST" == false ]; then wget https://scrutinizer-ci.com/ocular.phar; fi
- if [ "$TRAVIS_PHP_VERSION" == "5.6" ] && [ "$TRAVIS_PULL_REQUEST" == false ]; then php ocular.phar code-coverage:upload --format=php-clover build/logs/clover.xml; fi
script: vendor/bin/phpunit

View File

@@ -1,13 +1,15 @@
# Cachet
[![StyleCI](https://styleci.io/repos/26730195/shield)](https://styleci.io/repos/26730195/)
[![Build Status](https://img.shields.io/travis/CachetHQ/Cachet.svg?style=flat-square)](https://travis-ci.org/CachetHQ/Cachet)
[![Quality Score](https://img.shields.io/scrutinizer/g/CachetHQ/Cachet.svg?style=flat-square)](https://scrutinizer-ci.com/g/CachetHQ/Cachet)
[![Build Status](https://img.shields.io/travis/CachetHQ/Cachet/2.3.svg?style=flat-square)](https://travis-ci.org/CachetHQ/Cachet)
[![Software License](https://img.shields.io/badge/license-BSD3-brightgreen.svg?style=flat-square)](LICENSE)
[![Crowdin](https://d322cqt584bo4o.cloudfront.net/cachet/localized.png)](http://translate.cachethq.io/project/cachet)
[![Crowdin](https://d322cqt584bo4o.cloudfront.net/cachet/localized.svg)](http://translate.cachethq.io/project/cachet)
[![Packagist](https://img.shields.io/packagist/v/cachethq/cachet.svg?style=flat-square)](https://packagist.org/packages/cachethq/cachet)
![Screenshot](https://cachethq.io/img/main-interface.jpg)
Cachet is a beautiful and powerful open source status page system.
## Features
- List your services components
@@ -19,46 +21,86 @@
- Metrics
- Cross-database support: MySQL, PostgreSQL and SQLite
- Subscriber notifications via Email
- Two factor authentication, with Google Authenticator
## Usage in production
The `master` branch of this repository is a development branch and **should not** be used in production. Instead, please check out the latest tag release.
- Two factor authentication using Google Authenticator
## Requirements
- PHP 5.5.9+ or newer
- PHP 5.5.9 - 7.1
- Apache or Nginx server
- [Composer](https://getcomposer.org)
### Development Requirements
## I'm looking to contribute to this awesome project!
These extra dependencies are required to develop Cachet:
Sweet, we're always looking for contributions that improve Cachet! It's easy to get started and you don't even need to know how to write a single line of code!
### Contributing as a non-developer/non-designer
We're always looking for new [translations](#translations).
Of course bug reports, feature requests and [documentation](https://docs.cachethq.io) are always appreciated.
### Contributing as a designer
As Cachet gains new features, the design and ideas that were once a perfect fit need updating and in some cases designing from scratch. This is where you come in! Fancy giving Cachet a lick of paint? Sweet!
You'll need to install Node.js, Bower and Gulp.
To get started you can do the following:
1. Install Node.js and our dev dependencies.
2. Make your changes to the SCSS files in `./resources/assets/sass/`
3. Run `gulp`
If you're making a lot of changes, you'll find that running `gulp watch` will make life easier for you!
### Contributing as a developer
Built using [Laravel](https://laravel.com).
We use these extra dependencies to develop Cachet:
- Node.js
- Bower
- Gulp
- Git
Once cloned to your local machine, you'll need some demo data! Run `php artisan cachet:seed` to get the demo installation ready for action.
## Installation, Upgrades and Documentation
You can now find our documentation at [https://docs.cachethq.io](https://docs.cachethq.io).
Documentation is found at [https://docs.cachethq.io](https://docs.cachethq.io).
Here are some useful quick links:
- [Installing Cachet](https://docs.cachethq.io/docs/installing-cachet)
- [Getting started with Docker](https://docs.cachethq.io/docs/get-started-with-docker)
- [Getting started with Vagrant](https://docs.cachethq.io/docs/get-started-with-vagrant)
### Demo Account
To test out the demo, you may login to the [Dashboard](https://demo.cachethq.io/dashboard) with the following:
- **Username:** test or test@test.com
- **Password:** test123
- **Username:** `test` or `test@test.com`
- **Password:** `test123`
The demo is reset every half hour.
### Release Notes
We list releases on the [Releases page](https://github.com/CachetHQ/Cachet/releases) of the [Cachet GitHub repository](https://github.com/CachetHQ/Cachet). On the Releases page, you can also find the release notes for each release.
## Translations
A special thank you to our [translators](https://crowdin.com/project/cachet/activity_stream), who have allowed us to share Cachet with the world. If you'd like to contribute translations, please check out our [CrowdIn project](https://crowdin.com/project/cachet).
If you'd like to contribute translations, please check out our [CrowdIn project](https://crowdin.com/project/cachet).
> Thank you to our [translators](https://crowdin.com/project/cachet/activity_stream), who have allowed us to share Cachet with the world!
## Show your support
Cachet is a BSD-3-licensed open source project.
## Professional Installation Service
We offer a professional installation service. To find out more, email us at [support@alt-three.com](mailto:support@alt-three.com?Cachet Installation)
## Security Vulnerabilities
If you discover a security vulnerability within Cachet, please send an e-mail to us at support@alt-three.com. All security vulnerabilities will be promptly addressed.
If you discover a security vulnerability within Cachet, please send an e-mail to us at support@alt-three.com. We handle all security vulnerabilities on a case-by-case basis.

View File

@@ -1 +1 @@
2.1.2
2.3.19-dev

View File

@@ -11,6 +11,11 @@
namespace CachetHQ\Cachet\Bus\Commands\ComponentGroup;
/**
* This is the add component group command.
*
* @author James Brooks <james@alt-three.com>
*/
final class AddComponentGroupCommand
{
/**
@@ -30,7 +35,7 @@ final class AddComponentGroupCommand
/**
* Is the component group collapsed?
*
* @var bool
* @var int
*/
public $collapsed;
@@ -42,7 +47,7 @@ final class AddComponentGroupCommand
public $rules = [
'name' => 'required|string',
'order' => 'int',
'collapsed' => 'bool',
'collapsed' => 'int|between:0,3',
];
/**
@@ -50,7 +55,7 @@ final class AddComponentGroupCommand
*
* @param string $name
* @param int $order
* @param bool $collapsed
* @param int $collapsed
*
* @return void
*/

View File

@@ -13,6 +13,11 @@ namespace CachetHQ\Cachet\Bus\Commands\ComponentGroup;
use CachetHQ\Cachet\Models\ComponentGroup;
/**
* This is the update component group command.
*
* @author James Brooks <james@alt-three.com>
*/
final class UpdateComponentGroupCommand
{
/**
@@ -39,7 +44,7 @@ final class UpdateComponentGroupCommand
/**
* Is the component group collapsed?
*
* @var bool
* @var int
*/
public $collapsed;
@@ -51,7 +56,7 @@ final class UpdateComponentGroupCommand
public $rules = [
'name' => 'string',
'order' => 'int',
'collapsed' => 'bool',
'collapsed' => 'int|between:0,3',
];
/**
@@ -60,7 +65,7 @@ final class UpdateComponentGroupCommand
* @param \CachetHQ\Cachet\Models\ComponentGroup $group
* @param string $name
* @param int $order
* @param bool $collapsed
* @param int $collapsed
*
* @return void
*/

View File

@@ -69,6 +69,20 @@ final class AddMetricCommand
*/
public $default_view;
/**
* The threshold to buffer the metric points in.
*
* @var int
*/
public $threshold;
/**
* The order of which to place the metric in.
*
* @var int
*/
public $order;
/**
* The validation rules.
*
@@ -84,6 +98,8 @@ final class AddMetricCommand
'display_chart' => 'int',
'places' => 'int|between:0,4',
'default_view' => 'int|between:0,3',
'threshold' => 'numeric|between:0,10',
'order' => 'int',
];
/**
@@ -97,10 +113,12 @@ final class AddMetricCommand
* @param int $display_chart
* @param int $places
* @param int $default_view
* @param int $threshold
* @param int $order
*
* @return void
*/
public function __construct($name, $suffix, $description, $default_value, $calc_type, $display_chart, $places, $default_view)
public function __construct($name, $suffix, $description, $default_value, $calc_type, $display_chart, $places, $default_view, $threshold, $order = 0)
{
$this->name = $name;
$this->suffix = $suffix;
@@ -110,5 +128,7 @@ final class AddMetricCommand
$this->display_chart = $display_chart;
$this->places = $places;
$this->default_view = $default_view;
$this->threshold = $threshold;
$this->order = $order;
}
}

View File

@@ -42,7 +42,7 @@ final class AddMetricPointCommand
* @var string[]
*/
public $rules = [
'value' => 'int',
'value' => 'numeric',
'created_at' => 'string',
];

View File

@@ -78,6 +78,20 @@ final class UpdateMetricCommand
*/
public $default_view;
/**
* The threshold to buffer the metric points in.
*
* @var int
*/
public $threshold;
/**
* The order of which to place the metric in.
*
* @var int|null
*/
public $order;
/**
* The validation rules.
*
@@ -93,6 +107,8 @@ final class UpdateMetricCommand
'display_chart' => 'int',
'places' => 'numeric|between:0,4',
'default_view' => 'numeric|between:0,4',
'threshold' => 'numeric|between:0,10',
'order' => 'int',
];
/**
@@ -107,10 +123,12 @@ final class UpdateMetricCommand
* @param int $display_chart
* @param int $places
* @param int $default_view
* @param int $threshold
* @param int|null $order
*
* @return void
*/
public function __construct(Metric $metric, $name, $suffix, $description, $default_value, $calc_type, $display_chart, $places, $default_view)
public function __construct(Metric $metric, $name, $suffix, $description, $default_value, $calc_type, $display_chart, $places, $default_view, $threshold, $order = null)
{
$this->metric = $metric;
$this->name = $name;
@@ -121,5 +139,7 @@ final class UpdateMetricCommand
$this->display_chart = $display_chart;
$this->places = $places;
$this->default_view = $default_view;
$this->threshold = $threshold;
$this->order = $order;
}
}

View File

@@ -14,6 +14,11 @@ namespace CachetHQ\Cachet\Bus\Commands\Metric;
use CachetHQ\Cachet\Models\Metric;
use CachetHQ\Cachet\Models\MetricPoint;
/**
* This is the update metric point command.
*
* @author James Brooks <james@alt-three.com>
*/
final class UpdateMetricPointCommand
{
/**
@@ -33,7 +38,7 @@ final class UpdateMetricPointCommand
/**
* The metric point value.
*
* @var int
* @var float
*/
public $value;
@@ -50,7 +55,7 @@ final class UpdateMetricPointCommand
* @var string[]
*/
public $rules = [
'value' => 'int',
'value' => 'numeric',
'created_at' => 'string',
];
@@ -59,7 +64,7 @@ final class UpdateMetricPointCommand
*
* @param \CachetHQ\Cachet\Models\MetricPoint $point
* @param \CachetHQ\Cachet\Models\Metric $metric
* @param int $value
* @param float $value
* @param string $created_at
*
* @return void

View File

@@ -33,7 +33,7 @@ final class SubscribeSubscriberCommand
public $verified;
/**
* The subscriptions that we want to add.
* The list of subscriptions to set the subscriber up with.
*
* @var array|null
*/
@@ -53,7 +53,7 @@ final class SubscribeSubscriberCommand
*
* @param string $email
* @param bool $verified
* @param null|array $subscriptions
* @param array|null $subscriptions
*
* @return void
*/

View File

@@ -0,0 +1,50 @@
<?php
/*
* This file is part of Cachet.
*
* (c) Alt Three Services Limited
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace CachetHQ\Cachet\Bus\Commands\Subscriber;
use CachetHQ\Cachet\Models\Subscriber;
/**
* This is the subscribe subscriber command.
*
* @author Joseph Cohen <joe@alt-three.com>
*/
final class UpdateSubscriberSubscriptionCommand
{
/**
* The subscriber email.
*
* @var \CachetHQ\Cachet\Models\Subscriber
*/
public $subscriber;
/**
* The subscriptions that we want to add.
*
* @var array|null
*/
public $subscriptions;
/**
* Create a new subscribe subscriber command instance.
*
* @param \CachetHQ\Cachet\Models\Subscriber $subscriber
* @param null|array $subscriptions
*
* @return void
*/
public function __construct($subscriber, $subscriptions = null)
{
$this->subscriber = $subscriber;
$this->subscriptions = $subscriptions;
}
}

View File

@@ -1,26 +0,0 @@
<?php
/*
* This file is part of Cachet.
*
* (c) Alt Three Services Limited
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace CachetHQ\Cachet\Bus\Exceptions\Subscriber;
use CachetHQ\Cachet\Bus\Exceptions\ExceptionInterface;
use Exception;
/**
* This is the already subscribed exception class.
*
* @author Graham Campbell <graham@alt-three.com>
* @author James Brooks <james@alt-three.com>
*/
class AlreadySubscribedException extends Exception implements ExceptionInterface
{
//
}

View File

@@ -18,8 +18,13 @@ use CachetHQ\Cachet\Models\Component;
use CachetHQ\Cachet\Models\Incident;
use CachetHQ\Cachet\Models\IncidentTemplate;
use Twig_Loader_String;
use TwigBridge\Facade\Twig;
use TwigBridge\Bridge;
/**
* This is the report incident command handler.
*
* @author James Brooks <james@alt-three.com>
*/
class ReportIncidentCommandHandler
{
/**
@@ -29,16 +34,25 @@ class ReportIncidentCommandHandler
*/
protected $dates;
/**
* The twig bridge instance.
*
* @var \TwigBridge\Bridge
*/
protected $twig;
/**
* Create a new report incident command handler instance.
*
* @param \CachetHQ\Cachet\Dates\DateFactory $dates
* @param \TwigBridge\Bridge $twig
*
* @return void
*/
public function __construct(DateFactory $dates)
public function __construct(DateFactory $dates, Bridge $twig)
{
$this->dates = $dates;
$this->twig = $twig;
}
/**
@@ -56,7 +70,7 @@ class ReportIncidentCommandHandler
'visible' => $command->visible,
];
if ($command->template) {
if (IncidentTemplate::where('slug', '=', $command->template)->first()) {
$data['message'] = $this->parseIncidentTemplate($command->template, $command->template_vars);
} else {
$data['message'] = $command->message;
@@ -106,9 +120,9 @@ class ReportIncidentCommandHandler
$vars = [];
}
Twig::setLoader(new Twig_Loader_String());
$this->twig->setLoader(new Twig_Loader_String());
$template = IncidentTemplate::forSlug($templateSlug)->first();
return Twig::render($template->template, $vars);
return $this->twig->render($template->template, $vars);
}
}

View File

@@ -18,8 +18,13 @@ use CachetHQ\Cachet\Models\Component;
use CachetHQ\Cachet\Models\Incident;
use CachetHQ\Cachet\Models\IncidentTemplate;
use Twig_Loader_String;
use TwigBridge\Facade\Twig;
use TwigBridge\Bridge;
/**
* This is the update incident command handler.
*
* @author James Brooks <james@alt-three.com>
*/
class UpdateIncidentCommandHandler
{
/**
@@ -29,16 +34,25 @@ class UpdateIncidentCommandHandler
*/
protected $dates;
/**
* The twig bridge instance.
*
* @var \TwigBridge\Bridge
*/
protected $twig;
/**
* Create a new update incident command handler instance.
*
* @param \CachetHQ\Cachet\Dates\DateFactory $dates
* @param \TwigBridge\Bridge $twig
*
* @return void
*/
public function __construct(DateFactory $dates)
public function __construct(DateFactory $dates, Bridge $twig)
{
$this->dates = $dates;
$this->twig = $twig;
}
/**
@@ -113,9 +127,9 @@ class UpdateIncidentCommandHandler
*/
protected function parseIncidentTemplate($templateSlug, $vars)
{
Twig::setLoader(new Twig_Loader_String());
$this->twig->setLoader(new Twig_Loader_String());
$template = IncidentTemplate::forSlug($templateSlug)->first();
return Twig::render($template->template, $vars);
return $this->twig->render($template->template, $vars);
}
}

View File

@@ -35,6 +35,8 @@ class AddMetricCommandHandler
'display_chart' => $command->display_chart,
'places' => $command->places,
'default_view' => $command->default_view,
'threshold' => $command->threshold,
'order' => $command->order,
]);
event(new MetricWasAddedEvent($metric));

View File

@@ -15,6 +15,7 @@ use CachetHQ\Cachet\Bus\Commands\Metric\AddMetricPointCommand;
use CachetHQ\Cachet\Bus\Events\Metric\MetricPointWasAddedEvent;
use CachetHQ\Cachet\Dates\DateFactory;
use CachetHQ\Cachet\Models\MetricPoint;
use Carbon\Carbon;
class AddMetricPointCommandHandler
{
@@ -49,19 +50,35 @@ class AddMetricPointCommandHandler
$metric = $command->metric;
$createdAt = $command->created_at;
$data = [
'metric_id' => $metric->id,
'value' => $command->value,
];
// Do we have an existing point with the same value?
$point = $this->findOrCreatePoint($command);
if ($createdAt) {
$data['created_at'] = $this->dates->create('U', $createdAt)->format('Y-m-d H:i:s');
$point->increment('counter', 1);
event(new MetricPointWasAddedEvent($point));
return $point;
}
protected function findOrCreatePoint(AddMetricPointCommand $command)
{
$buffer = Carbon::now()->subMinutes($command->metric->threshold);
$point = MetricPoint::where('metric_id', $command->metric->id)->where('value', $command->value)->where('created_at', '>=', $buffer)->first();
if ($point) {
return $point;
}
$metricPoint = MetricPoint::create($data);
$data = [
'metric_id' => $command->metric->id,
'value' => $command->value,
'counter' => 0,
];
event(new MetricPointWasAddedEvent($metricPoint));
if ($command->created_at) {
$data['created_at'] = $this->dates->create('U', $command->created_at)->format('Y-m-d H:i:s');
}
return $metricPoint;
return MetricPoint::create($data);
}
}

View File

@@ -53,6 +53,8 @@ class UpdateMetricCommandHandler
'display_chart' => $command->display_chart,
'places' => $command->places,
'default_view' => $command->default_view,
'threshold' => $command->threshold,
'order' => $command->order,
];
return array_filter($params, function ($val) {

View File

@@ -51,7 +51,7 @@ class UpdateMetricPointCommandHandler
$data = [
'metric_id' => $metric->id,
'value' => $command->value,
'value' => (float) $command->value,
];
if ($createdAt) {

View File

@@ -14,8 +14,7 @@ namespace CachetHQ\Cachet\Bus\Handlers\Commands\Subscriber;
use CachetHQ\Cachet\Bus\Commands\Subscriber\SubscribeSubscriberCommand;
use CachetHQ\Cachet\Bus\Commands\Subscriber\VerifySubscriberCommand;
use CachetHQ\Cachet\Bus\Events\Subscriber\SubscriberHasSubscribedEvent;
use CachetHQ\Cachet\Bus\Events\Subscriber\SubscriberHasUpdatedSubscriptionsEvent;
use CachetHQ\Cachet\Bus\Exceptions\Subscriber\AlreadySubscribedException;
use CachetHQ\Cachet\Models\Component;
use CachetHQ\Cachet\Models\Subscriber;
use CachetHQ\Cachet\Models\Subscription;
@@ -23,6 +22,8 @@ use CachetHQ\Cachet\Models\Subscription;
* This is the subscribe subscriber command handler.
*
* @author James Brooks <james@alt-three.com>
* @author Joe Cohen <joe@alt-three.com>
* @author Graham Campbell <graham@alt-three.com>
*/
class SubscribeSubscriberCommandHandler
{
@@ -31,37 +32,38 @@ class SubscribeSubscriberCommandHandler
*
* @param \CachetHQ\Cachet\Bus\Commands\Subscriber\SubscribeSubscriberCommand $command
*
* @throws \CachetHQ\Cachet\Exceptions\AlreadySubscribedException
*
* @return \CachetHQ\Cachet\Models\Subscriber
*/
public function handle(SubscribeSubscriberCommand $command)
{
if (Subscriber::where('email', $command->email)->first() && $command->subscriptions === null) {
throw new AlreadySubscribedException("Cannot subscribe {$command->email} because they're already subscribed.");
if ($subscriber = Subscriber::where('email', $command->email)->first()) {
return $subscriber;
}
$subscriber = Subscriber::firstOrCreate(['email' => $command->email]);
// Decide what to subscribe the subscriber to.
if ($subscriptions = $command->subscriptions) {
foreach ($subscriptions as $subscription => $subscriptionValue) {
Subscription::firstOrCreate([
'subscriber_id' => $subscriber->id,
$subscription => $subscriptionValue,
]);
}
$components = Component::whereIn('id', $subscriptions)->get();
} else {
$components = Component::all();
}
if ($subscriber->is_verified === false) {
if ($command->verified) {
dispatch(new VerifySubscriberCommand($subscriber));
} else {
event(new SubscriberHasSubscribedEvent($subscriber));
}
$components->map(function ($component) use ($subscriber) {
Subscription::create([
'subscriber_id' => $subscriber->id,
'component_id' => $component->id,
]);
});
if ($command->verified) {
dispatch(new VerifySubscriberCommand($subscriber));
} else {
event(new SubscriberHasUpdatedSubscriptionsEvent($subscriber));
event(new SubscriberHasSubscribedEvent($subscriber));
}
$subscriber->load('subscriptions');
return $subscriber;
}
}

View File

@@ -13,7 +13,6 @@ namespace CachetHQ\Cachet\Bus\Handlers\Commands\Subscriber;
use CachetHQ\Cachet\Bus\Commands\Subscriber\UnsubscribeSubscriberCommand;
use CachetHQ\Cachet\Bus\Events\Subscriber\SubscriberHasUnsubscribedEvent;
use CachetHQ\Cachet\Models\Subscriber;
class UnsubscribeSubscriberCommandHandler
{

View File

@@ -0,0 +1,64 @@
<?php
/*
* This file is part of Cachet.
*
* (c) Alt Three Services Limited
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace CachetHQ\Cachet\Bus\Handlers\Commands\Subscriber;
use CachetHQ\Cachet\Bus\Commands\Subscriber\UpdateSubscriberSubscriptionCommand;
use CachetHQ\Cachet\Bus\Events\Subscriber\SubscriberHasUpdatedSubscriptionsEvent;
use CachetHQ\Cachet\Models\Component;
use CachetHQ\Cachet\Models\Subscriber;
use CachetHQ\Cachet\Models\Subscription;
/**
* This is the subscribe subscriber command handler.
*
* @author Joseph Cohen <joe@alt-three.com>
*/
class UpdateSubscriberSubscriptionCommandHandler
{
/**
* Handle the subscribe subscriber command.
*
* @param \CachetHQ\Cachet\Bus\Commands\Subscriber\UpdateSubscriberSubscriptionCommand $command
*
* @return \CachetHQ\Cachet\Models\Subscriber
*/
public function handle(UpdateSubscriberSubscriptionCommand $command)
{
$subscriber = $command->subscriber;
$subscriptions = $command->subscriptions ?: [];
$components = Component::all();
$updateSubscriptions = $components->filter(function ($item) use ($subscriptions) {
return in_array($item->id, $subscriptions);
});
$subscriber->global = ($updateSubscriptions->count() === $components->count());
$subscriber->subscriptions()->delete();
if (!$updateSubscriptions->isEmpty()) {
foreach ($updateSubscriptions as $subscription) {
Subscription::firstOrCreate([
'subscriber_id' => $subscriber->id,
'component_id' => $subscription->id,
]);
}
}
$subscriber->save();
event(new SubscriberHasUpdatedSubscriptionsEvent($subscriber));
return $subscriber;
}
}

View File

@@ -0,0 +1,40 @@
<?php
/*
* This file is part of Cachet.
*
* (c) Alt Three Services Limited
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace CachetHQ\Cachet\Bus\Handlers\Events\Component;
use CachetHQ\Cachet\Bus\Events\Component\ComponentWasRemovedEvent;
use CachetHQ\Cachet\Models\Component;
use CachetHQ\Cachet\Models\Subscription;
/**
* This is the cleanup component subscriptions handler.
*
* @author James Brooks <james@alt-three.com>
*/
class CleanupComponentSubscriptionsHandler
{
/**
* Handle the event.
*
* @param \CachetHQ\Cachet\Bus\Events\Component\ComponentWasRemovedEvent $event
*
* @return void
*/
public function handle(ComponentWasRemovedEvent $event)
{
$component = $event->component;
$subscription = Subscription::forComponent($component->id);
// Cleanup the subscriptions.
$subscription->delete();
}
}

View File

@@ -13,7 +13,7 @@ namespace CachetHQ\Cachet\Bus\Handlers\Events\Component;
use CachetHQ\Cachet\Bus\Events\Component\ComponentWasUpdatedEvent;
use CachetHQ\Cachet\Models\Component;
use CachetHQ\Cachet\Models\Subscription;
use CachetHQ\Cachet\Models\Subscriber;
use Illuminate\Contracts\Mail\MailQueue;
use Illuminate\Mail\Message;
use McCool\LaravelAutoPresenter\Facades\AutoPresenter;
@@ -27,16 +27,25 @@ class SendComponentUpdateEmailNotificationHandler
*/
protected $mailer;
/**
* The subscriber instance.
*
* @var \CachetHQ\Cachet\Models\Subscriber
*/
protected $subscriber;
/**
* Create a new send incident email notification handler.
*
* @param \Illuminate\Contracts\Mail\Mailer $mailer
* @param \Illuminate\Contracts\Mail\Mailer $mailer
* @param \CachetHQ\Cachet\Models\Subscriber $subscriber
*
* @return void
*/
public function __construct(MailQueue $mailer)
public function __construct(MailQueue $mailer, Subscriber $subscriber)
{
$this->mailer = $mailer;
$this->subscriber = $subscriber;
}
/**
@@ -48,7 +57,42 @@ class SendComponentUpdateEmailNotificationHandler
*/
public function handle(ComponentWasUpdatedEvent $event)
{
$component = AutoPresenter::decorate($event->component);
$component = $event->component;
// First notify all global subscribers.
$globalSubscribers = $this->subscriber->isVerified()->isGlobal()->get();
foreach ($globalSubscribers as $subscriber) {
$this->notify($component, $subscriber);
}
$notified = $globalSubscribers->pluck('id')->all();
// Notify the remaining component specific subscribers.
$componentSubscribers = $this->subscriber
->isVerified()
->forComponent($component->id)
->get()
->reject(function ($subscriber) use ($notified) {
return in_array($subscriber->id, $notified);
});
foreach ($componentSubscribers as $subscriber) {
$this->notify($component, $subscriber);
}
}
/**
* Send notification to subscriber.
*
* @param \CachetHQ\Cachet\Models\Component $component
* @param \CachetHQ\Cachet\Models\Subscriber $subscriber
*
* @return \Illuminate\Database\Eloquent\Collection
*/
public function notify(Component $component, Subscriber $subscriber)
{
$component = AutoPresenter::decorate($component);
$mail = [
'subject' => trans('cachet.subscriber.email.component.subject'),
@@ -56,17 +100,14 @@ class SendComponentUpdateEmailNotificationHandler
'component_human_status' => $component->human_status,
];
foreach (Subscription::isVerifiedForComponent($component->id)->with('subscriber')->get() as $subscription) {
$subscriber = $subscription->subscriber;
$mail['email'] = $subscriber->email;
$mail['unsubscribe_link'] = route('subscribe.unsubscribe', ['code' => $subscriber->verify_code, 'subscription' => $subscription->id]);
$mail['email'] = $subscriber->email;
$mail['manage_link'] = route('subscribe.manage', ['code' => $subscriber->verify_code]);
$this->mailer->queue([
'html' => 'emails.components.update-html',
'text' => 'emails.components.update-text',
], $mail, function (Message $message) use ($mail) {
$message->to($mail['email'])->subject($mail['subject']);
});
}
$this->mailer->queue([
'html' => 'emails.components.update-html',
'text' => 'emails.components.update-text',
], $mail, function (Message $message) use ($mail) {
$message->to($mail['email'])->subject($mail['subject']);
});
}
}

View File

@@ -50,7 +50,7 @@ class SendIncidentEmailNotificationHandler
/**
* Handle the event.
*
* @param \CachetHQ\Cachet\Bus\Events\Incident\IncidentHasReportedEvent $event
* @param \CachetHQ\Cachet\Bus\Events\Incident\IncidentWasReportedEvent $event
*
* @return void
*/
@@ -60,31 +60,74 @@ class SendIncidentEmailNotificationHandler
return false;
}
// Only send emails for public incidents.
if ($event->incident->visible === 0) {
return;
}
// First notify all global subscribers.
$globalSubscribers = $this->subscriber->isVerified()->isGlobal()->get();
foreach ($globalSubscribers as $subscriber) {
$this->notify($event, $subscriber);
}
if (!$event->incident->component) {
return;
}
$notified = $globalSubscribers->pluck('id')->all();
// Notify the remaining component specific subscribers.
$componentSubscribers = $this->subscriber
->isVerified()
->forComponent($event->incident->component->id)
->get()
->reject(function ($subscriber) use ($notified) {
return in_array($subscriber->id, $notified);
});
foreach ($componentSubscribers as $subscriber) {
$this->notify($event, $subscriber);
}
}
/**
* Send notification to subscriber.
*
* @param \CachetHQ\Cachet\Bus\Events\IncidentWasReportedEvent $event
* @param \CachetHQ\Cachet\Models\Subscriber $subscriber
*
* @return \Illuminate\Database\Eloquent\Collection
*/
public function notify(IncidentWasReportedEvent $event, $subscriber)
{
$incident = AutoPresenter::decorate($event->incident);
$component = AutoPresenter::decorate($event->incident->component);
// Only send emails for public incidents.
if ($event->incident->visible === 1) {
foreach ($this->subscriber->isVerified()->get() as $subscriber) {
$mail = [
'email' => $subscriber->email,
'subject' => 'New incident reported.',
'has_component' => ($event->incident->component) ? true : false,
'component_name' => $component ? $component->name : null,
'status' => $incident->human_status,
'html_content' => $incident->formattedMessage,
'text_content' => $incident->message,
'token' => $subscriber->token,
'unsubscribe_link' => route('subscribe.unsubscribe', ['code' => $subscriber->verify_code]),
];
$mail = [
'email' => $subscriber->email,
'subject' => trans('cachet.subscriber.email.incident.subject', [
'status' => $incident->human_status,
'name' => $incident->name,
]),
'has_component' => ($event->incident->component) ? true : false,
'component_name' => $component ? $component->name : null,
'name' => $incident->name,
'timestamp' => $incident->created_at_formatted,
'status' => $incident->human_status,
'html_content' => $incident->formattedMessage,
'text_content' => $incident->message,
'token' => $subscriber->token,
'manage_link' => route('subscribe.manage', ['code' => $subscriber->verify_code]),
'unsubscribe_link' => route('subscribe.unsubscribe', ['code' => $subscriber->verify_code]),
];
$this->mailer->queue([
'html' => 'emails.incidents.new-html',
'text' => 'emails.incidents.new-text',
], $mail, function (Message $message) use ($mail) {
$message->to($mail['email'])->subject($mail['subject']);
});
}
}
$this->mailer->queue([
'html' => 'emails.incidents.new-html',
'text' => 'emails.incidents.new-text',
], $mail, function (Message $message) use ($mail) {
$message->to($mail['email'])->subject($mail['subject']);
});
}
}

View File

@@ -50,7 +50,7 @@ class SendMaintenanceEmailNotificationHandler
/**
* Handle the event.
*
* @param \CachetHQ\Cachet\Bus\Events\MaintenanceHasScheduledEvent $event
* @param \CachetHQ\Cachet\Bus\Events\MaintenanceWasScheduledEvent $event
*
* @return void
*/
@@ -60,26 +60,73 @@ class SendMaintenanceEmailNotificationHandler
return false;
}
$data = AutoPresenter::decorate($event->incident);
// Only send emails for public incidents.
if ($event->incident->visible === 0) {
return;
}
foreach ($this->subscriber->isVerified()->get() as $subscriber) {
$mail = [
'email' => $subscriber->email,
'subject' => 'Scheduled maintenance.',
'status' => $data->human_status,
'html_content' => $data->formattedMessage,
'text_content' => $data->message,
'scheduled_at' => $data->scheduled_at_formatted,
'token' => $subscriber->token,
'unsubscribe_link' => route('subscribe.unsubscribe', ['code' => $subscriber->verify_code]),
];
// First notify all global subscribers.
$globalSubscribers = $this->subscriber->isVerified()->isGlobal()->get();
$this->mailer->queue([
'html' => 'emails.incidents.maintenance-html',
'text' => 'emails.incidents.maintenance-text',
], $mail, function (Message $message) use ($mail) {
$message->to($mail['email'])->subject($mail['subject']);
foreach ($globalSubscribers as $subscriber) {
$this->notify($event, $subscriber);
}
if (!$event->incident->component) {
return;
}
$notified = $globalSubscribers->pluck('id')->all();
// Notify the remaining component specific subscribers.
$componentSubscribers = $this->subscriber
->isVerified()
->forComponent($event->incident->component->id)
->get()
->reject(function ($subscriber) use ($notified) {
return in_array($subscriber->id, $notified);
});
foreach ($componentSubscribers as $subscriber) {
$this->notify($event, $subscriber);
}
}
/**
* Send notification to subscriber.
*
* @param \CachetHQ\Cachet\Bus\Events\MaintenanceWasScheduledEvent $event
* @param \CachetHQ\Cachet\Models\Subscriber $subscriber
*
* @return \Illuminate\Database\Eloquent\Collection
*/
public function notify(MaintenanceWasScheduledEvent $event, $subscriber)
{
$incident = AutoPresenter::decorate($event->incident);
$component = AutoPresenter::decorate($event->incident->component);
$mail = [
'email' => $subscriber->email,
'subject' => trans('cachet.subscriber.email.maintenance.subject', [
'name' => $incident->name,
]),
'has_component' => ($event->incident->component) ? true : false,
'component_name' => $component ? $component->name : null,
'name' => $incident->name,
'timestamp' => $incident->scheduled_at_formatted,
'status' => $incident->human_status,
'html_content' => $incident->formattedMessage,
'text_content' => $incident->message,
'token' => $subscriber->token,
'manage_link' => route('subscribe.manage', ['code' => $subscriber->verify_code]),
'unsubscribe_link' => route('subscribe.unsubscribe', ['code' => $subscriber->verify_code]),
];
$this->mailer->queue([
'html' => 'emails.incidents.maintenance-html',
'text' => 'emails.incidents.maintenance-text',
], $mail, function (Message $message) use ($mail) {
$message->to($mail['email'])->subject($mail['subject']);
});
}
}

View File

@@ -46,9 +46,9 @@ class SendSubscriberVerificationEmailHandler
public function handle(SubscriberHasSubscribedEvent $event)
{
$mail = [
'email' => $event->subscriber->email,
'subject' => 'Confirm your subscription.',
'link' => route('subscribe.verify', ['code' => $event->subscriber->verify_code]),
'email' => $event->subscriber->email,
'subject' => 'Confirm your subscription.',
'link' => route('subscribe.verify', ['code' => $event->subscriber->verify_code]),
];
$this->mailer->queue([

View File

@@ -46,9 +46,9 @@ class SendInviteUserEmailHandler
public function handle(UserWasInvitedEvent $event)
{
$mail = [
'email' => $event->invite->email,
'subject' => 'You have been invited.',
'link' => route('signup.invite', ['code' => $event->invite->code]),
'email' => $event->invite->email,
'subject' => 'You have been invited.',
'link' => route('signup.invite', ['code' => $event->invite->code]),
];
$this->mailer->queue([

View File

@@ -0,0 +1,38 @@
<?php
/*
* This file is part of Cachet.
*
* (c) Alt Three Services Limited
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace CachetHQ\Cachet\Bus\Middleware;
use Closure;
use Illuminate\Support\Facades\DB;
/**
* This is the use database transactions bus middleware class.
*
* @author James Brooks <james@alt-three.com>
*/
class UseDatabaseTransactions
{
/**
* Handle the current command in the pipeline.
*
* @param mixed $command
* @param \Closure $next
*
* @return bool
*/
public function handle($command, Closure $next)
{
return DB::transaction(function () use ($command, $next) {
return $next($command);
});
}
}

View File

@@ -28,7 +28,7 @@ class AppComposer
{
$view->withAboutApp(Markdown::convertToHtml(Config::get('setting.app_about')));
$view->withAppAnalytics(Config::get('setting.app_analytics'));
$view->withAppAnalyticsGoSquared(Config::get('setting.app_analytics_go_squared'));
$view->withAppAnalyticsGoSquared(Config::get('setting.app_analytics_gs'));
$view->withAppAnalyticsPiwikUrl(Config::get('setting.app_analytics_piwik_url'));
$view->withAppAnalyticsPiwikSiteId(Config::get('setting.app_analytics_piwik_site_id'));
$view->withAppBanner(Config::get('setting.app_banner'));
@@ -39,14 +39,12 @@ class AppComposer
$view->withAppLocale(Config::get('setting.app_locale'));
$view->withAppStylesheet(Config::get('setting.stylesheet'));
$view->withAppUrl(Config::get('app.url'));
$view->withAppName($name = Config::get('setting.app_name'));
$view->withAppHeader(Config::get('setting.header'));
$view->withAppFooter(Config::get('setting.footer'));
$view->withAppName(Config::get('setting.app_name'));
$view->withShowSupport($support = Config::get('setting.show_support'));
if ($support) {
$view->withSiteTitle(Config::get('setting.app_name').' | Cachet');
} else {
$view->withSiteTitle(Config::get('setting.app_name'));
}
$view->withAutomaticLocalization(Config::get('setting.automatic_localization'));
$view->withSiteTitle(Config::get('setting.app_name'));
$view->withFontSubset(Config::get('langs.'.Config::get('app.locale').'.subset', 'latin'));
}
}

View File

@@ -13,6 +13,8 @@ namespace CachetHQ\Cachet\Composers;
use CachetHQ\Cachet\Models\Component;
use CachetHQ\Cachet\Models\Incident;
use CachetHQ\Cachet\Models\IncidentTemplate;
use CachetHQ\Cachet\Models\Subscriber;
use Illuminate\Contracts\View\View;
class DashboardComposer
@@ -27,6 +29,8 @@ class DashboardComposer
public function compose(View $view)
{
$view->withIncidentCount(Incident::notScheduled()->count());
$view->withComponentCount(Component::all()->count());
$view->withIncidentTemplateCount(IncidentTemplate::count());
$view->withComponentCount(Component::count());
$view->withSubscriberCount(Subscriber::isVerified()->count());
}
}

View File

@@ -12,29 +12,11 @@
namespace CachetHQ\Cachet\Composers;
use CachetHQ\Cachet\Models\Metric;
use CachetHQ\Cachet\Repositories\Metric\MetricRepository;
use Illuminate\Contracts\View\View;
use Illuminate\Support\Facades\Config;
class MetricsComposer
{
/**
* @var \CachetHQ\Cachet\Repositories\Metric\MetricRepository
*/
protected $metricRepository;
/**
* Construct a new home controller instance.
*
* @param \CachetHQ\Cachet\Repositories\Metric\MetricRepository $metricRepository
*
* @return void
*/
public function __construct(MetricRepository $metricRepository)
{
$this->metricRepository = $metricRepository;
}
/**
* Metrics view composer.
*
@@ -45,22 +27,11 @@ class MetricsComposer
public function compose(View $view)
{
$metrics = null;
$metricData = [];
if ($displayMetrics = Config::get('setting.display_graphs')) {
$metrics = Metric::where('display_chart', 1)->orderBy('id')->get();
$metrics->map(function ($metric) use (&$metricData) {
$metricData[$metric->id] = [
'last_hour' => $this->metricRepository->listPointsLastHour($metric),
'today' => $this->metricRepository->listPointsToday($metric),
'week' => $this->metricRepository->listPointsForWeek($metric),
'month' => $this->metricRepository->listPointsForMonth($metric),
];
});
$metrics = Metric::displayable()->orderBy('order')->orderBy('id')->get();
}
$view->withDisplayMetrics($displayMetrics)
->withMetrics($metrics)
->withMetricData($metricData);
->withMetrics($metrics);
}
}

View File

@@ -11,13 +11,38 @@
namespace CachetHQ\Cachet\Composers;
use CachetHQ\Cachet\Integrations\Core\System;
use CachetHQ\Cachet\Models\Component;
use CachetHQ\Cachet\Models\ComponentGroup;
use CachetHQ\Cachet\Models\Incident;
use Illuminate\Contracts\View\View;
/**
* This is the status page composer.
*
* @author James Brooks <james@alt-three.com>
*/
class StatusPageComposer
{
/**
* The system instance.
*
* @var \CachetHQ\Cachet\Integrations\Contracts\System
*/
protected $system;
/**
* Create a new status page composer instance.
*
* @param \CachetHQ\Cachet\Integrations\Contracts\System $system
*
* @return void
*/
public function __construct(System $system)
{
$this->system = $system;
}
/**
* Index page view composer.
*
@@ -27,40 +52,7 @@ class StatusPageComposer
*/
public function compose(View $view)
{
$totalComponents = Component::enabled()->count();
$majorOutages = Component::enabled()->status(4)->count();
$isMajorOutage = $totalComponents ? ($majorOutages / $totalComponents) >= 0.5 : false;
// Default data
$withData = [
'system_status' => 'info',
'system_message' => trans_choice('cachet.service.bad', $totalComponents),
'favicon' => 'favicon-high-alert',
];
if ($isMajorOutage) {
$withData = [
'system_status' => 'danger',
'system_message' => trans_choice('cachet.service.major', $totalComponents),
'favicon' => 'favicon-high-alert',
];
} elseif (Component::enabled()->notStatus(1)->count() === 0) {
// If all our components are ok, do we have any non-fixed incidents?
$incidents = Incident::notScheduled()->orderBy('created_at', 'desc')->get();
$incidentCount = $incidents->count();
if ($incidentCount === 0 || ($incidentCount >= 1 && (int) $incidents->first()->status === 4)) {
$withData = [
'system_status' => 'success',
'system_message' => trans_choice('cachet.service.good', $totalComponents),
'favicon' => 'favicon',
];
}
} else {
if (Component::enabled()->whereIn('status', [2, 3])->count() > 0) {
$withData['favicon'] = 'favicon-medium-alert';
}
}
$status = $this->system->getStatus();
// Scheduled maintenance code.
$scheduledMaintenance = Incident::scheduled()->orderBy('scheduled_at')->get();
@@ -70,7 +62,7 @@ class StatusPageComposer
$componentGroups = ComponentGroup::whereIn('id', $usedComponentGroups)->orderBy('order')->get();
$ungroupedComponents = Component::enabled()->where('group_id', 0)->orderBy('order')->orderBy('created_at')->get();
$view->with($withData)
$view->with($status)
->withComponentGroups($componentGroups)
->withUngroupedComponents($ungroupedComponents)
->withScheduledMaintenance($scheduledMaintenance);

View File

@@ -14,6 +14,7 @@ namespace CachetHQ\Cachet\Composers;
use DateTime;
use DateTimeZone;
use Illuminate\Contracts\View\View;
use Illuminate\Support\Arr;
use Illuminate\Support\Facades\Config;
class TimezoneLocaleComposer
@@ -32,7 +33,7 @@ class TimezoneLocaleComposer
$langs = array_map(function ($lang) use ($enabledLangs) {
$locale = basename($lang);
return [$locale => $enabledLangs[$locale]];
return [$locale => Arr::get($enabledLangs, $locale)];
}, glob(base_path('resources/lang').'/*'));
$langs = call_user_func_array('array_merge', $langs);

View File

@@ -14,11 +14,12 @@ namespace CachetHQ\Cachet\Console\Commands;
use CachetHQ\Cachet\Models\Component;
use CachetHQ\Cachet\Models\ComponentGroup;
use CachetHQ\Cachet\Models\Incident;
use CachetHQ\Cachet\Models\IncidentTemplate;
use CachetHQ\Cachet\Models\Metric;
use CachetHQ\Cachet\Models\MetricPoint;
use CachetHQ\Cachet\Models\Setting;
use CachetHQ\Cachet\Models\Subscriber;
use CachetHQ\Cachet\Models\User;
use CachetHQ\Cachet\Settings\Repository;
use DateInterval;
use DateTime;
use Illuminate\Console\Command;
@@ -48,6 +49,27 @@ class DemoSeederCommand extends Command
*/
protected $description = 'Seeds Cachet with demo data.';
/**
* The settings repository.
*
* @var \CachetHQ\Cache\Settings\Repository
*/
protected $settings;
/**
* Create a new demo seeder command instance.
*
* @param \CachetHQ\Cache\Settings\Repository $settings
*
* @return void
*/
public function __construct(Repository $settings)
{
parent::__construct();
$this->settings = $settings;
}
/**
* Execute the console command.
*
@@ -62,6 +84,7 @@ class DemoSeederCommand extends Command
$this->seedComponentGroups();
$this->seedComponents();
$this->seedIncidents();
$this->seedIncidentTemplates();
$this->seedMetricPoints();
$this->seedMetrics();
$this->seedSettings();
@@ -82,11 +105,11 @@ class DemoSeederCommand extends Command
[
'name' => 'Websites',
'order' => 1,
'collapsed' => false,
'collapsed' => 0,
], [
'name' => 'Alt Three',
'order' => 2,
'collapsed' => true,
'collapsed' => 1,
],
];
@@ -157,7 +180,25 @@ class DemoSeederCommand extends Command
*/
protected function seedIncidents()
{
$incidentMessage = <<<'EINCIDENT'
# Of course it does!
What kind of web application doesn't these days?
## Headers are fun aren't they
It's _exactly_ why we need Markdown. For **emphasis** and such.
EINCIDENT;
$defaultIncidents = [
[
'name' => 'Cachet supports Markdown!',
'message' => $incidentMessage,
'status' => 4,
'component_id' => 0,
'scheduled_at' => null,
'visible' => 1,
],
[
'name' => 'Awesome',
'message' => ':+1: We totally nailed the fix.',
@@ -207,6 +248,16 @@ class DemoSeederCommand extends Command
}
}
/**
* Seed the incident templates table.
*
* @return void
*/
protected function seedIncidentTemplates()
{
IncidentTemplate::truncate();
}
/**
* Seed the metric points table.
*
@@ -263,47 +314,45 @@ class DemoSeederCommand extends Command
{
$defaultSettings = [
[
'name' => 'app_name',
'key' => 'app_name',
'value' => 'Cachet Demo',
],
[
'name' => 'app_domain',
], [
'key' => 'app_domain',
'value' => 'https://demo.cachethq.io',
],
[
'name' => 'show_support',
], [
'key' => 'show_support',
'value' => '1',
],
[
'name' => 'app_locale',
], [
'key' => 'app_locale',
'value' => 'en',
],
[
'name' => 'app_timezone',
], [
'key' => 'app_timezone',
'value' => 'Europe/London',
],
[
'name' => 'app_incident_days',
], [
'key' => 'app_incident_days',
'value' => '7',
],
[
'name' => 'app_analytics',
], [
'key' => 'app_analytics',
'value' => 'UA-58442674-3',
],
[
'name' => 'app_analytics_gs',
], [
'key' => 'app_analytics_gs',
'value' => 'GSN-712462-P',
],
[
'name' => 'display_graphs',
], [
'key' => 'display_graphs',
'value' => '1',
], [
'key' => 'app_about',
'value' => 'This is the demo instance of [Cachet](https://cachethq.io?ref=demo). The open source status page system, for everyone. An [Alt Three](https://alt-three.com) product.',
], [
'key' => 'enable_subscribers',
'value' => '0',
],
];
Setting::truncate();
$this->settings->clear();
foreach ($defaultSettings as $setting) {
Setting::create($setting);
$this->settings->set($setting['key'], $setting['value']);
}
}

View File

@@ -0,0 +1,88 @@
<?php
/*
* This file is part of Cachet.
*
* (c) Alt Three Services Limited
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace CachetHQ\Cachet\Foundation\Exceptions\Displayers;
use Exception;
use GrahamCampbell\Exceptions\Displayers\DisplayerInterface;
use Illuminate\Http\Request;
use Symfony\Component\HttpKernel\Exception\TooManyRequestsHttpException;
class ThrottleDisplayer implements DisplayerInterface
{
/**
* The request instance.
*
* @var \Illuminate\Http\Request
*/
protected $request;
/**
* Create a new redirect displayer instance.
*
* @param \Illuminate\Http\Request $request
*
* @return void
*/
public function __construct(Request $request)
{
$this->request = $request;
}
/**
* Get the error response associated with the given exception.
*
* @param \Exception $exception
* @param string $id
* @param int $code
* @param string[] $headers
*
* @return \Symfony\Component\HttpFoundation\Response
*/
public function display(Exception $exception, $id, $code, array $headers)
{
return redirect()->route('auth.login')->withError(trans('forms.login.rate-limit'));
}
/**
* Get the supported content type.
*
* @return string
*/
public function contentType()
{
return 'text/html';
}
/**
* Can we display the exception?
*
* @param \Exception $original
* @param \Exception $transformed
* @param int $code
*
* @return bool
*/
public function canDisplay(Exception $original, Exception $transformed, $code)
{
return $transformed instanceof TooManyRequestsHttpException && $this->request->is('auth*');
}
/**
* Do we provide verbose information about the exception?
*
* @return bool
*/
public function isVerbose()
{
return false;
}
}

View File

@@ -12,10 +12,21 @@
namespace CachetHQ\Cachet\Foundation\Providers;
use AltThree\Bus\Dispatcher;
use CachetHQ\Cachet\Bus\Middleware\UseDatabaseTransactions;
use CachetHQ\Cachet\Dates\DateFactory;
use CachetHQ\Cachet\Integrations\Credits;
use CachetHQ\Cachet\Integrations\Feed;
use CachetHQ\Cachet\Integrations\Releases;
use Illuminate\Support\ServiceProvider;
use Illuminate\Support\Str;
/**
* This is the app service provider.
*
* @author James Brooks <james@alt-three.com>
* @author Joe Cohen <joe@alt-three.com>
* @author Graham Campbell <graham@alt-three.com>
*/
class AppServiceProvider extends ServiceProvider
{
/**
@@ -29,6 +40,8 @@ class AppServiceProvider extends ServiceProvider
return Dispatcher::simpleMapping($command, 'CachetHQ\Cachet\Bus', 'CachetHQ\Cachet\Bus\Handlers');
});
$dispatcher->pipeThrough([UseDatabaseTransactions::class]);
Str::macro('canonicalize', function ($url) {
return preg_replace('/([^\/])$/', '$1/', $url);
});
@@ -42,6 +55,9 @@ class AppServiceProvider extends ServiceProvider
public function register()
{
$this->registerDateFactory();
$this->registerCredits();
$this->registerFeed();
$this->registerReleases();
}
/**
@@ -52,10 +68,53 @@ class AppServiceProvider extends ServiceProvider
protected function registerDateFactory()
{
$this->app->singleton(DateFactory::class, function ($app) {
$appTimezone = $app->config->get('app.timezone');
$cacheTimezone = $app->config->get('cachet.timezone');
$appTimezone = $app['config']->get('app.timezone');
$cacheTimezone = $app['config']->get('cachet.timezone');
return new DateFactory($appTimezone, $cacheTimezone);
});
}
/**
* Register the credits class.
*
* @return void
*/
protected function registerCredits()
{
$this->app->singleton(Credits::class, function ($app) {
$cache = $app['cache.store'];
return new Credits($cache);
});
}
/**
* Register the feed class.
*
* @return void
*/
protected function registerFeed()
{
$this->app->singleton(Feed::class, function ($app) {
$cache = $app['cache.store'];
return new Feed($cache);
});
}
/**
* Register the releases class.
*
* @return void
*/
protected function registerReleases()
{
$this->app->singleton(Releases::class, function ($app) {
$cache = $app['cache.store'];
$token = $app['config']->get('services.github.token');
return new Releases($cache, $token);
});
}
}

View File

@@ -33,8 +33,8 @@ class ComposerServiceProvider extends ServiceProvider
$factory->composer('*', AppComposer::class);
$factory->composer('*', CurrentUserComposer::class);
$factory->composer(['index'], MetricsComposer::class);
$factory->composer(['index', 'incident', 'subscribe', 'signup'], StatusPageComposer::class);
$factory->composer(['index', 'incident', 'subscribe', 'signup', 'dashboard.settings.theme'], ThemeComposer::class);
$factory->composer(['index', 'single-incident', 'subscribe', 'signup'], StatusPageComposer::class);
$factory->composer(['index', 'single-incident', 'subscribe.*', 'signup', 'dashboard.settings.theme', 'emails.*'], ThemeComposer::class);
$factory->composer('dashboard.*', DashboardComposer::class);
$factory->composer(['setup', 'dashboard.settings.localization'], TimezoneLocaleComposer::class);
}

View File

@@ -11,11 +11,20 @@
namespace CachetHQ\Cachet\Foundation\Providers;
use CachetHQ\Cachet\Config\Repository;
use CachetHQ\Cachet\Models\Setting as SettingModel;
use CachetHQ\Cachet\Settings\Cache;
use CachetHQ\Cachet\Settings\Repository;
use Exception;
use Illuminate\Support\ServiceProvider;
use Jenssegers\Date\Date;
/**
* This is the config service provider class.
*
* @author James Brooks <james@alt-three.com>
* @author Graham Campbell <graham@alt-three.com>
* @author Joe Cohen <joe@alt-three.com>
*/
class ConfigServiceProvider extends ServiceProvider
{
/**
@@ -25,8 +34,26 @@ class ConfigServiceProvider extends ServiceProvider
*/
public function boot()
{
$env = $this->app->environment();
$repo = $this->app->make(Repository::class);
$cache = $this->app->make(Cache::class);
$loaded = $cache->load($env);
$this->app->terminating(function () use ($repo, $cache) {
if ($repo->stale()) {
$cache->clear();
}
});
try {
$this->app->config->set('setting', $this->app->setting->all());
if ($loaded === false) {
$loaded = $repo->all();
$cache->store($env, $loaded);
}
$settings = array_merge($this->app->config->get('setting'), $loaded);
$this->app->config->set('setting', $settings);
} catch (Exception $e) {
//
}
@@ -35,9 +62,10 @@ class ConfigServiceProvider extends ServiceProvider
$this->app->config->set('app.url', $appDomain);
}
if ($appLocale = $this->app->config->get('setting.app.locale')) {
if ($appLocale = $this->app->config->get('setting.app_locale')) {
$this->app->config->set('app.locale', $appLocale);
$this->app->translator->setLocale($appLocale);
Date::setLocale($appLocale);
}
if ($appTimezone = $this->app->config->get('setting.app_timezone')) {
@@ -65,10 +93,12 @@ class ConfigServiceProvider extends ServiceProvider
*/
public function register()
{
$this->app->singleton('setting', function () {
return new Repository(new SettingModel());
$this->app->singleton(Cache::class, function ($app) {
return new Cache($app->files, $app->bootstrapPath().'/cachet');
});
$this->app->alias('setting', Repository::class);
$this->app->singleton(Repository::class, function () {
return new Repository(new SettingModel());
});
}
}

View File

@@ -11,11 +11,28 @@
namespace CachetHQ\Cachet\Foundation\Providers;
use CachetHQ\Cachet\GitHub\Release;
use CachetHQ\Cachet\Subscribers\CommandSubscriber;
use Illuminate\Support\ServiceProvider;
class GitHubServiceProvider extends ServiceProvider
/**
* This is the console service provider.
*
* @author James Brooks <james@alt-three.com>
*/
class ConsoleServiceProvider extends ServiceProvider
{
/**
* Boot the service provider.
*
* @return void
*/
public function boot()
{
$subscriber = $this->app->make(CommandSubscriber::class);
$this->app->events->subscribe($subscriber);
}
/**
* Register the service provider.
*
@@ -23,23 +40,6 @@ class GitHubServiceProvider extends ServiceProvider
*/
public function register()
{
$this->registerRelease();
}
/**
* Register the releases class.
*
* @return void
*/
protected function registerRelease()
{
$this->app->singleton('cachet.release', function ($app) {
$cache = $app['cache.store'];
$config = $app['config'];
return new Release($cache, $config);
});
$this->app->alias('cachet.release', Release::class);
//
}
}

View File

@@ -34,14 +34,20 @@ class EventServiceProvider extends ServiceProvider
//
],
'CachetHQ\Cachet\Bus\Events\Component\ComponentWasRemovedEvent' => [
//
'CachetHQ\Cachet\Bus\Handlers\Events\Component\CleanupComponentSubscriptionsHandler',
],
'CachetHQ\Cachet\Bus\Events\Component\ComponentWasUpdatedEvent' => [
'CachetHQ\Cachet\Bus\Handlers\Events\Component\SendComponentUpdateEmailNotificationHandler',
],
'CachetHQ\Cachet\Bus\Events\Incident\IncidentWasRemovedEvent' => [
//
],
'CachetHQ\Cachet\Bus\Events\Incident\IncidentWasReportedEvent' => [
'CachetHQ\Cachet\Bus\Handlers\Events\Incident\SendIncidentEmailNotificationHandler',
],
'CachetHQ\Cachet\Bus\Events\Incident\IncidentWasUpdatedEvent' => [
//
],
'CachetHQ\Cachet\Bus\Events\Incident\MaintenanceWasScheduledEvent' => [
'CachetHQ\Cachet\Bus\Handlers\Events\Incident\SendMaintenanceEmailNotificationHandler',
],

View File

@@ -0,0 +1,47 @@
<?php
/*
* This file is part of Cachet.
*
* (c) Alt Three Services Limited
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace CachetHQ\Cachet\Foundation\Providers;
use CachetHQ\Cachet\Integrations\Contracts\System as SystemContract;
use CachetHQ\Cachet\Integrations\Core\System;
use Illuminate\Contracts\Container\Container;
use Illuminate\Support\ServiceProvider;
/**
* This is the integration service provider.
*
* @author James Brooks <james@alt-three.com>
*/
class IntegrationServiceProvider extends ServiceProvider
{
/**
* Register the service provider.
*
* @return void
*/
public function register()
{
$this->registerSystem();
}
/**
* Register the system class.
*
* @return void
*/
protected function registerSystem()
{
$this->app->singleton(SystemContract::class, function (Container $app) {
return new System();
});
}
}

View File

@@ -16,8 +16,15 @@ use CachetHQ\Cachet\Repositories\Metric\MetricRepository;
use CachetHQ\Cachet\Repositories\Metric\MySqlRepository as MetricMySqlRepository;
use CachetHQ\Cachet\Repositories\Metric\PgSqlRepository as MetricPgSqlRepository;
use CachetHQ\Cachet\Repositories\Metric\SqliteRepository as MetricSqliteRepository;
use Illuminate\Contracts\Config\Repository as ConfigRepository;
use Illuminate\Contracts\Container\Container;
use Illuminate\Support\ServiceProvider;
/**
* This is the repository service provider.
*
* @author James Brooks <james@alt-three.com>
*/
class RepositoryServiceProvider extends ServiceProvider
{
/**
@@ -37,22 +44,21 @@ class RepositoryServiceProvider extends ServiceProvider
*/
protected function registerMetricRepository()
{
$this->app->singleton('cachet.metricrepository', function ($app) {
$dbDriver = $app['config']->get('database.default');
$this->app->singleton(MetricRepository::class, function (Container $app) {
$config = $app->make(ConfigRepository::class);
$driver = $config->get('database.default');
if ($dbDriver == 'mysql') {
$repository = new MetricMySqlRepository();
} elseif ($dbDriver == 'pgsql') {
$repository = new MetricPgSqlRepository();
} elseif ($dbDriver == 'sqlite') {
$repository = new MetricSqliteRepository();
if ($driver == 'mysql') {
$repository = new MetricMySqlRepository($config);
} elseif ($driver == 'pgsql') {
$repository = new MetricPgSqlRepository($config);
} elseif ($driver == 'sqlite') {
$repository = new MetricSqliteRepository($config);
}
$dates = $app->make(DateFactory::class);
return new MetricRepository($repository, $dates);
});
$this->app->alias('cachet.metricrepository', MetricRepository::class);
}
}

View File

@@ -17,7 +17,7 @@ use Illuminate\Routing\Router;
class RouteServiceProvider extends ServiceProvider
{
/**
* This namespace is applied to the controller routes in your routes file.
* This namespace is applied to your controller routes.
*
* In addition, it is set as the URL generator's root namespace.
*

View File

@@ -1,70 +0,0 @@
<?php
/*
* This file is part of Cachet.
*
* (c) Alt Three Services Limited
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace CachetHQ\Cachet\GitHub;
use GuzzleHttp\Client;
use Illuminate\Contracts\Cache\Repository as CacheRepository;
use Illuminate\Contracts\Config\Repository as ConfigRepository;
class Release
{
/**
* The cache repository instance.
*
* @var \Illuminate\Contracts\Cache\Repository
*/
protected $cache;
/**
* The config repository instance.
*
* @var \Illuminate\Contracts\Config\Repository
*/
protected $config;
/**
* Creates a new release instance.
*
* @param \Illuminate\Contracts\Cache\Repository $cache
* @param \Illuminate\Contracts\Config\Repository $config
*
* @return void
*/
public function __construct(CacheRepository $cache, ConfigRepository $config)
{
$this->cache = $cache;
$this->config = $config;
}
/**
* Returns the latest GitHub release.
*
* @return string
*/
public function latest()
{
$release = $this->cache->remember('version', 720, function () {
$headers = ['Accept' => 'application/vnd.github.v3+json'];
// We can re-use the Emoji token here, if we have it.
if ($token = $this->config->get('services.github.token')) {
$headers['OAUTH-TOKEN'] = $token;
}
return json_decode((new Client())->get('https://api.github.com/repos/cachethq/cachet/releases/latest', [
'headers' => $headers,
])->getBody(), true);
});
return $release['tag_name'];
}
}

View File

@@ -161,12 +161,6 @@ abstract class AbstractApiController extends Controller
$items = $paginator->getCollection();
if ($sortBy = $request->get('sort')) {
$direction = $request->has('order') && $request->get('order') == 'desc';
$items = $items->sortBy($sortBy, SORT_REGULAR, $direction);
}
return $this->setMetaData($pagination)->setData(AutoPresenter::decorate($items->values()))->respond();
}

View File

@@ -32,12 +32,22 @@ class ComponentController extends AbstractApiController
public function getComponents()
{
if (app(Guard::class)->check()) {
$components = Component::whereRaw('1 = 1');
$components = Component::query();
} else {
$components = Component::enabled();
}
return $this->paginator($components->paginate(Binput::get('per_page', 20)), Request::instance());
$components->search(Binput::except(['sort', 'order', 'per_page']));
if ($sortBy = Binput::get('sort')) {
$direction = Binput::has('order') && Binput::get('order') == 'desc';
$components->sort($sortBy, $direction);
}
$components = $components->paginate(Binput::get('per_page', 20));
return $this->paginator($components, Request::instance());
}
/**
@@ -78,7 +88,7 @@ class ComponentController extends AbstractApiController
$tags = preg_split('/ ?, ?/', Binput::get('tags'));
// For every tag, do we need to create it?
$componentTags = array_map(function ($taggable) use ($component) {
$componentTags = array_map(function ($taggable) {
return Tag::firstOrCreate([
'name' => $taggable,
])->id;
@@ -118,7 +128,7 @@ class ComponentController extends AbstractApiController
$tags = preg_split('/ ?, ?/', Binput::get('tags'));
// For every tag, do we need to create it?
$componentTags = array_map(function ($taggable) use ($component) {
$componentTags = array_map(function ($taggable) {
return Tag::firstOrCreate(['name' => $taggable])->id;
}, $tags);

View File

@@ -20,6 +20,13 @@ use Illuminate\Database\QueryException;
use Illuminate\Support\Facades\Request;
use Symfony\Component\HttpKernel\Exception\BadRequestHttpException;
/**
* This is the component group controller.
*
* @author James Brooks <james@alt-three.com>
* @author Graham Campbell <graham@alt-three.com>
* @author Joe Cohen <joe@alt-three.com>
*/
class ComponentGroupController extends AbstractApiController
{
/**
@@ -29,7 +36,17 @@ class ComponentGroupController extends AbstractApiController
*/
public function getGroups()
{
$groups = ComponentGroup::paginate(Binput::get('per_page', 20));
$groups = ComponentGroup::query();
$groups->search(Binput::except(['sort', 'order', 'per_page']));
if ($sortBy = Binput::get('sort')) {
$direction = Binput::has('order') && Binput::get('order') == 'desc';
$groups->sort($sortBy, $direction);
}
$groups = $groups->paginate(Binput::get('per_page', 20));
return $this->paginator($groups, Request::instance());
}
@@ -57,7 +74,7 @@ class ComponentGroupController extends AbstractApiController
$group = dispatch(new AddComponentGroupCommand(
Binput::get('name'),
Binput::get('order', 0),
Binput::get('collapsed')
Binput::get('collapsed', 0)
));
} catch (QueryException $e) {
throw new BadRequestHttpException();
@@ -79,7 +96,7 @@ class ComponentGroupController extends AbstractApiController
$group = dispatch(new UpdateComponentGroupCommand(
$group,
Binput::get('name'),
Binput::get('order', 0),
Binput::get('order'),
Binput::get('collapsed')
));
} catch (QueryException $e) {

View File

@@ -11,6 +11,14 @@
namespace CachetHQ\Cachet\Http\Controllers\Api;
use CachetHQ\Cachet\Integrations\Contracts\System;
use CachetHQ\Cachet\Integrations\Releases;
/**
* This is the general api controller.
*
* @author James Brooks <james@bluebaytravel.co.uk>
*/
class GeneralController extends AbstractApiController
{
/**
@@ -22,4 +30,34 @@ class GeneralController extends AbstractApiController
{
return $this->item('Pong!');
}
/**
* Endpoint to show the Cachet version.
*
* @return \Illuminate\Http\JsonResponse
*/
public function version()
{
$latest = app(Releases::class)->latest();
return $this->setMetaData([
'on_latest' => version_compare(CACHET_VERSION, $latest['tag_name']) === 1,
'latest' => $latest,
])->item(CACHET_VERSION);
}
/**
* Get the system status message.
*
* @return \Illuminate\Http\JsonResponse
*/
public function status()
{
$system = app()->make(System::class)->getStatus();
return $this->item([
'status' => $system['system_status'],
'message' => $system['system_message'],
]);
}
}

View File

@@ -32,7 +32,17 @@ class IncidentController extends AbstractApiController
{
$incidentVisibility = app(Guard::class)->check() ? 0 : 1;
$incidents = Incident::where('visible', '>=', $incidentVisibility)->paginate(Binput::get('per_page', 20));
$incidents = Incident::where('visible', '>=', $incidentVisibility);
$incidents->search(Binput::except(['sort', 'order', 'per_page']));
if ($sortBy = Binput::get('sort')) {
$direction = Binput::has('order') && Binput::get('order') == 'desc';
$incidents->sort($sortBy, $direction);
}
$incidents = $incidents->paginate(Binput::get('per_page', 20));
return $this->paginator($incidents, Request::instance());
}

View File

@@ -29,7 +29,15 @@ class MetricController extends AbstractApiController
*/
public function getMetrics()
{
$metrics = Metric::paginate(Binput::get('per_page', 20));
$metrics = Metric::query();
if ($sortBy = Binput::get('sort')) {
$direction = Binput::has('order') && Binput::get('order') == 'desc';
$metrics->sort($sortBy, $direction);
}
$metrics = $metrics->paginate(Binput::get('per_page', 20));
return $this->paginator($metrics, Request::instance());
}
@@ -55,7 +63,9 @@ class MetricController extends AbstractApiController
*/
public function getMetricPoints(Metric $metric)
{
return $this->collection($metric->points);
$points = $metric->points()->paginate(Binput::get('per_page', 20));
return $this->paginator($points, Request::instance());
}
/**
@@ -72,9 +82,11 @@ class MetricController extends AbstractApiController
Binput::get('description'),
Binput::get('default_value'),
Binput::get('calc_type', 0),
Binput::get('display_chart'),
Binput::get('display_chart', true),
Binput::get('places', 2),
Binput::get('view', 1)
Binput::get('default_view', Binput::get('view', 1)),
Binput::get('threshold', 5),
Binput::get('order', 0)
));
} catch (QueryException $e) {
throw new BadRequestHttpException();
@@ -99,10 +111,12 @@ class MetricController extends AbstractApiController
Binput::get('suffix'),
Binput::get('description'),
Binput::get('default_value'),
Binput::get('calc_type', 0),
Binput::get('calc_type'),
Binput::get('display_chart'),
Binput::get('places', 2),
Binput::get('view', 1)
Binput::get('places'),
Binput::get('default_view', Binput::get('view')),
Binput::get('threshold'),
Binput::get('order')
));
} catch (QueryException $e) {
throw new BadRequestHttpException();

View File

@@ -48,8 +48,8 @@ class MetricPointController extends AbstractApiController
$metricPoint = dispatch(new AddMetricPointCommand(
$metric,
Binput::get('value'),
Binput::get('timestamp'))
);
Binput::get('timestamp')
));
} catch (QueryException $e) {
throw new BadRequestHttpException();
}

View File

@@ -21,6 +21,12 @@ use Illuminate\Database\QueryException;
use Illuminate\Support\Facades\Request;
use Symfony\Component\HttpKernel\Exception\BadRequestHttpException;
/**
* This is the subscriber controller class.
*
* @author James Brooks <james@alt-three.com>
* @author Graham Campbell <graham@alt-three.com>
*/
class SubscriberController extends AbstractApiController
{
/**
@@ -43,7 +49,11 @@ class SubscriberController extends AbstractApiController
public function postSubscribers()
{
try {
$subscriber = dispatch(new SubscribeSubscriberCommand(Binput::get('email'), Binput::get('verify', false), null));
$subscriber = dispatch(new SubscribeSubscriberCommand(
Binput::get('email'),
Binput::get('verify', false),
Binput::get('components', null)
));
} catch (QueryException $e) {
throw new BadRequestHttpException();
}

View File

@@ -41,11 +41,11 @@ class AuthController extends Controller
*/
public function postLogin()
{
$loginData = Binput::only(['login', 'password']);
$loginData = Binput::only(['username', 'password']);
// Login with username or email.
$loginKey = Str::contains($loginData['login'], '@') ? 'email' : 'username';
$loginData[$loginKey] = array_pull($loginData, 'login');
$loginKey = Str::contains($loginData['username'], '@') ? 'email' : 'username';
$loginData[$loginKey] = array_pull($loginData, 'username');
// Validate login credentials.
if (Auth::validate($loginData)) {

View File

@@ -11,34 +11,46 @@
namespace CachetHQ\Cachet\Http\Controllers\Dashboard;
use CachetHQ\Cachet\GitHub\Release;
use CachetHQ\Cachet\Bus\Commands\Component\UpdateComponentCommand;
use CachetHQ\Cachet\Bus\Commands\ComponentGroup\UpdateComponentGroupCommand;
use CachetHQ\Cachet\Http\Controllers\Api\AbstractApiController;
use CachetHQ\Cachet\Models\Component;
use CachetHQ\Cachet\Models\ComponentGroup;
use CachetHQ\Cachet\Models\IncidentTemplate;
use Exception;
use GrahamCampbell\Binput\Facades\Binput;
use Illuminate\Database\Eloquent\ModelNotFoundException;
use Illuminate\Routing\Controller;
use Illuminate\Support\Facades\Response;
use Illuminate\Database\QueryException;
use Symfony\Component\HttpKernel\Exception\BadRequestHttpException;
class ApiController extends Controller
class ApiController extends AbstractApiController
{
/**
* Updates a component with the entered info.
*
* @param \CachetHQ\Cachet\Models\Component $component
*
* @throws \Exception
* @throws \Symfony\Component\HttpKernel\Exception\BadRequestHttpException
*
* @return \CachetHQ\Cachet\Models\Component
*/
public function postUpdateComponent(Component $component)
{
if (!$component->update(Binput::except(['_token']))) {
throw new Exception(trans('dashboard.components.edit.failure'));
try {
dispatch(new UpdateComponentCommand(
$component,
$component->name,
$component->description,
Binput::get('status'),
$component->link,
$component->order,
$component->group_id,
$component->enabled
));
} catch (QueryException $e) {
throw new BadRequestHttpException();
}
return $component;
return $this->item($component);
}
/**
@@ -51,11 +63,25 @@ class ApiController extends Controller
$componentData = Binput::get('ids');
foreach ($componentData as $order => $componentId) {
// Ordering should be 1-based, data comes in 0-based
Component::find($componentId)->update(['order' => $order + 1]);
try {
$component = Component::find($componentId);
dispatch(new UpdateComponentCommand(
$component,
$component->name,
$component->description,
$component->status,
$component->link,
$order + 1,
$component->group_id,
$component->enabled
));
} catch (QueryException $e) {
throw new BadRequestHttpException();
}
}
return $componentData;
return $this->collection(Component::query()->orderBy('order')->get());
}
/**
@@ -68,10 +94,17 @@ class ApiController extends Controller
$groupData = Binput::get('ids');
foreach ($groupData as $order => $groupId) {
ComponentGroup::find($groupId)->update(['order' => $order + 1]);
$group = ComponentGroup::find($groupId);
dispatch(new UpdateComponentGroupCommand(
$group,
$group->name,
$order + 1,
$group->collapsed
));
}
return $groupData;
return $this->collection(ComponentGroup::query()->orderBy('order')->get());
}
/**
@@ -91,20 +124,4 @@ class ApiController extends Controller
throw new ModelNotFoundException("Incident template for $templateSlug could not be found.");
}
/**
* Checks if Cachet is up to date.
*
* @return \Illuminate\Http\JsonResponse
*/
public function checkVersion()
{
$latest = app(Release::class)->latest();
return Response::json([
'cachet_version' => CACHET_VERSION,
'latest_version' => $latest,
'is_latest' => version_compare(CACHET_VERSION, $latest) === 1,
]);
}
}

View File

@@ -148,7 +148,7 @@ class ComponentController extends Controller
$tags = preg_split('/ ?, ?/', $tags);
// For every tag, do we need to create it?
$componentTags = array_map(function ($taggable) use ($component) {
$componentTags = array_map(function ($taggable) {
return Tag::firstOrCreate(['name' => $taggable])->id;
}, $tags);
@@ -201,7 +201,7 @@ class ComponentController extends Controller
$tags = preg_split('/ ?, ?/', $tags);
// For every tag, do we need to create it?
$componentTags = array_map(function ($taggable) use ($component) {
$componentTags = array_map(function ($taggable) {
return Tag::firstOrCreate(['name' => $taggable])->id;
}, $tags);
@@ -303,7 +303,7 @@ class ComponentController extends Controller
$group = dispatch(new UpdateComponentGroupCommand(
$group,
Binput::get('name'),
Binput::get('order', 0),
$group->order,
Binput::get('collapsed')
));
} catch (ValidationException $e) {

View File

@@ -11,11 +11,14 @@
namespace CachetHQ\Cachet\Http\Controllers\Dashboard;
use CachetHQ\Cachet\Integrations\Feed;
use CachetHQ\Cachet\Models\Component;
use CachetHQ\Cachet\Models\ComponentGroup;
use CachetHQ\Cachet\Models\Incident;
use CachetHQ\Cachet\Models\Subscriber;
use Illuminate\Routing\Controller;
use Illuminate\Support\Facades\Config;
use Illuminate\Support\Facades\Redirect;
use Illuminate\Support\Facades\View;
use Jenssegers\Date\Date;
@@ -36,16 +39,36 @@ class DashboardController extends Controller
protected $timeZone;
/**
* Creates a new dashboard controller.
* The feed integration.
*
* @var \CachetHQ\Cachet\Integrations\Feed
*/
protected $feed;
/**
* Creates a new dashboard controller instance.
*
* @param \CachetHQ\Cachet\Integrations\Feed $feed
*
* @return void
*/
public function __construct()
public function __construct(Feed $feed)
{
$this->feed = $feed;
$this->startDate = new Date();
$this->dateTimeZone = Config::get('cachet.timezone');
}
/**
* Redirect /admin to /dashboard.
*
* @return \Illuminate\Http\RedirectResponse
*/
public function redirectAdmin()
{
return Redirect::route('dashboard.index');
}
/**
* Shows the dashboard view.
*
@@ -56,12 +79,25 @@ class DashboardController extends Controller
$components = Component::orderBy('order')->get();
$incidents = $this->getIncidents();
$subscribers = $this->getSubscribers();
$usedComponentGroups = Component::enabled()->where('group_id', '>', 0)->groupBy('group_id')->pluck('group_id');
$componentGroups = ComponentGroup::whereIn('id', $usedComponentGroups)->orderBy('order')->get();
$ungroupedComponents = Component::enabled()->where('group_id', 0)->orderBy('order')->orderBy('created_at')->get();
$entries = null;
if ($feed = $this->feed->latest()) {
if (is_object($feed)) {
$entries = array_slice($feed->channel->item, 0, 5);
}
}
return View::make('dashboard.index')
->withPageTitle(trans('dashboard.dashboard'))
->withComponents($components)
->withIncidents($incidents)
->withSubscribers($subscribers);
->withSubscribers($subscribers)
->withEntries($entries)
->withComponentGroups($componentGroups)
->withUngroupedComponents($ungroupedComponents);
}
/**

View File

@@ -31,7 +31,7 @@ class MetricController extends Controller
*/
public function showMetrics()
{
$metrics = Metric::orderBy('created_at', 'desc')->get();
$metrics = Metric::orderBy('order')->orderBy('id')->get();
return View::make('dashboard.metrics.index')
->withPageTitle(trans('dashboard.metrics.metrics').' - '.trans('dashboard.dashboard'))
@@ -79,7 +79,8 @@ class MetricController extends Controller
$metricData['calc_type'],
$metricData['display_chart'],
$metricData['places'],
$metricData['default_view']
$metricData['default_view'],
$metricData['threshold']
));
} catch (ValidationException $e) {
return Redirect::route('dashboard.metrics.add')
@@ -151,7 +152,8 @@ class MetricController extends Controller
Binput::get('calc_type', null, false),
Binput::get('display_chart', null, false),
Binput::get('places', null, false),
Binput::get('default_view', null, false)
Binput::get('default_view', null, false),
Binput::get('threshold', null, false)
));
} catch (ValidationException $e) {
return Redirect::route('dashboard.metrics.edit', ['id' => $metric->id])

View File

@@ -95,10 +95,10 @@ class ScheduleController extends Controller
{
try {
$incident = dispatch(new ReportMaintenanceCommand(
Binput::get('incident.name'),
Binput::get('incident.message'),
Binput::get('incident.notify'),
Binput::get('incident.scheduled_at')
Binput::get('name'),
Binput::get('message'),
Binput::get('notify'),
Binput::get('scheduled_at')
));
} catch (ValidationException $e) {
return Redirect::route('dashboard.schedule.add')
@@ -140,7 +140,7 @@ class ScheduleController extends Controller
$scheduleData = Binput::get('incident');
// Parse the schedule date.
$scheduledAt = app(DateFactory::class)->createNormalized('d/m/Y H:i', $scheduleData['scheduled_at']);
$scheduledAt = app(DateFactory::class)->create('d/m/Y H:i', $scheduleData['scheduled_at']);
if ($scheduledAt->isPast()) {
$messageBag = new MessageBag();

View File

@@ -11,7 +11,9 @@
namespace CachetHQ\Cachet\Http\Controllers\Dashboard;
use CachetHQ\Cachet\Integrations\Credits;
use CachetHQ\Cachet\Models\User;
use CachetHQ\Cachet\Settings\Repository;
use Exception;
use GrahamCampbell\Binput\Facades\Binput;
use Illuminate\Routing\Controller;
@@ -20,6 +22,7 @@ use Illuminate\Support\Facades\Lang;
use Illuminate\Support\Facades\Redirect;
use Illuminate\Support\Facades\Session;
use Illuminate\Support\Facades\View;
use Illuminate\Support\Str;
class SettingsController extends Controller
{
@@ -56,6 +59,12 @@ class SettingsController extends Controller
'icon' => 'ion-paintbucket',
'active' => false,
],
'customization' => [
'title' => trans('dashboard.settings.customization.customization'),
'url' => route('dashboard.settings.customization'),
'icon' => 'ion-wand',
'active' => false,
],
'localization' => [
'title' => trans('dashboard.settings.localization.localization'),
'url' => route('dashboard.settings.localization'),
@@ -74,6 +83,12 @@ class SettingsController extends Controller
'icon' => 'ion-stats-bars',
'active' => false,
],
'credits' => [
'title' => trans('dashboard.settings.credits.credits'),
'url' => route('dashboard.settings.credits'),
'icon' => 'ion-ios-list',
'active' => false,
],
'about' => [
'title' => CACHET_VERSION,
'url' => 'javascript: void(0);',
@@ -137,6 +152,22 @@ class SettingsController extends Controller
->withSubMenu($this->subMenu);
}
/**
* Shows the settings customization view.
*
* @return \Illuminate\View\View
*/
public function showCustomizationView()
{
$this->subMenu['customization']['active'] = true;
Session::flash('redirect_to', $this->subMenu['customization']['url']);
return View::make('dashboard.settings.customization')
->withPageTitle(trans('dashboard.settings.customization.customization').' - '.trans('dashboard.dashboard'))
->withSubMenu($this->subMenu);
}
/**
* Shows the settings theme view.
*
@@ -188,6 +219,30 @@ class SettingsController extends Controller
->withSubMenu($this->subMenu);
}
/**
* Show the credits view.
*
* @return \Illuminate\View\View
*/
public function showCreditsView()
{
$this->subMenu['credits']['active'] = true;
$credits = app(Credits::class)->latest();
$backers = $credits['backers'];
$contributors = $credits['contributors'];
shuffle($backers);
shuffle($contributors);
return View::make('dashboard.settings.credits')
->withPageTitle(trans('dashboard.settings.credits.credits').' - '.trans('dashboard.dashboard'))
->withBackers($backers)
->withContributors($contributors)
->withSubMenu($this->subMenu);
}
/**
* Updates the status page settings.
*
@@ -195,42 +250,53 @@ class SettingsController extends Controller
*/
public function postSettings()
{
$redirectUrl = Session::get('redirect_to', route('dashboard.settings.setup'));
$setting = app('setting');
$setting = app(Repository::class);
if (Binput::get('remove_banner') === '1') {
$setting->set('app_banner', null);
}
if (Binput::hasFile('app_banner')) {
$file = Binput::file('app_banner');
$parameters = Binput::all();
// Image Validation.
// Image size in bytes.
$maxSize = $file->getMaxFilesize();
if ($file->getSize() > $maxSize) {
return Redirect::to($redirectUrl)->withErrors(trans('dashboard.settings.app-setup.too-big', ['size' => $maxSize]));
if (isset($parameters['header'])) {
if ($header = Binput::get('header', null, false, false)) {
$setting->set('header', $header);
} else {
$setting->delete('header');
}
if (!$file->isValid() || $file->getError()) {
return Redirect::to($redirectUrl)->withErrors($file->getErrorMessage());
}
if (!starts_with($file->getMimeType(), 'image/')) {
return Redirect::to($redirectUrl)->withErrors(trans('dashboard.settings.app-setup.images-only'));
}
// Store the banner.
$setting->set('app_banner', base64_encode(file_get_contents($file->getRealPath())));
// Store the banner type.
$setting->set('app_banner_type', $file->getMimeType());
}
if (isset($parameters['footer'])) {
if ($footer = Binput::get('footer', null, false, false)) {
$setting->set('footer', $footer);
} else {
$setting->delete('footer');
}
}
if (isset($parameters['stylesheet'])) {
if ($stylesheet = Binput::get('stylesheet', null, false, false)) {
$setting->set('stylesheet', $stylesheet);
} else {
$setting->delete('stylesheet');
}
}
if (Binput::hasFile('app_banner')) {
$this->handleUpdateBanner($setting);
}
$excludedParams = [
'_token',
'app_banner',
'remove_banner',
'header',
'footer',
'stylesheet',
];
try {
foreach (Binput::except(['app_banner', 'remove_banner', '_token']) as $settingName => $settingValue) {
foreach (Binput::except($excludedParams) as $settingName => $settingValue) {
if ($settingName === 'app_analytics_pi_url') {
$settingValue = rtrim($settingValue, '/');
}
@@ -238,13 +304,47 @@ class SettingsController extends Controller
$setting->set($settingName, $settingValue);
}
} catch (Exception $e) {
return Redirect::to($redirectUrl)->withErrors(trans('dashboard.settings.edit.failure'));
return Redirect::back()->withErrors(trans('dashboard.settings.edit.failure'));
}
if (Binput::has('app_locale')) {
Lang::setLocale(Binput::get('app_locale'));
}
return Redirect::to($redirectUrl)->withSuccess(trans('dashboard.settings.edit.success'));
return Redirect::back()->withSuccess(trans('dashboard.settings.edit.success'));
}
/**
* Handle updating of the banner image.
*
* @param \CachetHQ\Cachet\Settings\Repository $setting
*
* @return void
*/
protected function handleUpdateBanner(Repository $setting)
{
$file = Binput::file('app_banner');
// Image Validation.
// Image size in bytes.
$maxSize = $file->getMaxFilesize();
if ($file->getSize() > $maxSize) {
return Redirect::to($redirectUrl)->withErrors(trans('dashboard.settings.app-setup.too-big', ['size' => $maxSize]));
}
if (!$file->isValid() || $file->getError()) {
return Redirect::to($redirectUrl)->withErrors($file->getErrorMessage());
}
if (!Str::startsWith($file->getMimeType(), 'image/')) {
return Redirect::to($redirectUrl)->withErrors(trans('dashboard.settings.app-setup.images-only'));
}
// Store the banner.
$setting->set('app_banner', base64_encode(file_get_contents($file->getRealPath())));
// Store the banner type.
$setting->set('app_banner_type', $file->getMimeType());
}
}

View File

@@ -53,7 +53,11 @@ class SubscriberController extends Controller
public function createSubscriberAction()
{
try {
dispatch(new SubscribeSubscriberCommand(Binput::get('email')));
$subscribers = preg_split("/\r\n|\n|\r/", Binput::get('email'));
foreach ($subscribers as $subscriber) {
dispatch(new SubscribeSubscriberCommand($subscriber));
}
} catch (ValidationException $e) {
return Redirect::route('dashboard.subscribers.add')
->withInput(Binput::all())

View File

@@ -79,7 +79,7 @@ class FeedController extends Controller
private function feedAction(ComponentGroup &$group, $isRss)
{
if ($group->exists) {
$group->components->map(function ($component) {
$group->components->map(function ($component) use ($isRss) {
$component->incidents()->visible()->orderBy('created_at', 'desc')->get()->map(function ($incident) use ($isRss) {
$this->feedAddItem($incident, $isRss);
});

View File

@@ -12,6 +12,7 @@
namespace CachetHQ\Cachet\Http\Controllers;
use CachetHQ\Cachet\Models\User;
use CachetHQ\Cachet\Settings\Repository;
use Dotenv\Dotenv;
use Dotenv\Exception\InvalidPathException;
use GrahamCampbell\Binput\Facades\Binput;
@@ -41,6 +42,22 @@ class SetupController extends Controller
'redis' => 'Redis',
];
/**
* Array of cache drivers.
*
* @var string[]
*/
protected $mailDrivers = [
'smtp' => 'SMTP',
'mail' => 'Mail',
'sendmail' => 'Sendmail',
'mailgun' => 'Mailgun',
'mandrill' => 'Mandrill',
// 'ses' => 'Amazon SES', this will be available only if aws/aws-sdk-php is installed
'sparkpost' => 'SparkPost',
'log' => 'Log (Testing)',
];
/**
* Array of step1 rules.
*
@@ -72,6 +89,7 @@ class SetupController extends Controller
$this->rulesStep1 = [
'env.cache_driver' => 'required|in:'.implode(',', array_keys($this->cacheDrivers)),
'env.session_driver' => 'required|in:'.implode(',', array_keys($this->cacheDrivers)),
'env.mail_driver' => 'required|in:'.implode(',', array_keys($this->mailDrivers)),
];
$this->rulesStep2 = [
@@ -96,11 +114,6 @@ class SetupController extends Controller
*/
public function getIndex()
{
// If we've copied the .env.example file, then we should try and reset it.
if (strlen(Config::get('app.key')) !== 32) {
$this->keyGenerate();
}
$supportedLanguages = Request::getLanguages();
$userLanguage = Config::get('app.locale');
@@ -116,6 +129,7 @@ class SetupController extends Controller
return View::make('setup')
->withPageTitle(trans('setup.setup'))
->withCacheDrivers($this->cacheDrivers)
->withMailDrivers($this->mailDrivers)
->withUserLanguage($userLanguage)
->withAppUrl(Request::root());
}
@@ -131,6 +145,14 @@ class SetupController extends Controller
$v = Validator::make($postData, $this->rulesStep1);
$v->sometimes('env.mail_host', 'required', function ($input) {
return $input->mail_driver === 'smtp';
});
$v->sometimes(['env.mail_address', 'env.mail_username'], 'required', function ($input) {
return $input->mail_driver !== 'log';
});
if ($v->passes()) {
return Response::json(['status' => 1]);
}
@@ -180,7 +202,7 @@ class SetupController extends Controller
Auth::login($user);
$setting = app('setting');
$setting = app(Repository::class);
$settings = array_pull($postData, 'settings');
@@ -228,33 +250,16 @@ class SetupController extends Controller
try {
(new Dotenv($dir, $file))->load();
$envKey = strtoupper($key);
$envValue = env($envKey) ?: 'null';
file_put_contents($path, str_replace(
env(strtoupper($key)), $value, file_get_contents($path)
$envKey.'='.$envValue,
$envKey.'='.$value,
file_get_contents($path)
));
} catch (InvalidPathException $e) {
//
}
}
/**
* Generate the app.key value.
*
* @return void
*/
protected function keyGenerate()
{
$key = str_random(32);
$dir = app()->environmentPath();
$file = app()->environmentFile();
$path = "{$dir}/{$file}";
(new Dotenv($dir, $file))->load();
file_put_contents($path, str_replace(
Config::get('app.key'), $key, file_get_contents($path)
));
Config::set('app.key', $key);
}
}

View File

@@ -47,7 +47,7 @@ class SignupController extends Controller
return View::make('signup')
->withCode($invite->code)
->withUsername(Binput::old('username'))
->withEmail(Binput::old('emai', $invite->email));
->withEmail(Binput::old('email', $invite->email));
}
/**

View File

@@ -11,18 +11,42 @@
namespace CachetHQ\Cachet\Http\Controllers;
use AltThree\Badger\Facades\Badger;
use CachetHQ\Cachet\Dates\DateFactory;
use CachetHQ\Cachet\Http\Controllers\Api\AbstractApiController;
use CachetHQ\Cachet\Models\Component;
use CachetHQ\Cachet\Models\Incident;
use CachetHQ\Cachet\Models\Metric;
use CachetHQ\Cachet\Repositories\Metric\MetricRepository;
use Exception;
use GrahamCampbell\Binput\Facades\Binput;
use Illuminate\Routing\Controller;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Config;
use Illuminate\Support\Facades\Response;
use Illuminate\Support\Facades\View;
use Jenssegers\Date\Date;
use McCool\LaravelAutoPresenter\Facades\AutoPresenter;
class StatusPageController extends Controller
class StatusPageController extends AbstractApiController
{
/**
* @var \CachetHQ\Cachet\Repositories\Metric\MetricRepository
*/
protected $metricRepository;
/**
* Construct a new status page controller instance.
*
* @param \CachetHQ\Cachet\Repositories\Metric\MetricRepository $metricRepository
*
* @return void
*/
public function __construct(MetricRepository $metricRepository)
{
$this->metricRepository = $metricRepository;
}
/**
* Displays the status page.
*
@@ -97,7 +121,77 @@ class StatusPageController extends Controller
*/
public function showIncident(Incident $incident)
{
return View::make('incident')
return View::make('single-incident')
->withIncident($incident);
}
/**
* Returns metrics in a readily formatted way.
*
* @param \CachetHQ\Cachet\Models\Metric $metric
*
* @return \Illuminate\Http\JsonResponse
*/
public function getMetrics(Metric $metric)
{
$metricData = [];
$type = Binput::get('filter', 'last_hour');
switch ($type) {
case 'last_hour':
$metricData = $this->metricRepository->listPointsLastHour($metric);
break;
case 'today':
$metricData = $this->metricRepository->listPointsToday($metric);
break;
case 'week':
$metricData = $this->metricRepository->listPointsForWeek($metric);
break;
case 'month':
$metricData = $this->metricRepository->listPointsForMonth($metric);
break;
}
return $this->item([
'metric' => $metric->toArray(),
'items' => $metricData,
]);
}
/**
* Generates a Shield (badge) for the component.
*
* @param \CachetHQ\Cachet\Models\Component $component
*
* @return \Illuminate\Http\Response
*/
public function showComponentBadge(Component $component)
{
$component = AutoPresenter::decorate($component);
$color = null;
switch ($component->status_color) {
case 'reds':
$color = Config::get('setting.style_reds', '#ff6f6f');
break;
case 'blues':
$color = Config::get('setting.style_blues', '#3498db');
break;
case 'greens':
$color = Config::get('setting.style_greens', '#7ED321');
break;
case 'yellows':
$color = Config::get('setting.style_yellows', '#F7CA18');
break;
}
$badge = Badger::generate(
$component->name,
$component->human_status,
substr($color, 1),
Binput::get('style', 'flat-square')
);
return Response::make($badge, 200, ['Content-Type' => 'image/svg+xml']);
}
}

View File

@@ -15,8 +15,9 @@ use AltThree\Validator\ValidationException;
use CachetHQ\Cachet\Bus\Commands\Subscriber\SubscribeSubscriberCommand;
use CachetHQ\Cachet\Bus\Commands\Subscriber\UnsubscribeSubscriberCommand;
use CachetHQ\Cachet\Bus\Commands\Subscriber\UnsubscribeSubscriptionCommand;
use CachetHQ\Cachet\Bus\Commands\Subscriber\UpdateSubscriberSubscriptionCommand;
use CachetHQ\Cachet\Bus\Commands\Subscriber\VerifySubscriberCommand;
use CachetHQ\Cachet\Bus\Exceptions\Subscriber\AlreadySubscribedException;
use CachetHQ\Cachet\Models\Component;
use CachetHQ\Cachet\Models\Subscriber;
use CachetHQ\Cachet\Models\Subscription;
use GrahamCampbell\Binput\Facades\Binput;
@@ -42,7 +43,7 @@ class SubscribeController extends Controller
*/
public function showSubscribe()
{
return View::make('subscribe')
return View::make('subscribe.subscribe')
->withAboutApp(Markdown::convertToHtml(Config::get('setting.app_about')));
}
@@ -57,20 +58,22 @@ class SubscribeController extends Controller
$subscriptions = Binput::get('subscriptions');
try {
dispatch(new SubscribeSubscriberCommand($email, false, $subscriptions));
} catch (AlreadySubscribedException $e) {
return Redirect::route('subscribe.subscribe')
->withTitle(sprintf('<strong>%s</strong> %s', trans('dashboard.notifications.whoops'), trans('cachet.subscriber.email.failure')))
->withErrors(trans('cachet.subscriber.email.already-subscribed', ['email' => $email]));
$verified = false;
$subscription = dispatch(new SubscribeSubscriberCommand($email, $verified));
} catch (ValidationException $e) {
return Redirect::route('subscribe.subscribe')
return Redirect::route('status-page')
->withInput(Binput::all())
->withTitle(sprintf('<strong>%s</strong> %s', trans('dashboard.notifications.whoops'), trans('cachet.subscriber.email.failure')))
->withTitle(sprintf('%s %s', trans('dashboard.notifications.whoops'), trans('cachet.subscriber.email.failure')))
->withErrors($e->getMessageBag());
}
return Redirect::route('status-page')
->withSuccess(sprintf('<strong>%s</strong> %s', trans('dashboard.notifications.awesome'), trans('cachet.subscriber.email.subscribed')));
$message = $subscription->is_verified ?
trans('cachet.subscriber.email.already-subscribed', ['email' => $email]) :
trans('cachet.subscriber.email.subscribed');
return Redirect::route('subscribe.manage', $subscription->verify_code)
->withSuccess(sprintf('%s %s', trans('dashboard.notifications.awesome'), $message));
}
/**
@@ -86,16 +89,18 @@ class SubscribeController extends Controller
throw new NotFoundHttpException();
}
$subscriber = Subscriber::where('verify_code', '=', $code)->first();
$subscriber = Subscriber::where('verify_code', $code)->first();
if (!$subscriber || $subscriber->is_verified) {
if (!$subscriber) {
throw new BadRequestHttpException();
}
dispatch(new VerifySubscriberCommand($subscriber));
if (!$subscriber->is_verified) {
dispatch(new VerifySubscriberCommand($subscriber));
}
return Redirect::route('status-page')
->withSuccess(sprintf('<strong>%s</strong> %s', trans('dashboard.notifications.awesome'), trans('cachet.subscriber.email.verified')));
->withSuccess(sprintf('%s %s', trans('dashboard.notifications.awesome'), trans('cachet.subscriber.email.verified')));
}
/**
@@ -125,6 +130,63 @@ class SubscribeController extends Controller
}
return Redirect::route('status-page')
->withSuccess(sprintf('<strong>%s</strong> %s', trans('dashboard.notifications.awesome'), trans('cachet.subscriber.email.unsubscribed')));
->withSuccess(sprintf('%s %s', trans('dashboard.notifications.awesome'), trans('cachet.subscriber.email.unsubscribed')));
}
/**
* Shows the subscription manager page.
*
* @param string|null $code
*
* @return \Illuminate\View\View
*/
public function showManage($code = null)
{
if ($code === null) {
throw new NotFoundHttpException();
}
$subscriber = Subscriber::where('verify_code', '=', $code)->first();
if (!$subscriber) {
throw new BadRequestHttpException();
}
return View::make('subscribe.manage')
->withComponents(Component::all())
->withSubscriber($subscriber)
->withSubscriptions($subscriber->subscriptions->pluck('component_id')->all());
}
/**
* Updates the subscription manager for a subscriber.
*
* @param string|null $code
*
* @return \Illuminate\View\View
*/
public function postManage($code = null)
{
if ($code === null) {
throw new NotFoundHttpException();
}
$subscriber = Subscriber::where('verify_code', '=', $code)->first();
if (!$subscriber) {
throw new BadRequestHttpException();
}
try {
dispatch(new UpdateSubscriberSubscriptionCommand($subscriber, Binput::get('subscriptions')));
} catch (ValidationException $e) {
return Redirect::route('subscribe.manage', $subscriber->verify_code)
->withInput(Binput::all())
->withTitle(sprintf('%s %s', trans('dashboard.notifications.whoops'), trans('cachet.subscriber.email.failure')))
->withErrors($e->getMessageBag());
}
return Redirect::route('subscribe.manage', $subscriber->verify_code)
->withSuccess(sprintf('%s %s', trans('dashboard.notifications.awesome'), trans('cachet.subscriber.email.subscribed')));
}
}

View File

@@ -23,7 +23,6 @@ class Kernel extends HttpKernel
protected $middleware = [
'Fideloper\Proxy\TrustProxies',
'Illuminate\Foundation\Http\Middleware\CheckForMaintenanceMode',
];
/**
@@ -40,6 +39,7 @@ class Kernel extends HttpKernel
'Illuminate\Foundation\Http\Middleware\VerifyCsrfToken',
],
'api' => [
'Barryvdh\Cors\HandleCors',
'CachetHQ\Cachet\Http\Middleware\Acceptable',
'CachetHQ\Cachet\Http\Middleware\Timezone',
],
@@ -59,6 +59,6 @@ class Kernel extends HttpKernel
'ready' => 'CachetHQ\Cachet\Http\Middleware\ReadyForUse',
'setup' => 'CachetHQ\Cachet\Http\Middleware\SetupAlreadyCompleted',
'subscribers' => 'CachetHQ\Cachet\Http\Middleware\SubscribersConfigured',
'throttling' => 'GrahamCampbell\Throttle\Http\Middleware\ThrottleMiddleware',
'throttle' => 'AltThree\Throttle\ThrottlingMiddleware',
];
}

View File

@@ -28,7 +28,7 @@ class Acceptable
*/
public function handle(Request $request, Closure $next, $type = null)
{
if (!$request->accepts($type ?: 'accept:application/json')) {
if (!$request->accepts($type ?: 'application/json')) {
throw new NotAcceptableHttpException();
}

View File

@@ -55,6 +55,10 @@ class Localize
*/
public function handle(Request $request, Closure $next)
{
if (!(bool) $this->config->get('setting.automatic_localization')) {
return $next($request);
}
$supportedLanguages = $request->getLanguages();
$userLanguage = $this->config->get('app.locale');

View File

@@ -25,7 +25,7 @@ class Timezone
protected $config;
/**
* Creates a new release instance.
* Creates a new timezone middleware instance.
*
* @param \Illuminate\Contracts\Config\Repository $config
*

View File

@@ -29,9 +29,11 @@ class ApiRoutes
*/
public function map(Registrar $router)
{
$router->group(['namespace' => 'Api', 'prefix' => 'api/v1', 'middleware' => ['api']], function ($router) {
$router->group(['middleware' => ['auth.api']], function ($router) {
$router->group(['namespace' => 'Api', 'prefix' => 'api/v1', 'middleware' => ['api']], function (Registrar $router) {
$router->group(['middleware' => ['auth.api']], function (Registrar $router) {
$router->get('ping', 'GeneralController@ping');
$router->get('version', 'GeneralController@version');
$router->get('status', 'GeneralController@status');
$router->get('components', 'ComponentController@getComponents');
$router->get('components/groups', 'ComponentGroupController@getGroups');
@@ -46,7 +48,7 @@ class ApiRoutes
$router->get('metrics/{metric}/points', 'MetricController@getMetricPoints');
});
$router->group(['middleware' => ['auth.api:true']], function ($router) {
$router->group(['middleware' => ['auth.api:true']], function (Registrar $router) {
$router->get('subscribers', 'SubscriberController@getSubscribers');
$router->post('components', 'ComponentController@postComponents');

View File

@@ -29,7 +29,7 @@ class AuthRoutes
*/
public function map(Registrar $router)
{
$router->group(['as' => 'auth.', 'middleware' => ['web', 'ready'], 'prefix' => 'auth'], function ($router) {
$router->group(['as' => 'auth.', 'middleware' => ['web', 'ready'], 'prefix' => 'auth'], function (Registrar $router) {
$router->get('login', [
'middleware' => 'guest',
'as' => 'login',
@@ -37,7 +37,7 @@ class AuthRoutes
]);
$router->post('login', [
'middleware' => ['guest', 'throttling:10,10'],
'middleware' => ['guest', 'throttle:10,10'],
'uses' => 'AuthController@postLogin',
]);
@@ -47,7 +47,7 @@ class AuthRoutes
]);
$router->post('2fa', [
'middleware' => ['throttling:10,10'],
'middleware' => ['throttle:10,10'],
'uses' => 'AuthController@postTwoFactor',
]);

View File

@@ -29,202 +29,213 @@ class DashboardRoutes
*/
public function map(Registrar $router)
{
$router->group(['middleware' => ['web', 'auth'], 'prefix' => 'dashboard', 'namespace' => 'Dashboard', 'as' => 'dashboard.'], function ($router) {
$router->get('/', [
'as' => 'index',
'uses' => 'DashboardController@showDashboard',
]);
$router->group(['middleware' => ['web', 'auth'], 'namespace' => 'Dashboard'], function (Registrar $router) {
$router->get('admin', 'DashboardController@redirectAdmin');
$router->group(['as' => 'components.', 'prefix' => 'components'], function ($router) {
$router->group(['prefix' => 'dashboard', 'as' => 'dashboard.'], function (Registrar $router) {
$router->get('/', [
'as' => 'index',
'uses' => 'ComponentController@showComponents',
]);
$router->get('add', [
'as' => 'add',
'uses' => 'ComponentController@showAddComponent',
]);
$router->post('add', 'ComponentController@createComponentAction');
$router->get('groups', [
'as' => 'groups',
'uses' => 'ComponentController@showComponentGroups',
]);
$router->get('groups/add', [
'as' => 'groups.add',
'uses' => 'ComponentController@showAddComponentGroup',
]);
$router->get('groups/edit/{component_group}', [
'as' => 'groups.edit',
'uses' => 'ComponentController@showEditComponentGroup',
]);
$router->post('groups/edit/{component_group}', 'ComponentController@updateComponentGroupAction');
$router->delete('groups/{component_group}/delete', 'ComponentController@deleteComponentGroupAction');
$router->post('groups/add', 'ComponentController@postAddComponentGroup');
$router->get('{component}/edit', [
'as' => 'edit',
'uses' => 'ComponentController@showEditComponent',
]);
$router->delete('{component}/delete', 'ComponentController@deleteComponentAction');
$router->post('{component}/edit', 'ComponentController@updateComponentAction');
});
$router->group(['as' => 'incidents.', 'prefix' => 'incidents'], function ($router) {
$router->get('/', [
'as' => 'index',
'uses' => 'IncidentController@showIncidents',
]);
$router->get('add', [
'as' => 'add',
'uses' => 'IncidentController@showAddIncident',
]);
$router->post('add', 'IncidentController@createIncidentAction');
$router->delete('{incident}/delete', [
'as' => 'delete',
'uses' => 'IncidentController@deleteIncidentAction',
]);
$router->get('{incident}/edit', [
'as' => 'edit',
'uses' => 'IncidentController@showEditIncidentAction',
]);
$router->post('{incident}/edit', 'IncidentController@editIncidentAction');
});
$router->group(['as' => 'schedule.', 'prefix' => 'schedule'], function ($router) {
$router->get('/', [
'as' => 'index',
'uses' => 'ScheduleController@showIndex',
]);
$router->get('add', [
'as' => 'add',
'uses' => 'ScheduleController@showAddSchedule',
]);
$router->post('add', 'ScheduleController@addScheduleAction');
$router->get('{incident}/edit', [
'as' => 'edit',
'uses' => 'ScheduleController@showEditSchedule',
]);
$router->post('{incident}/edit', 'ScheduleController@editScheduleAction');
$router->delete('{incident}/delete', [
'as' => 'delete',
'uses' => 'ScheduleController@deleteScheduleAction',
]);
});
$router->group(['as' => 'templates.', 'prefix' => 'templates'], function ($router) {
$router->get('/', [
'as' => 'index',
'uses' => 'IncidentController@showTemplates',
]);
$router->get('add', [
'as' => 'add',
'uses' => 'IncidentController@showAddIncidentTemplate',
]);
$router->post('add', 'IncidentController@createIncidentTemplateAction');
$router->get('{incident_template}/edit', [
'as' => 'edit',
'uses' => 'IncidentController@showEditTemplateAction',
]);
$router->post('{incident_template}/edit', 'IncidentController@editTemplateAction');
$router->delete('{incident_template}/delete', 'IncidentController@deleteTemplateAction');
});
$router->group(['as' => 'subscribers.', 'prefix' => 'subscribers'], function ($router) {
$router->get('/', [
'as' => 'index',
'uses' => 'SubscriberController@showSubscribers',
]);
$router->get('add', [
'as' => 'add',
'uses' => 'SubscriberController@showAddSubscriber',
]);
$router->post('add', 'SubscriberController@createSubscriberAction');
$router->delete('{subscriber}/delete', 'SubscriberController@deleteSubscriberAction');
});
$router->group(['as' => 'metrics.', 'prefix' => 'metrics'], function ($router) {
$router->get('/', [
'as' => 'index',
'uses' => 'MetricController@showMetrics',
]);
$router->get('add', [
'as' => 'add',
'uses' => 'MetricController@showAddMetric',
]);
$router->post('add', 'MetricController@createMetricAction');
$router->delete('{metric}/delete', 'MetricController@deleteMetricAction');
$router->get('{metric}/edit', [
'as' => 'edit',
'uses' => 'MetricController@showEditMetricAction',
]);
$router->post('{metric}/edit', 'MetricController@editMetricAction');
});
$router->group(['as' => 'team.', 'prefix' => 'team'], function ($router) {
$router->get('/', [
'as' => 'index',
'uses' => 'TeamController@showTeamView',
'uses' => 'DashboardController@showDashboard',
]);
$router->group(['middleware' => 'admin'], function ($router) {
$router->group(['as' => 'components.', 'prefix' => 'components'], function (Registrar $router) {
$router->get('/', [
'as' => 'index',
'uses' => 'ComponentController@showComponents',
]);
$router->get('add', [
'as' => 'add',
'uses' => 'TeamController@showAddTeamMemberView',
'uses' => 'ComponentController@showAddComponent',
]);
$router->get('invite', [
'as' => 'invite',
'uses' => 'TeamController@showInviteTeamMemberView',
$router->post('add', 'ComponentController@createComponentAction');
$router->get('groups', [
'as' => 'groups',
'uses' => 'ComponentController@showComponentGroups',
]);
$router->get('{user}', 'TeamController@showTeamMemberView');
$router->post('add', 'TeamController@postAddUser');
$router->post('invite', 'TeamController@postInviteUser');
$router->post('{user}', 'TeamController@postUpdateUser');
$router->delete('{user}/delete', 'TeamController@deleteUser');
$router->get('groups/add', [
'as' => 'groups.add',
'uses' => 'ComponentController@showAddComponentGroup',
]);
$router->get('groups/edit/{component_group}', [
'as' => 'groups.edit',
'uses' => 'ComponentController@showEditComponentGroup',
]);
$router->post('groups/edit/{component_group}', 'ComponentController@updateComponentGroupAction');
$router->delete('groups/{component_group}/delete', 'ComponentController@deleteComponentGroupAction');
$router->post('groups/add', 'ComponentController@postAddComponentGroup');
$router->get('{component}/edit', [
'as' => 'edit',
'uses' => 'ComponentController@showEditComponent',
]);
$router->delete('{component}/delete', 'ComponentController@deleteComponentAction');
$router->post('{component}/edit', 'ComponentController@updateComponentAction');
});
});
$router->group(['as' => 'settings.', 'prefix' => 'settings'], function ($router) {
$router->get('setup', [
'as' => 'setup',
'uses' => 'SettingsController@showSetupView',
]);
$router->get('analytics', [
'as' => 'analytics',
'uses' => 'SettingsController@showAnalyticsView',
]);
$router->get('localization', [
'as' => 'localization',
'uses' => 'SettingsController@showLocalizationView',
]);
$router->get('security', [
'as' => 'security',
'uses' => 'SettingsController@showSecurityView',
]);
$router->get('theme', [
'as' => 'theme',
'uses' => 'SettingsController@showThemeView',
]);
$router->get('stylesheet', [
'as' => 'stylesheet',
'uses' => 'SettingsController@showStylesheetView',
]);
$router->post('/', 'SettingsController@postSettings');
});
$router->group(['as' => 'incidents.', 'prefix' => 'incidents'], function (Registrar $router) {
$router->get('/', [
'as' => 'index',
'uses' => 'IncidentController@showIncidents',
]);
$router->get('add', [
'as' => 'add',
'uses' => 'IncidentController@showAddIncident',
]);
$router->post('add', 'IncidentController@createIncidentAction');
$router->delete('{incident}/delete', [
'as' => 'delete',
'uses' => 'IncidentController@deleteIncidentAction',
]);
$router->get('{incident}/edit', [
'as' => 'edit',
'uses' => 'IncidentController@showEditIncidentAction',
]);
$router->post('{incident}/edit', 'IncidentController@editIncidentAction');
});
$router->group(['prefix' => 'user'], function ($router) {
$router->get('/', [
'as' => 'user',
'uses' => 'UserController@showUser',
]);
$router->post('/', 'UserController@postUser');
$router->get('{user}/api/regen', 'UserController@regenerateApiKey');
});
$router->group(['as' => 'schedule.', 'prefix' => 'schedule'], function (Registrar $router) {
$router->get('/', [
'as' => 'index',
'uses' => 'ScheduleController@showIndex',
]);
$router->get('add', [
'as' => 'add',
'uses' => 'ScheduleController@showAddSchedule',
]);
$router->post('add', 'ScheduleController@addScheduleAction');
$router->get('{incident}/edit', [
'as' => 'edit',
'uses' => 'ScheduleController@showEditSchedule',
]);
$router->post('{incident}/edit', 'ScheduleController@editScheduleAction');
$router->delete('{incident}/delete', [
'as' => 'delete',
'uses' => 'ScheduleController@deleteScheduleAction',
]);
});
$router->group(['prefix' => 'api'], function ($router) {
$router->get('incidents/templates', 'ApiController@getIncidentTemplate');
$router->post('components/groups/order', 'ApiController@postUpdateComponentGroupOrder');
$router->post('components/order', 'ApiController@postUpdateComponentOrder');
$router->post('components/{component}', 'ApiController@postUpdateComponent');
$router->get('system/version', 'ApiController@checkVersion');
$router->group(['as' => 'templates.', 'prefix' => 'templates'], function (Registrar $router) {
$router->get('/', [
'as' => 'index',
'uses' => 'IncidentController@showTemplates',
]);
$router->get('add', [
'as' => 'add',
'uses' => 'IncidentController@showAddIncidentTemplate',
]);
$router->post('add', 'IncidentController@createIncidentTemplateAction');
$router->get('{incident_template}/edit', [
'as' => 'edit',
'uses' => 'IncidentController@showEditTemplateAction',
]);
$router->post('{incident_template}/edit', 'IncidentController@editTemplateAction');
$router->delete('{incident_template}/delete', 'IncidentController@deleteTemplateAction');
});
$router->group(['as' => 'subscribers.', 'prefix' => 'subscribers'], function (Registrar $router) {
$router->get('/', [
'as' => 'index',
'uses' => 'SubscriberController@showSubscribers',
]);
$router->get('add', [
'as' => 'add',
'uses' => 'SubscriberController@showAddSubscriber',
]);
$router->post('add', 'SubscriberController@createSubscriberAction');
$router->delete('{subscriber}/delete', 'SubscriberController@deleteSubscriberAction');
});
$router->group(['as' => 'metrics.', 'prefix' => 'metrics'], function (Registrar $router) {
$router->get('/', [
'as' => 'index',
'uses' => 'MetricController@showMetrics',
]);
$router->get('add', [
'as' => 'add',
'uses' => 'MetricController@showAddMetric',
]);
$router->post('add', 'MetricController@createMetricAction');
$router->delete('{metric}/delete', 'MetricController@deleteMetricAction');
$router->get('{metric}/edit', [
'as' => 'edit',
'uses' => 'MetricController@showEditMetricAction',
]);
$router->post('{metric}/edit', 'MetricController@editMetricAction');
});
$router->group(['as' => 'team.', 'prefix' => 'team'], function (Registrar $router) {
$router->get('/', [
'as' => 'index',
'uses' => 'TeamController@showTeamView',
]);
$router->group(['middleware' => 'admin'], function (Registrar $router) {
$router->get('add', [
'as' => 'add',
'uses' => 'TeamController@showAddTeamMemberView',
]);
$router->get('invite', [
'as' => 'invite',
'uses' => 'TeamController@showInviteTeamMemberView',
]);
$router->get('{user}', ['as' => 'edit', 'uses' => 'TeamController@showTeamMemberView']);
$router->post('add', 'TeamController@postAddUser');
$router->post('invite', 'TeamController@postInviteUser');
$router->post('{user}', 'TeamController@postUpdateUser');
$router->delete('{user}/delete', 'TeamController@deleteUser');
});
});
$router->group(['as' => 'settings.', 'prefix' => 'settings'], function (Registrar $router) {
$router->get('setup', [
'as' => 'setup',
'uses' => 'SettingsController@showSetupView',
]);
$router->get('analytics', [
'as' => 'analytics',
'uses' => 'SettingsController@showAnalyticsView',
]);
$router->get('localization', [
'as' => 'localization',
'uses' => 'SettingsController@showLocalizationView',
]);
$router->get('security', [
'as' => 'security',
'uses' => 'SettingsController@showSecurityView',
]);
$router->get('theme', [
'as' => 'theme',
'uses' => 'SettingsController@showThemeView',
]);
$router->get('stylesheet', [
'as' => 'stylesheet',
'uses' => 'SettingsController@showStylesheetView',
]);
$router->get('customization', [
'as' => 'customization',
'uses' => 'SettingsController@showCustomizationView',
]);
$router->get('credits', [
'as' => 'credits',
'uses' => 'SettingsController@showCreditsView',
]);
$router->post('/', 'SettingsController@postSettings');
});
$router->group(['prefix' => 'user'], function (Registrar $router) {
$router->get('/', [
'as' => 'user',
'uses' => 'UserController@showUser',
]);
$router->post('/', 'UserController@postUser');
$router->get('{user}/api/regen', 'UserController@regenerateApiKey');
});
$router->group(['prefix' => 'api'], function (Registrar $router) {
$router->get('incidents/templates', 'ApiController@getIncidentTemplate');
$router->post('components/groups/order', 'ApiController@postUpdateComponentGroupOrder');
$router->post('components/order', 'ApiController@postUpdateComponentOrder');
$router->post('components/{component}', 'ApiController@postUpdateComponent');
});
});
});
}

View File

@@ -29,7 +29,7 @@ class FeedRoutes
*/
public function map(Registrar $router)
{
$router->group(['middleware' => ['web', 'ready']], function ($router) {
$router->group(['middleware' => ['web', 'ready']], function (Registrar $router) {
$router->get('/atom/{component_group?}', [
'as' => 'feed.atom',
'uses' => 'FeedController@atomAction',

View File

@@ -17,6 +17,7 @@ use Illuminate\Contracts\Routing\Registrar;
* This is the setup routes class.
*
* @author James Brooks <james@alt-three.com>
* @author Graham Campbell <graham@alt-three.com>
*/
class SetupRoutes
{
@@ -29,8 +30,11 @@ class SetupRoutes
*/
public function map(Registrar $router)
{
$router->group(['middleware' => ['web', 'setup']], function ($router) {
$router->controller('setup', 'SetupController');
$router->group(['middleware' => ['web', 'setup']], function (Registrar $router) {
$router->get('setup', 'SetupController@getIndex');
$router->post('setup/step1', 'SetupController@postStep1');
$router->post('setup/step2', 'SetupController@postStep2');
$router->post('setup/step3', 'SetupController@postStep3');
});
}
}

View File

@@ -29,7 +29,7 @@ class SignupRoutes
*/
public function map(Registrar $router)
{
$router->group(['middleware' => ['web', 'ready', 'guest'], 'as' => 'signup.'], function ($router) {
$router->group(['middleware' => ['web', 'ready', 'guest'], 'as' => 'signup.'], function (Registrar $router) {
$router->get('signup/invite/{code}', [
'as' => 'invite',
'uses' => 'SignupController@getSignup',

View File

@@ -29,7 +29,7 @@ class StatusPageRoutes
*/
public function map(Registrar $router)
{
$router->group(['middleware' => ['web', 'ready', 'localize']], function ($router) {
$router->group(['middleware' => ['web', 'ready', 'localize']], function (Registrar $router) {
$router->get('/', [
'as' => 'status-page',
'uses' => 'StatusPageController@showIndex',
@@ -39,6 +39,13 @@ class StatusPageRoutes
'as' => 'incident',
'uses' => 'StatusPageController@showIncident',
]);
$router->get('metrics/{metric}', [
'as' => 'metrics',
'uses' => 'StatusPageController@getMetrics',
]);
$router->get('component/{component}/shield', 'StatusPageController@showComponentBadge');
});
}
}

View File

@@ -29,17 +29,25 @@ class SubscribeRoutes
*/
public function map(Registrar $router)
{
$router->group(['middleware' => ['web', 'ready', 'localize'], 'as' => 'subscribe.'], function ($router) {
$router->group(['middleware' => ['subscribers']], function ($router) {
$router->get('subscribe', [
'as' => 'subscribe',
'uses' => 'SubscribeController@showSubscribe',
]);
$router->group(['middleware' => ['web', 'ready', 'localize', 'subscribers'], 'as' => 'subscribe.'], function (Registrar $router) {
$router->get('subscribe', [
'as' => 'subscribe',
'uses' => 'SubscribeController@showSubscribe',
]);
$router->post('subscribe', [
'uses' => 'SubscribeController@postSubscribe',
]);
});
$router->post('subscribe', [
'uses' => 'SubscribeController@postSubscribe',
]);
$router->get('subscribe/manage/{code}', [
'as' => 'manage',
'uses' => 'SubscribeController@showManage',
]);
$router->post('subscribe/manage/{code}', [
'as' => 'manage',
'uses' => 'SubscribeController@postManage',
]);
$router->get('subscribe/verify/{code}', [
'as' => 'verify',

View File

@@ -0,0 +1,27 @@
<?php
/*
* This file is part of Cachet.
*
* (c) Alt Three Services Limited
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace CachetHQ\Cachet\Integrations\Contracts;
/**
* This is the system interface.
*
* @author James Brooks <james@alt-three.com>
*/
interface System
{
/**
* Get the entire system status.
*
* @return array
*/
public function getStatus();
}

View File

@@ -0,0 +1,70 @@
<?php
/*
* This file is part of Cachet.
*
* (c) Alt Three Services Limited
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace CachetHQ\Cachet\Integrations\Core;
use CachetHQ\Cachet\Integrations\Contracts\System as SystemContract;
use CachetHQ\Cachet\Models\Component;
use CachetHQ\Cachet\Models\Incident;
/**
* This is the core system class.
*
* @author James Brooks <james@alt-three.com>
*/
class System implements SystemContract
{
/**
* Get the entire system status.
*
* @return array
*/
public function getStatus()
{
$enabledScope = Component::enabled();
$totalComponents = Component::enabled()->count();
$majorOutages = Component::enabled()->status(4)->count();
$isMajorOutage = $totalComponents ? ($majorOutages / $totalComponents) >= 0.5 : false;
// Default data
$status = [
'system_status' => 'info',
'system_message' => trans_choice('cachet.service.bad', $totalComponents),
'favicon' => 'favicon-high-alert',
];
if ($isMajorOutage) {
$status = [
'system_status' => 'danger',
'system_message' => trans_choice('cachet.service.major', $totalComponents),
'favicon' => 'favicon-high-alert',
];
} elseif (Component::enabled()->notStatus(1)->count() === 0) {
// If all our components are ok, do we have any non-fixed incidents?
$incidents = Incident::notScheduled()->orderBy('created_at', 'desc')->get()->filter(function ($incident) {
return $incident->status > 0;
});
$incidentCount = $incidents->count();
if ($incidentCount === 0 || ($incidentCount >= 1 && (int) $incidents->first()->status === 4)) {
$status = [
'system_status' => 'success',
'system_message' => trans_choice('cachet.service.good', $totalComponents),
'favicon' => 'favicon',
];
}
} elseif (Component::enabled()->whereIn('status', [2, 3])->count() > 0) {
$status['favicon'] = 'favicon-medium-alert';
}
return $status;
}
}

View File

@@ -0,0 +1,81 @@
<?php
/*
* This file is part of Cachet.
*
* (c) Alt Three Services Limited
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace CachetHQ\Cachet\Integrations;
use Exception;
use GuzzleHttp\Client;
use Illuminate\Contracts\Cache\Repository;
class Credits
{
/**
* The default url.
*
* @var string
*/
const URL = 'https://cachethq.io/credits';
/**
* The failed status indicator.
*
* @var int
*/
const FAILED = 1;
/**
* The cache repository instance.
*
* @var \Illuminate\Contracts\Cache\Repository
*/
protected $cache;
/**
* The url to use.
*
* @var string|null
*/
protected $url;
/**
* Creates a new credits instance.
*
* @param \Illuminate\Contracts\Cache\Repository $cache
* @param string|null $url
*
* @return void
*/
public function __construct(Repository $cache, $url = null)
{
$this->cache = $cache;
$this->url = $url ?: static::URL;
}
/**
* Returns the latest credits.
*
* @return array|null
*/
public function latest()
{
$result = $this->cache->remember('credits', 2880, function () {
try {
return json_decode((new Client())->get($this->url, [
'headers' => ['Accept' => 'application/json', 'User-Agent' => defined('CACHET_VERSION') ? 'cachet/'.constant('CACHET_VERSION') : 'cachet'],
])->getBody(), true);
} catch (Exception $e) {
return self::FAILED;
}
});
return $result === self::FAILED ? null : $result;
}
}

88
app/Integrations/Feed.php Normal file
View File

@@ -0,0 +1,88 @@
<?php
/*
* This file is part of Cachet.
*
* (c) Alt Three Services Limited
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace CachetHQ\Cachet\Integrations;
use Exception;
use GuzzleHttp\Client;
use Illuminate\Contracts\Cache\Repository;
/**
* This is the feed class.
*
* @author James Brooks <james@alt-three.com>
*/
class Feed
{
/**
* The default url.
*
* @var string
*/
const URL = 'https://blog.alt-three.com/tag/cachet/rss';
/**
* The failed status indicator.
*
* @var int
*/
const FAILED = 1;
/**
* The cache repository instance.
*
* @var \Illuminate\Contracts\Cache\Repository
*/
protected $cache;
/**
* The url to use.
*
* @var string|null
*/
protected $url;
/**
* Creates a new feed instance.
*
* @param \Illuminate\Contracts\Cache\Repository $cache
* @param string|null $url
*
* @return void
*/
public function __construct(Repository $cache, $url = null)
{
$this->cache = $cache;
$this->url = $url ?: static::URL;
}
/**
* Returns the latest entries.
*
* @return array|null
*/
public function latest()
{
$result = $this->cache->remember('feeds', 720, function () {
try {
$xml = simplexml_load_string((new Client())->get($this->url, [
'headers' => ['Accept' => 'application/rss+xml', 'User-Agent' => defined('CACHET_VERSION') ? 'cachet/'.constant('CACHET_VERSION') : 'cachet'],
])->getBody()->getContents(), null, LIBXML_NOCDATA);
return json_decode(json_encode($xml));
} catch (Exception $e) {
return self::FAILED;
}
});
return $result === self::FAILED ? null : $result;
}
}

View File

@@ -0,0 +1,95 @@
<?php
/*
* This file is part of Cachet.
*
* (c) Alt Three Services Limited
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace CachetHQ\Cachet\Integrations;
use GuzzleHttp\Client;
use Illuminate\Contracts\Cache\Repository;
class Releases
{
/**
* The default url.
*
* @var string
*/
const URL = 'https://api.github.com/repos/cachethq/cachet/releases/latest';
/**
* The failed status indicator.
*
* @var int
*/
const FAILED = 1;
/**
* The cache repository instance.
*
* @var \Illuminate\Contracts\Cache\Repository
*/
protected $cache;
/**
* The github authentication token.
*
* @var string|null
*/
protected $token;
/**
* The url to use.
*
* @var string|null
*/
protected $url;
/**
* Creates a new releases instance.
*
* @param \Illuminate\Contracts\Cache\Repository $cache
* @param string|null $token
* @param string|null $url
*
* @return void
*/
public function __construct(Repository $cache, $token = null, $url = null)
{
$this->cache = $cache;
$this->token = $token;
$this->url = $url ?: static::URL;
}
/**
* Returns the latest release.
*
* @return string
*/
public function latest()
{
$release = $this->cache->remember('release.latest', 720, function () {
$headers = ['Accept' => 'application/vnd.github.v3+json', 'User-Agent' => defined('CACHET_VERSION') ? 'cachet/'.constant('CACHET_VERSION') : 'cachet'];
if ($this->token) {
$headers['OAUTH-TOKEN'] = $this->token;
}
return json_decode((new Client())->get($this->url, [
'headers' => $headers,
])->getBody(), true);
});
return [
'tag_name' => $release['tag_name'],
'prelease' => $release['prerelease'],
'draft' => $release['draft'],
];
}
}

View File

@@ -12,6 +12,8 @@
namespace CachetHQ\Cachet\Models;
use AltThree\Validator\ValidatingTrait;
use CachetHQ\Cachet\Models\Traits\SearchableTrait;
use CachetHQ\Cachet\Models\Traits\SortableTrait;
use CachetHQ\Cachet\Presenters\ComponentPresenter;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Model;
@@ -20,7 +22,10 @@ use McCool\LaravelAutoPresenter\HasPresenter;
class Component extends Model implements HasPresenter
{
use SoftDeletes, ValidatingTrait;
use SearchableTrait;
use SoftDeletes;
use SortableTrait;
use ValidatingTrait;
/**
* List of attributes that have default values.
@@ -76,6 +81,34 @@ class Component extends Model implements HasPresenter
'link' => 'url',
];
/**
* The searchable fields.
*
* @var string[]
*/
protected $searchable = [
'id',
'name',
'status',
'order',
'group_id',
'enabled',
];
/**
* The sortable fields.
*
* @var string[]
*/
protected $sortable = [
'id',
'name',
'status',
'order',
'group_id',
'enabled',
];
/**
* Components can belong to a group.
*

View File

@@ -12,14 +12,28 @@
namespace CachetHQ\Cachet\Models;
use AltThree\Validator\ValidatingTrait;
use CachetHQ\Cachet\Models\Traits\SearchableTrait;
use CachetHQ\Cachet\Models\Traits\SortableTrait;
use CachetHQ\Cachet\Presenters\ComponentGroupPresenter;
use Illuminate\Database\Eloquent\Model;
use McCool\LaravelAutoPresenter\HasPresenter;
class ComponentGroup extends Model implements HasPresenter
{
use SearchableTrait;
use SortableTrait;
use ValidatingTrait;
/**
* The model's attributes.
*
* @var string
*/
protected $attributes = [
'order' => 0,
'collapsed' => 0,
];
/**
* The attributes that should be casted to native types.
*
@@ -28,7 +42,7 @@ class ComponentGroup extends Model implements HasPresenter
protected $casts = [
'name' => 'string',
'order' => 'int',
'collapsed' => 'bool',
'collapsed' => 'int',
];
/**
@@ -46,7 +60,31 @@ class ComponentGroup extends Model implements HasPresenter
public $rules = [
'name' => 'required|string',
'order' => 'int',
'collapsed' => 'bool',
'collapsed' => 'int',
];
/**
* The searchable fields.
*
* @var string[]
*/
protected $searchable = [
'id',
'name',
'order',
'collapsed',
];
/**
* The sortable fields.
*
* @var string[]
*/
protected $sortable = [
'id',
'name',
'order',
'collapsed',
];
/**
@@ -66,6 +104,16 @@ class ComponentGroup extends Model implements HasPresenter
return $this->hasMany(Component::class, 'group_id', 'id');
}
/**
* Get the incidents relation.
*
* @return \Illuminate\Database\Eloquent\Relations\HasManyThrough
*/
public function incidents()
{
return $this->hasManyThrough(Incident::class, Component::class, 'id', 'component_id');
}
/**
* Return all of the enabled components.
*
@@ -73,7 +121,7 @@ class ComponentGroup extends Model implements HasPresenter
*/
public function enabled_components()
{
return $this->components()->enabled();
return $this->components()->enabled()->orderBy('order');
}
/**

View File

@@ -12,15 +12,21 @@
namespace CachetHQ\Cachet\Models;
use AltThree\Validator\ValidatingTrait;
use CachetHQ\Cachet\Models\Traits\SearchableTrait;
use CachetHQ\Cachet\Models\Traits\SortableTrait;
use CachetHQ\Cachet\Presenters\IncidentPresenter;
use Carbon\Carbon;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
use McCool\LaravelAutoPresenter\HasPresenter;
class Incident extends Model implements HasPresenter
{
use SoftDeletes, ValidatingTrait;
use SearchableTrait;
use SoftDeletes;
use SortableTrait;
use ValidatingTrait;
/**
* The attributes that should be casted to native types.
@@ -62,6 +68,32 @@ class Incident extends Model implements HasPresenter
'message' => 'required',
];
/**
* The searchable fields.
*
* @var string[]
*/
protected $searchable = [
'id',
'component_id',
'name',
'status',
'visible',
];
/**
* The sortable fields.
*
* @var string[]
*/
protected $sortable = [
'id',
'name',
'status',
'visible',
'message',
];
/**
* Finds all visible incidents.
*
@@ -69,7 +101,7 @@ class Incident extends Model implements HasPresenter
*
* @return \Illuminate\Database\Eloquent\Builder
*/
public function scopeVisible($query)
public function scopeVisible(Builder $query)
{
return $query->where('visible', 1);
}
@@ -81,9 +113,9 @@ class Incident extends Model implements HasPresenter
*
* @return \Illuminate\Database\Eloquent\Builder
*/
public function scopeScheduled($query)
public function scopeScheduled(Builder $query)
{
return $query->where('status', 0)->where('scheduled_at', '>=', Carbon::now());
return $query->where('status', 0)->where('scheduled_at', '>=', Carbon::now()->toDateTimeString());
}
/**
@@ -93,10 +125,12 @@ class Incident extends Model implements HasPresenter
*
* @return \Illuminate\Database\Eloquent\Builder
*/
public function scopeNotScheduled($query)
public function scopeNotScheduled(Builder $query)
{
return $query->where(function ($query) {
return $query->whereNull('scheduled_at')->orWhere('scheduled_at', '<=', Carbon::now());
return $query->where('status', '>', 0)->orWhere(function ($query) {
$query->where('status', 0)->where(function ($query) {
$query->whereNull('scheduled_at')->orWhere('scheduled_at', '<=', Carbon::now()->toDateTimeString());
});
});
}

View File

@@ -12,12 +12,15 @@
namespace CachetHQ\Cachet\Models;
use AltThree\Validator\ValidatingTrait;
use CachetHQ\Cachet\Models\Traits\SortableTrait;
use CachetHQ\Cachet\Presenters\MetricPresenter;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Model;
use McCool\LaravelAutoPresenter\HasPresenter;
class Metric extends Model implements HasPresenter
{
use SortableTrait;
use ValidatingTrait;
/**
@@ -46,6 +49,8 @@ class Metric extends Model implements HasPresenter
'calc_type' => 0,
'places' => 2,
'default_view' => 1,
'threshold' => 5,
'order' => 0,
];
/**
@@ -60,6 +65,8 @@ class Metric extends Model implements HasPresenter
'calc_type' => 'int',
'places' => 'int',
'default_view' => 'int',
'threshold' => 'int',
'order' => 'int',
];
/**
@@ -76,6 +83,8 @@ class Metric extends Model implements HasPresenter
'calc_type',
'places',
'default_view',
'threshold',
'order',
];
/**
@@ -90,6 +99,22 @@ class Metric extends Model implements HasPresenter
'default_value' => 'numeric',
'places' => 'numeric|between:0,4',
'default_view' => 'numeric|between:0,3',
'threshold' => 'numeric|between:0,10',
'threshold' => 'int',
];
/**
* The sortable fields.
*
* @var string[]
*/
protected $sortable = [
'id',
'name',
'display_chart',
'default_value',
'calc_type',
'order',
];
/**
@@ -102,6 +127,18 @@ class Metric extends Model implements HasPresenter
return $this->hasMany(MetricPoint::class, 'metric_id', 'id');
}
/**
* Scope metrics to those of which are displayable.
*
* @param \Illuminate\Database\Eloquent\Builder $query
*
* @return \Illuminate\Database\Eloquent\Builder
*/
public function scopeDisplayable(Builder $query)
{
return $query->where('display_chart', 1);
}
/**
* Determines whether a chart should be shown.
*

View File

@@ -20,6 +20,16 @@ class MetricPoint extends Model implements HasPresenter
{
use ValidatingTrait;
/**
* The model's attributes.
*
* @var string[]
*/
protected $attributes = [
'value' => 0,
'counter' => 1,
];
/**
* The attributes that should be casted to native types.
*
@@ -27,7 +37,8 @@ class MetricPoint extends Model implements HasPresenter
*/
protected $casts = [
'metric_id' => 'int',
'value' => 'int',
'value' => 'float',
'counter' => 'int',
];
/**
@@ -35,7 +46,12 @@ class MetricPoint extends Model implements HasPresenter
*
* @var string[]
*/
protected $fillable = ['metric_id', 'value', 'created_at'];
protected $fillable = [
'metric_id',
'value',
'counter',
'created_at',
];
/**
* The validation rules.
@@ -53,7 +69,25 @@ class MetricPoint extends Model implements HasPresenter
*/
public function metric()
{
return $this->belongsTo(Metric::class, 'id', 'metric_id');
return $this->belongsTo(Metric::class);
}
/**
* Override the value attribute.
*
* @param mixed $value
*
* @return float
*/
public function getActiveValueAttribute($value)
{
if ($this->metric->calc_type === Metric::CALC_SUM) {
return round((float) $value * $this->counter, $this->metric->places);
} elseif ($this->metric->calc_type === Metric::CALC_AVG) {
return round((float) $value * $this->counter, $this->metric->places);
}
return round((float) $value, $this->metric->places);
}
/**

View File

@@ -30,6 +30,7 @@ class Subscriber extends Model implements HasPresenter
'email' => 'string',
'verify_code' => 'string',
'verified_at' => 'date',
'global' => 'bool',
];
/**
@@ -48,6 +49,13 @@ class Subscriber extends Model implements HasPresenter
'email' => 'required|email',
];
/**
* The relations to eager load on every query.
*
* @var string[]
*/
protected $with = ['subscriptions'];
/**
* Overrides the models boot method.
*/
@@ -84,6 +92,33 @@ class Subscriber extends Model implements HasPresenter
return $query->whereNotNull('verified_at');
}
/**
* Scope global subscribers.
*
* @param \Illuminate\Database\Eloquent\Builder $query
*
* @return \Illuminate\Database\Eloquent\Builder
*/
public function scopeIsGlobal(Builder $query)
{
return $query->where('global', true);
}
/**
* Finds all verified subscriptions for a component.
*
* @param \Illuminate\Database\Eloquent\Builder $query
* @param int $component_id
*
* @return \Illuminate\Database\Eloquent\Builder
*/
public function scopeForComponent(Builder $query, $component_id)
{
return $query->select('subscribers.*')
->join('subscriptions', 'subscribers.id', '=', 'subscriptions.subscriber_id')
->where('subscriptions.component_id', $component_id);
}
/**
* Determines if the subscriber is verified.
*

View File

@@ -107,7 +107,10 @@ class Subscription extends Model
{
return $query->select('subscriptions.*')
->join('subscribers', 'subscriptions.subscriber_id', '=', 'subscribers.id')
->where('component_id', $component_id)
->where(function ($query) {
$query->where('subscriptions.component_id', $component_id)
->orWhere('subscribers.global');
})
->whereNotNull('subscribers.verified_at');
}
}

View File

@@ -0,0 +1,44 @@
<?php
/*
* This file is part of Cachet.
*
* (c) Alt Three Services Limited
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace CachetHQ\Cachet\Models\Traits;
use Illuminate\Database\Eloquent\Builder;
/**
* This is the searchable trait.
*
* @author James Brooks <james@alt-three.com>
*/
trait SearchableTrait
{
/**
* Adds a search scope.
*
* @param \Illuminate\Database\Eloquent\Builder $query
* @param array $search
*
* @return \Illuminate\Database\Eloquent\Builder
*/
public function scopeSearch(Builder $query, array $search = [])
{
if (empty($search)) {
return $query;
}
$allowed_search = array_intersect_key($search, array_flip($this->searchable));
if (!$allowed_search) {
return $query;
}
return $query->where($allowed_search);
}
}

View File

@@ -0,0 +1,40 @@
<?php
/*
* This file is part of Cachet.
*
* (c) Alt Three Services Limited
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace CachetHQ\Cachet\Models\Traits;
use Illuminate\Database\Eloquent\Builder;
/**
* This is the sortable trait.
*
* @author James Brooks <james@alt-three.com>
*/
trait SortableTrait
{
/**
* Adds a sort scope.
*
* @param \Illuminate\Database\Eloquent\Builder $query
* @param string $column
* @param string $direction
*
* @return \Illuminate\Database\Eloquent\Builder
*/
public function scopeSort(Builder $query, $column, $direction)
{
if (!in_array($column, $this->sortable)) {
return $query;
}
return $query->orderBy($column, $direction);
}
}

View File

@@ -22,7 +22,9 @@ use Illuminate\Support\Facades\Hash;
class User extends Model implements AuthenticatableContract, CanResetPasswordContract
{
use Authenticatable, CanResetPassword, ValidatingTrait;
use Authenticatable;
use CanResetPassword;
use ValidatingTrait;
/**
* The admin level of user.
@@ -116,7 +118,7 @@ class User extends Model implements AuthenticatableContract, CanResetPasswordCon
*/
public function getGravatarAttribute($size = 200)
{
return sprintf('https://www.gravatar.com/avatar/%s?size=%d', md5($this->email), $size);
return sprintf('https://www.gravatar.com/avatar/%s?size=%d', md5(strtolower($this->email)), $size);
}
/**

View File

@@ -63,7 +63,25 @@ class ComponentGroupPresenter extends BasePresenter implements Arrayable
*/
public function collapse_class()
{
return $this->wrappedObject->collapsed ? 'ion-ios-plus-outline' : 'ion-ios-minus-outline';
return $this->is_collapsed() ? 'ion-ios-plus-outline' : 'ion-ios-minus-outline';
}
/**
* Determine if the group should be collapsed.
*
* @return bool
*/
public function is_collapsed()
{
if ($this->wrappedObject->collapsed === 0) {
return false;
} elseif ($this->wrappedObject->collapsed === 1) {
return true;
}
return $this->wrappedObject->components->filter(function ($component) {
return $component->status > 1;
})->count() === 0;
}
/**

View File

@@ -11,8 +11,10 @@
namespace CachetHQ\Cachet\Presenters;
use CachetHQ\Cachet\Dates\DateFactory;
use CachetHQ\Cachet\Presenters\Traits\TimestampsTrait;
use Illuminate\Contracts\Support\Arrayable;
use Illuminate\Support\Facades\Config;
use McCool\LaravelAutoPresenter\BasePresenter;
class ComponentPresenter extends BasePresenter implements Arrayable
@@ -44,6 +46,26 @@ class ComponentPresenter extends BasePresenter implements Arrayable
return trans('cachet.components.status.'.$this->wrappedObject->status);
}
/**
* Find all tag names for the component names.
*
* @return array
*/
public function tags()
{
return $this->wrappedObject->tags->pluck('name', 'slug');
}
/**
* Present formatted date time.
*
* @return string
*/
public function updated_at_formatted()
{
return ucfirst(app(DateFactory::class)->make($this->wrappedObject->updated_at)->format(Config::get('setting.incident_date_format', 'l jS F Y H:i:s')));
}
/**
* Convert the presenter instance to an array.
*
@@ -55,6 +77,7 @@ class ComponentPresenter extends BasePresenter implements Arrayable
'created_at' => $this->created_at(),
'updated_at' => $this->updated_at(),
'status_name' => $this->human_status(),
'tags' => $this->tags(),
]);
}
}

View File

@@ -19,6 +19,16 @@ class MetricPointPresenter extends BasePresenter implements Arrayable
{
use TimestampsTrait;
/**
* Show the actual calculated value; as per (value * counter).
*
* @return int
*/
public function calculated_value()
{
return $this->wrappedObject->value * $this->wrappedObject->counter;
}
/**
* Convert the presenter instance to an array.
*
@@ -27,8 +37,9 @@ class MetricPointPresenter extends BasePresenter implements Arrayable
public function toArray()
{
return array_merge($this->wrappedObject->toArray(), [
'created_at' => $this->created_at(),
'updated_at' => $this->updated_at(),
'created_at' => $this->created_at(),
'updated_at' => $this->updated_at(),
'calculated_value' => $this->calculated_value(),
]);
}
}

View File

@@ -34,6 +34,16 @@ class MetricPresenter extends BasePresenter implements Arrayable
}
}
/**
* Determines the metric view filter name, used in the API.
*
* @return string
*/
public function default_view_name()
{
return trans('cachet.metrics.filter.'.$this->trans_string_name());
}
/**
* Determines the metric translation view filter name.
*
@@ -57,8 +67,9 @@ class MetricPresenter extends BasePresenter implements Arrayable
public function toArray()
{
return array_merge($this->wrappedObject->toArray(), [
'created_at' => $this->created_at(),
'updated_at' => $this->updated_at(),
'created_at' => $this->created_at(),
'updated_at' => $this->updated_at(),
'default_view_name' => $this->default_view_name(),
]);
}
}

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