diff --git a/README.md b/README.md
index 20955ef..f13e42d 100644
--- a/README.md
+++ b/README.md
@@ -6,12 +6,27 @@
MailTracker will hook into all outgoing emails from Laravel/Lumen and inject a tracking code into it. It will also store the rendered email in the database. There is also an interface to view sent emails.
+## Upgrade from 1.x
+
+First, upgrade to version 2.0 by running:
+
+``` bash
+$ composer require jdavidbakr/mail-tracker ~2.0
+```
+
+Version 2.0 contains a new model that tracks the links that were clicked on. This requires a migration to create the table. There are also additional changes to the config file. For best results, make a backup copy of config/mail-tracker.php to restore any values you have customized, then delete that file and run
+
+``` bash
+$ php artisan vendor:publish
+$ php artisan migrate
+```
+
## Install (Laravel)
Via Composer
``` bash
-$ composer require jdavidbakr/mail-tracker
+$ composer require jdavidbakr/mail-tracker ~2.0
```
Add the following to the providers array in config/app.php:
@@ -22,7 +37,7 @@ jdavidbakr\MailTracker\MailTrackerServiceProvider::class,
Publish the config file and migration
``` bash
-$ php artisan vendor:publish
+$ php artisan vendor:publish --provider='jdavidbakr\MailTracker\MailTrackerServiceProvider'
```
Run the migration
@@ -35,7 +50,7 @@ $ php artisan migrate
Via Composer
``` bash
-$ composer require jdavidbakr/mail-tracker
+$ composer require jdavidbakr/mail-tracker ~2.0
```
Register the following service provider in bootstrap/app.php
@@ -55,11 +70,14 @@ $ php artisan migrate
Once installed, all outgoing mail will be logged to the database. The following config options are available in config/mail-tracker.php:
+* **name**: set your App Name.
* **inject-pixel**: set to true to inject a tracking pixel into all outgoing html emails.
* **track-links**: set to true to rewrite all anchor href links to include a tracking link. The link will take the user back to your website which will then redirect them to the final destination after logging the click.
* **expire-days**: How long in days that an email should be retained in your database. If you are sending a lot of mail, you probably want it to eventually expire. Set it to zero to never purge old emails from the database.
* **route**: The route information for the tracking URLs. Set the prefix and middlware as desired.
-* **admin-route**: The route information for the admin. Set the prefix and middleware. *Note that this is not yet built.*
+* **admin-route**: The route information for the admin. Set the prefix and middleware.
+* **admin-template**: The params for the Admin Panel and Views. You can integrate your existing Admin Panel with the MailTracker admin panel.
+* **date-format**: You can define the format to show dates in the Admin Panel.
## Events
@@ -116,10 +134,18 @@ protected $listen = [
],
];
```
+## Views
+
+When you do the php artisan vendor:publish simple views will add to your resources/views/vendor/emailTrakingViews and you can customize.
-## TODO
+## Admin Panel
-Currently this plugin is only tracking the outgoing mail. There is no view yet to explore the existing data.
+Config your admin-route in the config file. Set the prefix and middlware.
+The route name is 'mailTracker_Index'. The standard admin panel route is located at /email-manager.
+You can use route names to include them into your existing admin menu.
+You can customize your route in the config file.
+You can see all sent emails, total opens, total urls clicks, show individuals emails and show the urls clicked details.
+All views (email tamplates, panel) can be customized in resources/views/vendor/emailTrakingViews.
## Contributing
diff --git a/config/mail-tracker.php b/config/mail-tracker.php
index c9b559c..aa234f9 100644
--- a/config/mail-tracker.php
+++ b/config/mail-tracker.php
@@ -1,27 +1,27 @@
true,
-
- /**
- * To disable injecting tracking links, set this to false.
- */
- 'track-links'=>true,
-
- /**
- * Optionally expire old emails, set to 0 to keep forever.
- */
- 'expire-days'=>60,
-
- /**
- * Where should the pingback URL route be?
- */
+ /**
+ * To disable the pixel injection, set this to false.
+ */
+ 'inject-pixel'=>true,
+
+ /**
+ * To disable injecting tracking links, set this to false.
+ */
+ 'track-links'=>true,
+
+ /**
+ * Optionally expire old emails, set to 0 to keep forever.
+ */
+ 'expire-days'=>60,
+
+ /**
+ * Where should the pingback URL route be?
+ */
'route' => [
'prefix' => 'email',
- 'middleware' => [],
+ 'middleware' => ['web'],
],
/**
@@ -29,7 +29,29 @@
*/
'admin-route' => [
'prefix' => 'email-manager',
- 'middleware' => 'super',
+ 'middleware' => ['web'],
],
+ /**
+ * Admin Tamplate
+ * example
+ * 'name' => 'layouts.app' for Default emailTraking use 'emailTrakingViews::layouts.app'
+ * 'section' => 'content' for Default emailTraking use 'content'
+ * 'styles_section' => 'styles' for Default emailTraking use 'styles'
+ */
+ 'admin-template' => [
+ 'name' => 'emailTrakingViews::layouts.app',
+ 'section' => 'content',
+ ],
+
+ /**
+ * Number of emails per page in the admin view
+ */
+ 'emails-per-page'=>5,
+
+ /**
+ * Date Format
+ */
+ 'date-format' => 'm/d/Y g:i a',
+
];
diff --git a/migrations/2016_03_01_193027_create_sent_emails_table.php b/migrations/2016_03_01_193027_create_sent_emails_table.php
index 96daa7a..35b1194 100644
--- a/migrations/2016_03_01_193027_create_sent_emails_table.php
+++ b/migrations/2016_03_01_193027_create_sent_emails_table.php
@@ -14,7 +14,6 @@ public function up()
{
Schema::create('sent_emails', function (Blueprint $table) {
$table->increments('id');
- $table->timestamps();
$table->char('hash',32)->unique();
$table->text('headers');
$table->string('sender');
@@ -23,6 +22,7 @@ public function up()
$table->text('content');
$table->integer('opens');
$table->integer('clicks');
+ $table->timestamps();
});
}
diff --git a/migrations/2016_09_07_193027_create_sent_emails_Url_Clicked_table.php b/migrations/2016_09_07_193027_create_sent_emails_Url_Clicked_table.php
new file mode 100644
index 0000000..1b161b0
--- /dev/null
+++ b/migrations/2016_09_07_193027_create_sent_emails_Url_Clicked_table.php
@@ -0,0 +1,35 @@
+increments('id');
+ $table->integer('sent_email_id')->unsigned();
+ $table->foreign('sent_email_id')->references('id')->on('sent_emails')->onDelete('cascade');
+ $table->string('url');
+ $table->char('hash',32);
+ $table->integer('clicks')->default('1');
+ $table->timestamps();
+ });
+ }
+
+ /**
+ * Reverse the migrations.
+ *
+ * @return void
+ */
+ public function down()
+ {
+ Schema::drop('sent_emails_url_clicked');
+ }
+}
diff --git a/src/AdminController.php b/src/AdminController.php
new file mode 100644
index 0000000..bfae571
--- /dev/null
+++ b/src/AdminController.php
@@ -0,0 +1,86 @@
+$request->search]);
+ return redirect(route('mailTracker_Index'));
+ }
+
+ /**
+ * Clear search
+ */
+ public function clearSearch()
+ {
+ session(['mail-tracker-index-search'=>null]);
+ return redirect(route('mailTracker_Index'));
+ }
+
+ /**
+ * Index.
+ *
+ * @return \Illuminate\Http\Response
+ */
+ public function getIndex()
+ {
+ session(['mail-tracker-index-page'=>request()->page]);
+ $search = session('mail-tracker-index-search');
+
+ $query = SentEmail::query();
+
+ if($search) {
+ $terms = explode(" ",$search);
+ foreach($terms as $term) {
+ $query->where(function($q) use($term) {
+ $q->where('sender','like','%'.$term.'%')
+ ->orWhere('recipient','like','%'.$term.'%')
+ ->orWhere('subject','like','%'.$term.'%');
+ });
+ }
+ }
+
+ $emails = $query->paginate(config('mail-tracker.emails-per-page'));
+
+ return \View('emailTrakingViews::index')->with('emails', $emails);
+ }
+
+ /**
+ * Show Email.
+ *
+ * @return \Illuminate\Http\Response
+ */
+ public function getShowEmail($id)
+ {
+ $email = SentEmail::where('id',$id)->first();
+ return \View('emailTrakingViews::show')->with('email', $email);
+ }
+
+ /**
+ * Url Detail.
+ *
+ * @return \Illuminate\Http\Response
+ */
+ public function getUrlDetail($id)
+ {
+ $detalle = SentEmailUrlClicked::where('sent_email_id',$id)->get();
+ return \View('emailTrakingViews::url_detail')->with('details', $detalle);
+ }
+}
diff --git a/src/MailTrackerController.php b/src/MailTrackerController.php
index f99107d..f84fcd7 100644
--- a/src/MailTrackerController.php
+++ b/src/MailTrackerController.php
@@ -45,6 +45,17 @@ public function getL($url, $hash)
if($tracker) {
$tracker->clicks++;
$tracker->save();
+ $url_clicked = Model\SentEmailUrlClicked::where('url',$url)->where('hash', $hash)->first();
+ if ($url_clicked) {
+ $url_clicked->clicks++;
+ $url_clicked->save();
+ } else {
+ $url_clicked = Model\SentEmailUrlClicked::create([
+ 'sent_email_id' => $tracker->id,
+ 'url' => $url,
+ 'hash' => $tracker->hash,
+ ]);
+ }
Event::fire(new LinkClickedEvent($tracker));
}
diff --git a/src/MailTrackerServiceProvider.php b/src/MailTrackerServiceProvider.php
index 42e31ad..8dc006d 100644
--- a/src/MailTrackerServiceProvider.php
+++ b/src/MailTrackerServiceProvider.php
@@ -9,10 +9,10 @@ class MailTrackerServiceProvider extends ServiceProvider
{
/**
* Check to see if we're using lumen or laravel.
- *
+ *
* @return bool
*/
- public function isLumen()
+ public function isLumen()
{
$lumenClass = 'Laravel\Lumen\Application';
return ($this->app instanceof $lumenClass);
@@ -33,6 +33,13 @@ public function boot()
$this->publishes([
__DIR__.'/../migrations/2016_03_01_193027_create_sent_emails_table.php' => database_path('migrations/2016_03_01_193027_create_sent_emails_table.php')
], 'config');
+ $this->publishes([
+ __DIR__.'/../migrations/2016_09_07_193027_create_sent_emails_Url_Clicked_table.php' => database_path('migrations/2016_09_07_193027_create_sent_emails_Url_Clicked_table.php')
+ ], 'config');
+ $this->loadViewsFrom(__DIR__.'/views', 'emailTrakingViews');
+ $this->publishes([
+ __DIR__.'/views' => base_path('resources/views/vendor/emailTrakingViews'),
+ ]);
}
// Hook into the mailer
@@ -45,14 +52,39 @@ public function boot()
if (!$this->isLumen()) {
Route::group($config, function()
{
- Route::get('t/{hash}', 'MailTrackerController@getT');
- Route::get('l/{url}/{hash}', 'MailTrackerController@getL');
+ Route::get('t/{hash}', 'MailTrackerController@getT')->name('mailTracker_t');
+ Route::get('l/{url}/{hash}', 'MailTrackerController@getL')->name('mailTracker_l');
});
} else {
$app = $this->app;
$app->group($config, function () use ($app) {
- $app->get('t', 'MailTrackerController@getT');
- $app->get('l', 'MailTrackerController@getL');
+ $app->get('t', 'MailTrackerController@getT')->name('mailTracker_t');
+ $app->get('l', 'MailTrackerController@getL')->name('mailTracker_l');
+ });
+ }
+ // Install the Admin routes
+ $config_admin = $this->app['config']->get('mail-tracker.admin-route', []);
+ $config_admin['namespace'] = 'jdavidbakr\MailTracker';
+
+ if (!$this->isLumen()) {
+ Route::group($config_admin, function()
+ {
+ Route::get('/', 'AdminController@getIndex')->name('mailTracker_Index');
+ Route::post('search', 'AdminController@postSearch')->name('mailTracker_Search');
+ Route::get('clear-search', 'AdminController@clearSearch')->name('mailTracker_ClearSearch');
+ Route::get('show-email/{id}', 'AdminController@getShowEmail')->name('mailTracker_ShowEmail');
+ Route::get('url-detail/{id}', 'AdminController@getUrlDetail')->name('mailTracker_UrlDetail');
+ Route::get('send-email', 'AdminController@getSendEmail')->name('mailTracker_SendEmail');
+ });
+ } else {
+ $app = $this->app;
+ $app->group($config_admin, function () use ($app) {
+ $app->get('/', 'AdminController@getIndex')->name('mailTracker_Index');
+ $app->post('search', 'AdminController@postSearch')->name('mailTracker_Search');
+ $app->get('clear-search', 'AdminController@clearSearch')->name('mailTracker_ClearSearch');
+ $app->get('show-email/{id}', 'AdminController@getShowEmail')->name('mailTracker_ShowEmail');
+ $app->get('url-detail/{id}', 'AdminController@getUrlDetail')->name('mailTracker_UrlDetail');
+ $app->get('send-email', 'AdminController@getSendEmail')->name('mailTracker_SendEmail');
});
}
}
diff --git a/src/Model/SentEmailUrlClicked.php b/src/Model/SentEmailUrlClicked.php
new file mode 100644
index 0000000..d5bea01
--- /dev/null
+++ b/src/Model/SentEmailUrlClicked.php
@@ -0,0 +1,23 @@
+belongsTo(SentEmail::class,'sent_email_id');
+ }
+}
diff --git a/src/views/emails/mensaje.blade.php b/src/views/emails/mensaje.blade.php
new file mode 100644
index 0000000..1e4dd69
--- /dev/null
+++ b/src/views/emails/mensaje.blade.php
@@ -0,0 +1,30 @@
+@extends('emailTrakingViews::emails/mensaje_layout')
+@section('title')
+ Message from {{config('mail-tracker.name')}}
+@endsection
+
+@section('preheader')
+ Message from {{config('mail-tracker.name')}}
+@endsection
+@section('nombre_destinatario')
+ {{ $data['name'] }}
+@endsection
+@section('mensaje')
+
Static Email Title
+
+ Static Email Content
+
+ {{ $data['message'] }}
+@endsection
+@section('href_call_to_action')
+ {{env('APP_URL')}}
+@endsection
+@section('txt_call_to_action')
+ Call To Action
+@endsection
+@section('txt_extra')
+ This email comes from {{config('mail-tracker.name')}}
+@endsection
+@section('saludo_final')
+ Regards
+@endsection
diff --git a/src/views/emails/mensaje_layout.blade.php b/src/views/emails/mensaje_layout.blade.php
new file mode 100644
index 0000000..1d1f0c4
--- /dev/null
+++ b/src/views/emails/mensaje_layout.blade.php
@@ -0,0 +1,195 @@
+
+
+
+
+
+ @yield('title')
+
+
+
+
+
+
+
+
+
+
+
+ @yield('preheader')
+ {{--This is preheader text. Some clients will show this text as a preview.--}}
+
+