diff --git a/app/config/app.php b/app/config/app.php index 671dc42e3562..1a786e0a768b 100644 --- a/app/config/app.php +++ b/app/config/app.php @@ -126,17 +126,18 @@ /* * Packages Service Providers... */ + 'CachetHQ\Segment\SegmentServiceProvider', 'Dingo\Api\Provider\ApiServiceProvider', - 'GrahamCampbell\Security\SecurityServiceProvider', + 'Fideloper\Proxy\ProxyServiceProvider', 'GrahamCampbell\Binput\BinputServiceProvider', - 'GrahamCampbell\Throttle\ThrottleServiceProvider', 'GrahamCampbell\Markdown\MarkdownServiceProvider', - 'Roumen\Feed\FeedServiceProvider', - 'Thujohn\Rss\RssServiceProvider', + 'GrahamCampbell\Security\SecurityServiceProvider', + 'GrahamCampbell\Throttle\ThrottleServiceProvider', 'Jenssegers\Date\DateServiceProvider', 'McCool\LaravelAutoPresenter\LaravelAutoPresenterServiceProvider', 'PragmaRX\Google2FA\Vendor\Laravel\ServiceProvider', - 'Fideloper\Proxy\ProxyServiceProvider', + 'Roumen\Feed\FeedServiceProvider', + 'Thujohn\Rss\RssServiceProvider', /* * Application Service Providers... diff --git a/app/config/packages/cachethq/segment/config.php b/app/config/packages/cachethq/segment/config.php new file mode 100644 index 000000000000..84214216c252 --- /dev/null +++ b/app/config/packages/cachethq/segment/config.php @@ -0,0 +1,9 @@ + 'AdcpUouGjiShPkxoZWxhMUDWAT6tsvbY', + 'consumer' => 'socket', + 'debug' => false, + 'ssl' => true, + 'error_handler' => null, +]; diff --git a/app/lang/de/setup.php b/app/lang/de/setup.php index 9b60680e9237..88301da692bd 100644 --- a/app/lang/de/setup.php +++ b/app/lang/de/setup.php @@ -10,4 +10,5 @@ 'complete_setup' => 'Setup abschließen', 'completed' => 'Cachet wurde erfolgreich eingerichtet!', 'finish_setup' => 'Zum Dashboard', + 'allow_tracking' => 'Allow anonymous usage tracking?', ]; diff --git a/app/lang/en/setup.php b/app/lang/en/setup.php index af0d654b1258..6a317615e33e 100644 --- a/app/lang/en/setup.php +++ b/app/lang/en/setup.php @@ -10,4 +10,5 @@ 'complete_setup' => 'Complete Setup', 'completed' => 'Cachet has been configured successfully!', 'finish_setup' => 'Go to dashboard', + 'allow_tracking' => 'Allow anonymous usage tracking?', ]; diff --git a/app/lang/fr/setup.php b/app/lang/fr/setup.php index ae8e0d68a061..3fb5cbbfb635 100644 --- a/app/lang/fr/setup.php +++ b/app/lang/fr/setup.php @@ -10,4 +10,5 @@ 'complete_setup' => 'Terminer l\'installation', 'completed' => 'Cachet a été configuré avec succès !', 'finish_setup' => 'Aller au tableau de bord', + 'allow_tracking' => 'Allow anonymous usage tracking?', ]; diff --git a/app/start/global.php b/app/start/global.php index 4853e52da2bb..39e24e26ef20 100644 --- a/app/start/global.php +++ b/app/start/global.php @@ -1,6 +1,8 @@ +
+
+
+ + + +
+
+
diff --git a/app/views/setup.blade.php b/app/views/setup.blade.php index 4b1c81b858c9..111fbcceb6ad 100644 --- a/app/views/setup.blade.php +++ b/app/views/setup.blade.php @@ -78,6 +78,12 @@ {{ trans("setup.show_support") }}
+
+ +

diff --git a/composer.json b/composer.json index 3d888eb12a03..e56e9bbbbd40 100644 --- a/composer.json +++ b/composer.json @@ -14,6 +14,7 @@ "ext-mcrypt": "*", "ext-openssl": "*", "laravel/framework": "4.2.*", + "cachethq/segment": "1.0.*@dev", "dingo/api": "0.8.*", "doctrine/dbal": "2.5.*", "graham-campbell/binput": "2.1.*", diff --git a/composer.lock b/composer.lock index 9ec0536d381a..69b65cabe544 100644 --- a/composer.lock +++ b/composer.lock @@ -4,8 +4,63 @@ "Read more about it at http://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", "This file is @generated automatically" ], - "hash": "3752fec41d40201f38e46974caa27d62", + "hash": "b32031bb1053f393308be4f68d1d0c94", "packages": [ + { + "name": "cachethq/segment", + "version": "dev-master", + "source": { + "type": "git", + "url": "https://github.com/cachethq/Laravel-Segment.git", + "reference": "39121d7953cb91197f0474b9cf43ae198fca1e26" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/cachethq/Laravel-Segment/zipball/39121d7953cb91197f0474b9cf43ae198fca1e26", + "reference": "39121d7953cb91197f0474b9cf43ae198fca1e26", + "shasum": "" + }, + "require": { + "illuminate/config": "~4.1", + "illuminate/support": "~4.1", + "php": ">=5.4.7", + "segmentio/analytics-php": "~1.1.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0-dev" + } + }, + "autoload": { + "psr-4": { + "CachetHQ\\Segment\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "James Brooks", + "email": "james@cachethq.io" + } + ], + "description": "Segment.com wrapper written for Laravel 4", + "keywords": [ + "CachetHQ", + "Laravel Segment", + "api", + "cachet", + "framework", + "laravel", + "segment", + "segment.com", + "segment.io" + ], + "time": "2015-01-23 22:49:00" + }, { "name": "classpreloader/classpreloader", "version": "1.0.2", @@ -2108,6 +2163,51 @@ ], "time": "2014-12-09 14:53:34" }, + { + "name": "segmentio/analytics-php", + "version": "1.1.0", + "source": { + "type": "git", + "url": "https://github.com/segmentio/analytics-php.git", + "reference": "db24fa9a2e1110570c338fea7a6f46bbb7ef105c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/segmentio/analytics-php/zipball/db24fa9a2e1110570c338fea7a6f46bbb7ef105c", + "reference": "db24fa9a2e1110570c338fea7a6f46bbb7ef105c", + "shasum": "" + }, + "require": { + "php": ">=5.3" + }, + "require-dev": { + "phpunit/phpunit": "3.7.*" + }, + "type": "library", + "autoload": { + "files": [ + "lib/Segment.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Segment.io ", + "homepage": "https://segment.io/" + } + ], + "description": "Segmentio Analytics PHP Library", + "homepage": "https://segment.io/libraries/php", + "keywords": [ + "analytics", + "analytics.js", + "segmentio" + ], + "time": "2015-01-07 07:11:38" + }, { "name": "stack/builder", "version": "v1.0.3", @@ -3997,7 +4097,9 @@ ], "aliases": [], "minimum-stability": "stable", - "stability-flags": [], + "stability-flags": { + "cachethq/segment": 20 + }, "prefer-stable": false, "prefer-lowest": false, "platform": { diff --git a/src/Console/Commands/OneClickDeployCommand.php b/src/Console/Commands/OneClickDeployCommand.php index fbd0d7cabaa4..9ec52b93283a 100644 --- a/src/Console/Commands/OneClickDeployCommand.php +++ b/src/Console/Commands/OneClickDeployCommand.php @@ -50,7 +50,13 @@ public function __construct($migrate) public function fire() { if ($this->migrate) { - return $this->runMigrations(); + $migrations = $this->runMigrations(); + + segment_track('Installation', [ + 'event' => 'Heroku Deployment', + ]); + + return $migrations; } $this->info('Please run "php artisan migrate" to finish the installation.'); diff --git a/src/Http/Controllers/DashComponentController.php b/src/Http/Controllers/DashComponentController.php index e73998c50f28..33f6a866e8c7 100644 --- a/src/Http/Controllers/DashComponentController.php +++ b/src/Http/Controllers/DashComponentController.php @@ -109,6 +109,11 @@ public function updateComponentAction(Component $component) $component->update($_component); if (! $component->isValid()) { + segment_track('Dashboard', [ + 'event' => 'Edit Component', + 'success' => false, + ]); + return Redirect::back()->withInput(Binput::all()) ->with('title', sprintf( '%s %s', @@ -118,6 +123,11 @@ public function updateComponentAction(Component $component) ->with('errors', $component->getErrors()); } + segment_track('Dashboard', [ + 'event' => 'Edit Component', + 'success' => true, + ]); + // The component was added successfully, so now let's deal with the tags. $tags = preg_split('/ ?, ?/', $tags); @@ -168,6 +178,11 @@ public function createComponentAction() $component = Component::create($_component); if (! $component->isValid()) { + segment_track('Dashboard', [ + 'event' => 'Created Component', + 'success' => false, + ]); + return Redirect::back()->withInput(Binput::all()) ->with('title', sprintf( '%s %s', @@ -177,6 +192,11 @@ public function createComponentAction() ->with('errors', $component->getErrors()); } + segment_track('Dashboard', [ + 'event' => 'Created Component', + 'success' => true, + ]); + // The component was added successfully, so now let's deal with the tags. $tags = preg_split('/ ?, ?/', $tags); @@ -207,6 +227,10 @@ public function createComponentAction() */ public function deleteComponentAction(Component $component) { + segment_track('Dashboard', [ + 'event' => 'Deleted Component', + ]); + $component->delete(); return Redirect::back(); @@ -221,6 +245,10 @@ public function deleteComponentAction(Component $component) */ public function deleteComponentGroupAction(ComponentGroup $group) { + segment_track('Dashboard', [ + 'event' => 'Deleted Component Group', + ]); + $group->delete(); return Redirect::back(); @@ -248,6 +276,11 @@ public function postAddComponentGroup() $group = ComponentGroup::create(Binput::get('group')); if (! $group->isValid()) { + segment_track('Dashboard', [ + 'event' => 'Created Component Group', + 'success' => false, + ]); + return Redirect::back()->withInput(Binput::all()) ->with('title', sprintf( '%s %s', @@ -257,6 +290,11 @@ public function postAddComponentGroup() ->with('errors', $group->getErrors()); } + segment_track('Dashboard', [ + 'event' => 'Created Component Group', + 'success' => true, + ]); + $successMsg = sprintf( '%s %s', trans('dashboard.notifications.awesome'), diff --git a/src/Http/Controllers/DashIncidentController.php b/src/Http/Controllers/DashIncidentController.php index ac16851d9d3d..77228ba640d5 100644 --- a/src/Http/Controllers/DashIncidentController.php +++ b/src/Http/Controllers/DashIncidentController.php @@ -66,6 +66,11 @@ public function createIncidentAction() $incident = Incident::create($incidentData); if (! $incident->isValid()) { + segment_track('Dashboard', [ + 'event' => 'Created Incident', + 'success' => false, + ]); + return Redirect::back()->withInput(Binput::all()) ->with('title', sprintf( '%s %s', @@ -82,6 +87,11 @@ public function createIncidentAction() ]); } + segment_track('Dashboard', [ + 'event' => 'Created Incident', + 'success' => true, + ]); + $successMsg = sprintf( '%s %s', trans('dashboard.notifications.awesome'), @@ -127,6 +137,10 @@ public function showEditTemplateAction(IncidentTemplate $template) */ public function deleteTemplateAction(IncidentTemplate $template) { + segment_track('Dashboard', [ + 'event' => 'Deleted Incident Template', + ]); + $template->delete(); return Redirect::back(); @@ -143,6 +157,11 @@ public function createIncidentTemplateAction() $template = IncidentTemplate::create($_template); if (! $template->isValid()) { + segment_track('Dashboard', [ + 'event' => 'Created Incident Template', + 'success' => false, + ]); + return Redirect::back()->withInput(Binput::all()) ->with('title', sprintf( '%s %s', @@ -152,6 +171,11 @@ public function createIncidentTemplateAction() ->with('errors', $template->getErrors()); } + segment_track('Dashboard', [ + 'event' => 'Created Incident Template', + 'success' => true, + ]); + $successMsg = sprintf( '%s %s', trans('dashboard.notifications.awesome'), @@ -170,6 +194,10 @@ public function createIncidentTemplateAction() */ public function deleteIncidentAction(Incident $incident) { + segment_track('Dashboard', [ + 'event' => 'Deleted Incident', + ]); + $incident->delete(); return Redirect::back(); @@ -204,6 +232,11 @@ public function editIncidentAction(Incident $incident) $incident->update($_incident); if (! $incident->isValid()) { + segment_track('Dashboard', [ + 'event' => 'Edited Incident', + 'success' => false, + ]); + return Redirect::back()->withInput(Binput::all()) ->with('title', sprintf( '%s %s', @@ -213,6 +246,11 @@ public function editIncidentAction(Incident $incident) ->with('errors', $incident->getErrors()); } + segment_track('Dashboard', [ + 'event' => 'Edited Incident', + 'success' => true, + ]); + $successMsg = sprintf( '%s %s', trans('dashboard.notifications.awesome'), @@ -231,6 +269,10 @@ public function editIncidentAction(Incident $incident) */ public function editTemplateAction(IncidentTemplate $template) { + segment_track('Dashboard', [ + 'event' => 'Edited Incident Template', + ]); + $template->update(Binput::get('template')); return Redirect::back()->with('updatedTemplate', $template); diff --git a/src/Http/Controllers/DashTeamController.php b/src/Http/Controllers/DashTeamController.php index b3533a4f72c2..7f5041130730 100644 --- a/src/Http/Controllers/DashTeamController.php +++ b/src/Http/Controllers/DashTeamController.php @@ -60,6 +60,11 @@ public function postAddUser() $user = User::create(Binput::all()); if (! $user->isValid()) { + segment_track('Dashboard', [ + 'event' => 'Added User', + 'success' => false, + ]); + return Redirect::back()->withInput(Binput::except('password')) ->with('title', sprintf( '%s %s', @@ -69,6 +74,11 @@ public function postAddUser() ->with('errors', $user->getErrors()); } + segment_track('Dashboard', [ + 'event' => 'Added User', + 'success' => true, + ]); + $successMsg = sprintf( '%s %s', trans('dashboard.notifications.awesome'), @@ -98,6 +108,11 @@ public function postUpdateUser(User $user) $user->update($items); if (! $user->isValid()) { + segment_track('Dashboard', [ + 'event' => 'Updated User', + 'success' => false, + ]); + return Redirect::back()->withInput(Binput::except('password')) ->with('title', sprintf( '%s %s', @@ -107,6 +122,11 @@ public function postUpdateUser(User $user) ->with('errors', $user->getErrors()); } + segment_track('Dashboard', [ + 'event' => 'Updated User', + 'success' => true, + ]); + $successMsg = sprintf( '%s %s', trans('dashboard.notifications.awesome'), diff --git a/src/Http/Controllers/DashUserController.php b/src/Http/Controllers/DashUserController.php index bf95039bda08..a5a2c250596e 100644 --- a/src/Http/Controllers/DashUserController.php +++ b/src/Http/Controllers/DashUserController.php @@ -39,8 +39,18 @@ public function postUser() // Let's enable/disable auth if ($enable2FA && ! Auth::user()->hasTwoFactor) { $items['google_2fa_secret'] = Google2FA::generateSecretKey(); + + segment_track('User Management', [ + 'event' => 'enabled_two_factor', + 'value' => true, + ]); } elseif (! $enable2FA) { $items['google_2fa_secret'] = ''; + + segment_track('User Management', [ + 'event' => 'enabled_two_factor', + 'value' => false, + ]); } if (trim($passwordChange) === '') { @@ -76,6 +86,10 @@ public function postUser() */ public function regenerateApiKey(User $user) { + segment_track('User Management', [ + 'event' => 'regenrated_api_token' + ]); + $user->api_key = User::generateApiKey(); $user->save(); diff --git a/src/Http/Controllers/HomeController.php b/src/Http/Controllers/HomeController.php index bb9c20fd5939..bd25ec0ca912 100644 --- a/src/Http/Controllers/HomeController.php +++ b/src/Http/Controllers/HomeController.php @@ -21,6 +21,10 @@ class HomeController extends Controller */ public function showIndex() { + segment_track('Status Page', [ + 'event' => 'Landed', + ]); + $components = Component::orderBy('order')->orderBy('created_at')->get(); $allIncidents = []; @@ -37,6 +41,21 @@ public function showIndex() try { // If date provided is valid $oldDate = Date::createFromFormat('Y-m-d', Binput::get('start_date')); + + segment_track('Status Page', [ + 'start_date' => $oldDate->format('Y-m-d'), + ]); + + if (Setting::get('app_tracking')) { + Segment::track([ + 'userId' => Config::get('app.key'), + 'event' => 'Home Page', + 'properties' => [ + 'start_date' => $oldDate, + ], + ]); + } + // If trying to get a future date fallback to today if ($today->gt($oldDate)) { $startDate = $oldDate; diff --git a/src/Http/Controllers/SetupController.php b/src/Http/Controllers/SetupController.php index f2094375b48a..b1aae56c3c3f 100644 --- a/src/Http/Controllers/SetupController.php +++ b/src/Http/Controllers/SetupController.php @@ -47,6 +47,10 @@ public function postStep1() { $postData = Binput::all(); + segment_track('Setup', [ + 'step' => '1', + ]); + $v = Validator::make($postData, [ 'settings.app_name' => 'required', 'settings.app_domain' => 'required', @@ -72,6 +76,10 @@ public function postStep2() { $postData = Binput::all(); + segment_track('Setup', [ + 'step' => '2', + ]); + $v = Validator::make($postData, [ 'settings.app_name' => 'required', 'settings.app_domain' => 'required', diff --git a/src/helpers.php b/src/helpers.php index bed037f33bbd..16db12574212 100644 --- a/src/helpers.php +++ b/src/helpers.php @@ -1,5 +1,6 @@ Config::get('app.key'), + ]); + } else { + return false; + } + } +} + +if (!function_exists('segment_track')) { + /** + * Tracks events in Segment.com. + * + * @param string $event + * @param array $properties + * + * @return bool + */ + function segment_track($event, array $properties) + { + if (Setting::get('app_track')) { + segment_identify(Config::get('app.key')); + + return Segment::track([ + 'userId' => Config::get('app.key'), + 'event' => $event, + 'properties' => $properties, + ]); + } else { + return false; + } + } +} + +if (!function_exists('segment_page')) { + /** + * Tracks pages in Segment.com. + * + * @param string $name + * + * @return bool + */ + function segment_page($page) + { + if (Setting::get('app_track')) { + segment_identify(Config::get('app.key')); + + return Segment::page([ + 'userId' => Config::get('app.key'), + 'page' => $page, + ]); + } else { + return false; + } + } +}