diff --git a/src/Symfony/Bundle/WebProfilerBundle/Command/ExportCommand.php b/src/Symfony/Bundle/WebProfilerBundle/Command/ExportCommand.php new file mode 100644 index 0000000000..b140e302b1 --- /dev/null +++ b/src/Symfony/Bundle/WebProfilerBundle/Command/ExportCommand.php @@ -0,0 +1,75 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Bundle\WebProfilerBundle\Command; + +use Symfony\Component\Console\Command\Command; +use Symfony\Component\Console\Input\InputArgument; +use Symfony\Component\Console\Input\InputInterface; +use Symfony\Component\Console\Output\OutputInterface; +use Symfony\Component\HttpKernel\Profiler\Profiler; + +/** + * Exports a profile. + * + * @author Fabien Potencier + */ +class ExportCommand extends Command +{ + private $profiler; + + public function __construct(Profiler $profiler = null) + { + $this->profiler = $profiler; + + parent::__construct(); + } + + /** + * {@inheritdoc} + */ + public function isEnabled() + { + if (null === $this->profiler) { + return false; + } + + return parent::isEnabled(); + } + + protected function configure() + { + $this + ->setName('profiler:export') + ->setDescription('Exports a profile') + ->setDefinition(array( + new InputArgument('token', InputArgument::REQUIRED, 'The profile token'), + )) + ->setHelp(<<%command.name% command exports a profile to the standard output: + +php %command.full_name% profile_token +EOF + ) + ; + } + + protected function execute(InputInterface $input, OutputInterface $output) + { + $token = $input->getArgument('token'); + + if (!$profile = $this->profiler->loadProfile($token)) { + throw new \LogicException(sprintf('Profile with token "%s" does not exist.', $token)); + } + + $output->writeln($this->profiler->export($profile), OutputInterface::OUTPUT_RAW); + } +} diff --git a/src/Symfony/Bundle/WebProfilerBundle/Command/ImportCommand.php b/src/Symfony/Bundle/WebProfilerBundle/Command/ImportCommand.php new file mode 100644 index 0000000000..70fecd45ea --- /dev/null +++ b/src/Symfony/Bundle/WebProfilerBundle/Command/ImportCommand.php @@ -0,0 +1,90 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Bundle\WebProfilerBundle\Command; + +use Symfony\Component\Console\Command\Command; +use Symfony\Component\Console\Input\InputArgument; +use Symfony\Component\Console\Input\InputInterface; +use Symfony\Component\Console\Output\OutputInterface; +use Symfony\Component\HttpKernel\Profiler\Profiler; + +/** + * Imports a profile. + * + * @author Fabien Potencier + */ +class ImportCommand extends Command +{ + private $profiler; + + public function __construct(Profiler $profiler = null) + { + $this->profiler = $profiler; + + parent::__construct(); + } + + /** + * {@inheritdoc} + */ + public function isEnabled() + { + if (null === $this->profiler) { + return false; + } + + return parent::isEnabled(); + } + + protected function configure() + { + $this + ->setName('profiler:import') + ->setDescription('Imports a profile') + ->setDefinition(array( + new InputArgument('filename', InputArgument::OPTIONAL, 'The profile path'), + )) + ->setHelp(<<%command.name% command imports a profile: + +php %command.full_name% profile_filepath + +You can also pipe the profile via STDIN: + +cat profile_file | php %command.full_name% +EOF + ) + ; + } + + protected function execute(InputInterface $input, OutputInterface $output) + { + $data = ''; + if ($input->getArgument('filename')) { + $data = file_get_contents($input->getArgument('filename')); + } else { + if (0 !== ftell(STDIN)) { + throw new \RuntimeException('Please provide a filename or pipe the profile to STDIN.'); + } + + while (!feof(STDIN)) { + $data .= fread(STDIN, 1024); + } + } + + if (!$profile = $this->profiler->import($data)) { + throw new \LogicException('The profile already exists in the database.'); + } + + $output->writeln(sprintf('Profile "%s" has been successfully imported.', $profile->getToken())); + } +} diff --git a/src/Symfony/Bundle/WebProfilerBundle/Controller/ProfilerController.php b/src/Symfony/Bundle/WebProfilerBundle/Controller/ProfilerController.php index 8542f2865f..dea4f8883f 100644 --- a/src/Symfony/Bundle/WebProfilerBundle/Controller/ProfilerController.php +++ b/src/Symfony/Bundle/WebProfilerBundle/Controller/ProfilerController.php @@ -111,33 +111,6 @@ class ProfilerController )), 200, array('Content-Type' => 'text/html')); } - /** - * Exports data for a given token. - * - * @param string $token The profiler token - * - * @return Response A Response instance - * - * @throws NotFoundHttpException - */ - public function exportAction($token) - { - if (null === $this->profiler) { - throw new NotFoundHttpException('The profiler must be enabled.'); - } - - $this->profiler->disable(); - - if (!$profile = $this->profiler->loadProfile($token)) { - throw new NotFoundHttpException(sprintf('Token "%s" does not exist.', $token)); - } - - return new Response($this->profiler->export($profile), 200, array( - 'Content-Type' => 'text/plain', - 'Content-Disposition' => 'attachment; filename= '.$token.'.txt', - )); - } - /** * Purges all tokens. * @@ -157,36 +130,6 @@ class ProfilerController return new RedirectResponse($this->generator->generate('_profiler_info', array('about' => 'purge')), 302, array('Content-Type' => 'text/html')); } - /** - * Imports token data. - * - * @param Request $request The current HTTP Request - * - * @return Response A Response instance - * - * @throws NotFoundHttpException - */ - public function importAction(Request $request) - { - if (null === $this->profiler) { - throw new NotFoundHttpException('The profiler must be enabled.'); - } - - $this->profiler->disable(); - - $file = $request->files->get('file'); - - if (empty($file) || !$file->isValid()) { - return new RedirectResponse($this->generator->generate('_profiler_info', array('about' => 'upload_error')), 302, array('Content-Type' => 'text/html')); - } - - if (!$profile = $this->profiler->import(file_get_contents($file->getPathname()))) { - return new RedirectResponse($this->generator->generate('_profiler_info', array('about' => 'already_exists')), 302, array('Content-Type' => 'text/html')); - } - - return new RedirectResponse($this->generator->generate('_profiler', array('token' => $profile->getToken())), 302, array('Content-Type' => 'text/html')); - } - /** * Displays information page. * diff --git a/src/Symfony/Bundle/WebProfilerBundle/Resources/config/commands.xml b/src/Symfony/Bundle/WebProfilerBundle/Resources/config/commands.xml new file mode 100644 index 0000000000..d85b54d38d --- /dev/null +++ b/src/Symfony/Bundle/WebProfilerBundle/Resources/config/commands.xml @@ -0,0 +1,23 @@ + + + + + + Symfony\Bundle\WebProfilerBundle\Command\ImportCommand + Symfony\Bundle\WebProfilerBundle\Command\ExportCommand + + + + + + + + + + + + + + diff --git a/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Profiler/admin.html.twig b/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Profiler/admin.html.twig index 3ca28ff162..a47b254a77 100644 --- a/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Profiler/admin.html.twig +++ b/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Profiler/admin.html.twig @@ -1,27 +1,10 @@ - +{% endif %} diff --git a/src/Symfony/Bundle/WebProfilerBundle/Tests/Command/ExportCommandTest.php b/src/Symfony/Bundle/WebProfilerBundle/Tests/Command/ExportCommandTest.php new file mode 100644 index 0000000000..572e9b3978 --- /dev/null +++ b/src/Symfony/Bundle/WebProfilerBundle/Tests/Command/ExportCommandTest.php @@ -0,0 +1,53 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Bundle\WebProfilerBundle\Tests\Command; + +use Symfony\Bundle\WebProfilerBundle\Command\ExportCommand; +use Symfony\Component\Console\Tester\CommandTester; +use Symfony\Component\Console\Application; +use Symfony\Component\HttpKernel\Profiler\Profile; + +class ExportCommandTest extends \PHPUnit_Framework_TestCase +{ + /** + * @expectedException \LogicException + */ + public function testExecuteWithUnknownToken() + { + $profiler = $this + ->getMockBuilder('Symfony\Component\HttpKernel\Profiler\Profiler') + ->disableOriginalConstructor() + ->getMock() + ; + + $command = new ExportCommand($profiler); + $commandTester = new CommandTester($command); + $commandTester->execute(array('token' => 'TOKEN')); + } + + public function testExecuteWithToken() + { + $profiler = $this + ->getMockBuilder('Symfony\Component\HttpKernel\Profiler\Profiler') + ->disableOriginalConstructor() + ->getMock() + ; + + $profile = new Profile('TOKEN'); + $profiler->expects($this->once())->method('loadProfile')->with('TOKEN')->will($this->returnValue($profile)); + + $command = new ExportCommand($profiler); + $commandTester = new CommandTester($command); + $commandTester->execute(array('token' => 'TOKEN')); + $this->assertEquals($profiler->export($profile), $commandTester->getDisplay()); + } +} diff --git a/src/Symfony/Bundle/WebProfilerBundle/Tests/Command/ImportCommandTest.php b/src/Symfony/Bundle/WebProfilerBundle/Tests/Command/ImportCommandTest.php new file mode 100644 index 0000000000..f5121c12d6 --- /dev/null +++ b/src/Symfony/Bundle/WebProfilerBundle/Tests/Command/ImportCommandTest.php @@ -0,0 +1,36 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Bundle\WebProfilerBundle\Tests\Command; + +use Symfony\Bundle\WebProfilerBundle\Command\ImportCommand; +use Symfony\Component\Console\Tester\CommandTester; +use Symfony\Component\Console\Application; +use Symfony\Component\HttpKernel\Profiler\Profile; + +class ImportCommandTest extends \PHPUnit_Framework_TestCase +{ + public function testExecute() + { + $profiler = $this + ->getMockBuilder('Symfony\Component\HttpKernel\Profiler\Profiler') + ->disableOriginalConstructor() + ->getMock() + ; + + $profiler->expects($this->once())->method('import')->will($this->returnValue(new Profile('TOKEN'))); + + $command = new ImportCommand($profiler); + $commandTester = new CommandTester($command); + $commandTester->execute(array('filename' => __DIR__.'/../Fixtures/profile.data')); + $this->assertRegExp('/Profile "TOKEN" has been successfully imported\./', $commandTester->getDisplay()); + } +} diff --git a/src/Symfony/Bundle/WebProfilerBundle/Tests/Fixtures/profile.data b/src/Symfony/Bundle/WebProfilerBundle/Tests/Fixtures/profile.data new file mode 100644 index 0000000000..ab76cea63d --- /dev/null +++ b/src/Symfony/Bundle/WebProfilerBundle/Tests/Fixtures/profile.data @@ -0,0 +1 @@ +Tzo0NToiU3ltZm9ueVxDb21wb25lbnRcSHR0cEtlcm5lbFxQcm9maWxlclxQcm9maWxlIjo4OntzOjUyOiIAU3ltZm9ueVxDb21wb25lbnRcSHR0cEtlcm5lbFxQcm9maWxlclxQcm9maWxlAHRva2VuIjtzOjU6IlRPS0VOIjtzOjUzOiIAU3ltZm9ueVxDb21wb25lbnRcSHR0cEtlcm5lbFxQcm9maWxlclxQcm9maWxlAHBhcmVudCI7TjtzOjU1OiIAU3ltZm9ueVxDb21wb25lbnRcSHR0cEtlcm5lbFxQcm9maWxlclxQcm9maWxlAGNoaWxkcmVuIjthOjA6e31zOjU3OiIAU3ltZm9ueVxDb21wb25lbnRcSHR0cEtlcm5lbFxQcm9maWxlclxQcm9maWxlAGNvbGxlY3RvcnMiO2E6MDp7fXM6NDk6IgBTeW1mb255XENvbXBvbmVudFxIdHRwS2VybmVsXFByb2ZpbGVyXFByb2ZpbGUAaXAiO047czo1MzoiAFN5bWZvbnlcQ29tcG9uZW50XEh0dHBLZXJuZWxcUHJvZmlsZXJcUHJvZmlsZQBtZXRob2QiO047czo1MDoiAFN5bWZvbnlcQ29tcG9uZW50XEh0dHBLZXJuZWxcUHJvZmlsZXJcUHJvZmlsZQB1cmwiO047czo1MToiAFN5bWZvbnlcQ29tcG9uZW50XEh0dHBLZXJuZWxcUHJvZmlsZXJcUHJvZmlsZQB0aW1lIjtOO30= \ No newline at end of file