From 81401617a1dde8d9bbb50c9bef1b5c95980670dd Mon Sep 17 00:00:00 2001 From: Jens Segers Date: Sun, 27 Jul 2014 12:52:23 +0200 Subject: [PATCH] Adding the export command --- README.md | 24 ++++++- composer.json | 5 +- src/Commands/ExportCommand.php | 114 +++++++++++++++++++++++++++++++++ src/TesterServiceProvider.php | 33 ++++++++-- tests/CommandTest.php | 23 +++++++ 5 files changed, 187 insertions(+), 12 deletions(-) create mode 100644 src/Commands/ExportCommand.php diff --git a/README.md b/README.md index 6bfb2cd..f56312d 100644 --- a/README.md +++ b/README.md @@ -114,13 +114,31 @@ This will generate a simple output containing the results for each experiment an | c | 173,073 | 5.0 % (8,653) | 1.0 % (1,730) | 1.3 % (5,538) | 3.2 % (5,538) | +------------+----------+----------------+---------------+---------------+---------------+ +You can also export these reports to .csv format using this command: + + php artisan ab:export /path/to/file.csv + +If you run that command without a filepath, it will write it to the console. + Advanced -------- -### AB::complete($goal) +***AB::pageview()** -Used to manually trigger goals. Useful when you want to track goals that are not linked to urls or routes. +Used to manually trigger an pageview. -### AB::interact() +***AB::interact()** Used to manually trigger an interaction which results in engagement. + +**AB::complete($goal)** + +Used to manually trigger goals. Useful when you want to track goals that are not linked to urls or routes. + +**AB::getExperiments()** + +Get the list of experiments. + +**AB::getGoals()** + +Get the list of goals. diff --git a/composer.json b/composer.json index f265be0..f58eeac 100644 --- a/composer.json +++ b/composer.json @@ -10,9 +10,10 @@ ], "license" : "MIT", "require": { - "php": ">=5.3.0", + "php": ">=5.4.0", "illuminate/support": "~4.0", - "pear/console_table": "*" + "pear/console_table": "*", + "league/csv": "5.*" }, "require-dev": { "orchestra/testbench": "2.2.*", diff --git a/src/Commands/ExportCommand.php b/src/Commands/ExportCommand.php new file mode 100644 index 0000000..416f495 --- /dev/null +++ b/src/Commands/ExportCommand.php @@ -0,0 +1,114 @@ +get(); + $goals = array_unique(Goal::active()->orderBy('name')->lists('name')); + + $columns = array_merge(['Experiment', 'Visitors', 'Engagement'], array_map('ucfirst', $goals)); + + $writer = new Writer(new SplTempFileObject); + $writer->setEncoding("utf-8"); + $writer->insertOne($columns); + + foreach ($experiments as $experiment) + { + $engagement = $experiment->visitors ? ($experiment->engagement / $experiment->visitors * 100) : 0; + + $row = [ + $experiment->name, + $experiment->visitors, + number_format($engagement, 2) . " % (" . $experiment->engagement .")", + ]; + + $results = $experiment->goals()->lists('count', 'name'); + + foreach ($goals as $column) + { + $count = array_get($results, $column, 0); + $percentage = $experiment->visitors ? ($count / $experiment->visitors * 100) : 0; + + $row[] = number_format($percentage, 2) . " % ($count)"; + } + + $writer->insertOne($row); + } + + $output = (string) $writer; + + if ($file = $this->argument('file')) + { + $this->info("Creating $file"); + + File::put($file, $output); + } + else + { + $this->line($output); + } + } + + /** + * Get the console command arguments. + * + * @return array + */ + protected function getArguments() + { + return array( + array('file', InputArgument::OPTIONAL, 'The target CSV file to write the output to.') + ); + } + + /** + * Get the console command options. + * + * @return array + */ + protected function getOptions() + { + return array(); + } + +} diff --git a/src/TesterServiceProvider.php b/src/TesterServiceProvider.php index 6fec2f6..b6672b7 100644 --- a/src/TesterServiceProvider.php +++ b/src/TesterServiceProvider.php @@ -2,9 +2,6 @@ use Jenssegers\AB\Session\LaravelSession; use Jenssegers\AB\Session\CookieSession; -use Jenssegers\AB\Commands\InstallCommand; -use Jenssegers\AB\Commands\FlushCommand; -use Jenssegers\AB\Commands\ReportCommand; use Illuminate\Support\ServiceProvider; @@ -46,11 +43,33 @@ public function register() return new Tester(new CookieSession); }); + $this->registerCommands(); + } + + /** + * Register Artisan commands. + * + * @return void + */ + protected function registerCommands() + { + // Available commands. + $commands = ['install', 'flush', 'report', 'export']; + + // Bind the command objects. + foreach ($commands as &$command) + { + $class = 'Jenssegers\\AB\\Commands\\' . ucfirst($command) . 'Command'; + $command = "ab::command.$class"; + + $this->app->bind($command, function($app) use ($class) + { + return new $class(); + }); + } + // Register artisan commands. - $this->app['ab.commands.install'] = new InstallCommand; - $this->app['ab.commands.flush'] = new FlushCommand; - $this->app['ab.commands.report'] = new ReportCommand; - $this->commands('ab.commands.install', 'ab.commands.flush', 'ab.commands.report'); + $this->commands($commands); } } diff --git a/tests/CommandTest.php b/tests/CommandTest.php index 0c73424..b1caf97 100644 --- a/tests/CommandTest.php +++ b/tests/CommandTest.php @@ -46,4 +46,27 @@ public function testReport() $this->assertContains('42', $report); } + public function testExport() + { + Artisan::call('ab:install'); + + Experiment::find('a')->update(['visitors' => 153, 'engagement' => 35]); + Goal::create(['name'=>'foo', 'experiment'=>'a', 'count'=>42]); + + $output = new Symfony\Component\Console\Output\BufferedOutput; + Artisan::call('ab:export', [], $output); + $report = $output->fetch(); + + $this->assertContains('Foo', $report); + $this->assertContains('153', $report); + $this->assertContains('35', $report); + $this->assertContains('42', $report); + + $output = new Symfony\Component\Console\Output\BufferedOutput; + Artisan::call('ab:export', ['file' => '/tmp/test.csv'], $output); + $report = $output->fetch(); + + $this->assertContains('Creating /tmp/test.csv', $report); + } + }