diff options
author | minstel <minstel@yandex.ru> | 2016-10-25 14:46:05 +0300 |
---|---|---|
committer | minstel <minstel@yandex.ru> | 2016-10-25 14:46:05 +0300 |
commit | b8540d92944123d15559f9033f523f9f6c5126ec (patch) | |
tree | 92d5e71c1e4d54a7727b29ae18f44f09965cad2a | |
parent | 34d3ddc178ca066fc534ceec7f37e393813d22fc (diff) | |
download | controller-b8540d92944123d15559f9033f523f9f6c5126ec.zip controller-b8540d92944123d15559f9033f523f9f6c5126ec.tar.gz controller-b8540d92944123d15559f9033f523f9f6c5126ec.tar.bz2 |
Flash
-rw-r--r-- | src/Controller.php | 21 | ||||
-rw-r--r-- | src/Flash.php | 109 | ||||
-rw-r--r-- | src/View/Twig.php | 11 | ||||
-rw-r--r-- | tests/ControllerTest.php | 38 | ||||
-rw-r--r-- | tests/FlashTest.php | 147 | ||||
-rw-r--r-- | tests/View/TwigTest.php | 10 |
6 files changed, 330 insertions, 6 deletions
diff --git a/src/Controller.php b/src/Controller.php index ddec2c0..f7ea6f3 100644 --- a/src/Controller.php +++ b/src/Controller.php @@ -23,6 +23,12 @@ abstract class Controller protected $response = null; /** + * Flash + * @var Flash + **/ + protected $flash = null; + + /** * Run the controller * * @return ResponseInterface @@ -65,6 +71,21 @@ abstract class Controller } /** + * Set the flash message and/or return the flash object. + * + * @param mixed $type flash type, eg. 'error', 'notice' or 'success' + * @param mixed $message flash message + * @return Flash + */ + public function flash($type = null, $message = null) + { + if (!isset($this->flash)) $this->flash = new Flash(); + if ($type && $message) $this->flash->set($type, $message); + + return $this->flash; + } + + /** * Check if response is 2xx succesful, or empty * * @return boolean diff --git a/src/Flash.php b/src/Flash.php new file mode 100644 index 0000000..ad060f9 --- /dev/null +++ b/src/Flash.php @@ -0,0 +1,109 @@ +<?php + +namespace Jasny; + +/** + * Class for the flash message + */ +class Flash +{ + /** + * @var object + */ + protected static $data = null; + + /** + * Check if the flash is set. + * + * @return boolean + */ + public static function isIssued() + { + return isset($_SESSION['flash']) || isset(static::$data); + } + + /** + * Set the flash. + * + * @param mixed $type flash type, eg. 'error', 'notice' or 'success' + * @param mixed $message flash message + */ + public static function set($type, $message) + { + if (!$type) { + throw new \InvalidArgumentException("Type should not be empty"); + } + + static::$data = (object)['type'=>$type, 'message'=>$message]; + + $_SESSION['flash'] = static::$data; + } + + /** + * Get the flash. + * + * @return object + */ + public static function get() + { + if (!isset(static::$data) && isset($_SESSION['flash'])) { + static::$data = (object)$_SESSION['flash']; + unset($_SESSION['flash']); + } + + return static::$data; + } + + /** + * Reissue the flash. + */ + public static function reissue() + { + if (!isset(static::$data) && isset($_SESSION['flash'])) { + static::$data = (object)$_SESSION['flash']; + } else { + $_SESSION['flash'] = static::$data; + } + } + + /** + * Clear the flash. + */ + public static function clear() + { + self::$data = null; + unset($_SESSION['flash']); + } + + /** + * Get the flash type + * + * @return string + */ + public static function getType() + { + $data = static::get(); + return isset($data) ? $data->type : null; + } + + /** + * Get the flash message + * + * @return string + */ + public static function getMessage() + { + $data = static::get(); + return isset($data) ? $data->message : null; + } + + /** + * Cast object to string + * + * @return string + */ + public function __toString() + { + return (string)$this->getMessage(); + } +} diff --git a/src/View/Twig.php b/src/View/Twig.php index 6d0f6ae..ee5d4ce 100644 --- a/src/View/Twig.php +++ b/src/View/Twig.php @@ -2,6 +2,7 @@ namespace Jasny\Controller\View; +use Jasny\Flash; use Psr\Http\Message\ServerRequestInterface; use Psr\Http\Message\ResponseInterface; @@ -47,8 +48,8 @@ trait Twig /** * Expose a function to the view. * - * @param string $function Variable name - * @param mixed $callback + * @param string $name Variable name + * @param mixed $function * @param string $as 'function' or 'filter' * @return $this */ @@ -119,7 +120,9 @@ trait Twig } $uri = $this->getRequest()->getUri()->getPath(); + $this->setViewVariable('current_url', $uri); + $this->setViewVariable('flash', new Flash()); return $this->twig; } @@ -149,7 +152,7 @@ trait Twig * Create twig function * * @param string $name Name of function in view - * @param callable $function + * @param callable|null $function * @return \Twig_SimpleFunction */ public function createTwigFunction($name, $function) @@ -163,7 +166,7 @@ trait Twig * Create twig filter * * @param string $name Name of filter in view - * @param callable $function + * @param callable|null $function * @return \Twig_SimpleFilter */ public function createTwigFilter($name, $function) diff --git a/tests/ControllerTest.php b/tests/ControllerTest.php index 8cdbf7d..5db4117 100644 --- a/tests/ControllerTest.php +++ b/tests/ControllerTest.php @@ -1,6 +1,7 @@ <?php use Jasny\Controller; +use Jasny\Flash; use Psr\Http\Message\ServerRequestInterface; use Psr\Http\Message\ResponseInterface; @@ -76,6 +77,43 @@ class ControllerTest extends PHPUnit_Framework_TestCase } /** + * Test setting flash + * + * @dataProvider flashProvider + * @param object $data + */ + public function testFlash($data) + { + $controller = $this->getMockBuilder(Controller::class)->disableOriginalConstructor()->getMockForAbstractClass(); + + $flash = $controller->flash(); + $this->assertInstanceOf(Flash::class, $flash, "Flash is not set"); + $this->assertEmpty($flash->get(), "Flash data should be empty"); + + $flash = $controller->flash($data->type, $data->message); + $this->assertInstanceOf(Flash::class, $flash, "Flash is not set"); + $this->assertEquals($data, $flash->get(), "Flash data is incorrect"); + + $flash = $controller->flash(); + $this->assertInstanceOf(Flash::class, $flash, "Flash is not set"); + $this->assertEquals($data, $flash->get(), "Flash data is incorrect"); + + $flash->clear(); + } + + /** + * Test setting flash + * + * @return array + */ + public function flashProvider() + { + return [ + [(object)['type' => 'test_type', 'message' => 'Test message']] + ]; + } + + /** * Get map of status codes to states * * @param int $code diff --git a/tests/FlashTest.php b/tests/FlashTest.php new file mode 100644 index 0000000..c17c446 --- /dev/null +++ b/tests/FlashTest.php @@ -0,0 +1,147 @@ +<?php + +use Jasny\Flash; + +/** + * @covers Jasny\Flash + */ +class FlashTest extends PHPUnit_Framework_TestCase +{ + /** + * Test flash + * + * @dataProvider flashProvider + * @param object $data + */ + public function testFlash($data) + { + $flash = new Flash(); + $this->assertFlashEmpty($flash); + + //Set flash + $flash->set($data->type, $data->message); + $this->assertFlashDataCorrect($flash, $data); + $this->assertFlashIsIssued($flash, $data); + + //Get data + $setData = $flash->get(); + $this->assertFlashDataCorrect($flash, $data); + $this->assertFlashIsIssued($flash, $data); + $this->assertEquals($data, $setData, "Flash data was not got correctly"); + + //Clear + $flash->clear(); + $this->assertFlashEmpty($flash); + + //Set from session + $_SESSION['flash'] = $data; + $this->assertFlashIsIssued($flash, $data); + + //When flash is set only in session, not by 'set' method, then getting it's data removes flash from session, so they only remain in flash object + $this->assertFlashDataCorrect($flash, $data); + $this->assertFalse(isset($_SESSION['flash']), "Session flash variable should be empty"); + $this->assertTrue($flash->isIssued(), "Flash should be issued"); + + //Clear + $flash->clear(); + $this->assertFlashEmpty($flash); + + //Reissue from session + $_SESSION['flash'] = $data; + $flash->reissue(); + + $this->assertFlashDataCorrect($flash, $data); + $this->assertFlashIsIssued($flash, $data); + + //Reissue from object data + unset($_SESSION['flash']); + $flash->reissue(); + + $this->assertFlashDataCorrect($flash, $data); + $this->assertFlashIsIssued($flash, $data); + + //Clear + $flash->clear(); + $this->assertFlashEmpty($flash); + } + + /** + * Provide data for testing flash + * + * @return array + */ + public function flashProvider() + { + return [ + [(object)['type' => 'test_type', 'message' => 'Test message']], + [(object)['type' => 'test_type', 'message' => '']] + ]; + } + + /** + * Test 'set' method with wrong params + * + * @dataProvider setNegativeProvider + * @param object $data + */ + public function testSetNegative($data) + { + $flash = new Flash(); + + $this->expectException(InvalidArgumentException::class); + + $flash->set($data->type, $data->message); + } + + /** + * Provide data for testing wrong set + * + * @return array + */ + public function setNegativeProvider() + { + return [ + [(object)['type' => '', 'message' => 'Test message']] + ]; + } + + /** + * Assert that flash is not set + * + * @param Flash $flash + */ + public function assertFlashEmpty($flash) + { + $this->assertFalse(isset($_SESSION['flash']), "Session flash variable should be empty"); + $this->assertFalse($flash->isIssued(), "Flash should not be issued"); + $this->assertEmpty($flash->get(), "Flash should be empty"); + $this->assertEmpty($flash->getType(), "Flash type should not be set"); + $this->assertEmpty($flash->getMessage(), "Message should be empty"); + $this->assertEmpty((string)$flash, "Flash should be empty"); + } + + /** + * Assert that flash is issued + * + * @param Flash $flash + * @param object $data + */ + public function assertFlashIsIssued($flash, $data) + { + $this->assertEquals($data, $_SESSION['flash'], "Flash data was not set correctly"); + $this->assertTrue($flash->isIssued(), "Flash should be issued"); + } + + /** + * Assert that flash data is correct + * + * @param Flash $flash + * @param object $data + */ + public function assertFlashDataCorrect($flash, $data) + { + $this->assertEquals($data->type, $flash->getType(), "Type was not got correctly"); + $this->assertEquals($data->message, $flash->getMessage(), "Message was not got correctly"); + $this->assertEquals($data->message, (string)$flash, "Message was not got correctly when presenting flash as string"); + } +} diff --git a/tests/View/TwigTest.php b/tests/View/TwigTest.php index 2792a03..662681d 100644 --- a/tests/View/TwigTest.php +++ b/tests/View/TwigTest.php @@ -1,5 +1,6 @@ <?php +use Jasny\Flash; use Jasny\Controller\View\Twig; use Psr\Http\Message\ServerRequestInterface; use Psr\Http\Message\ResponseInterface; @@ -16,7 +17,7 @@ class TwigTest extends PHPUnit_Framework_TestCase */ public function testGetTwig() { - $view = $this->getView(['getTwigLoader', 'getTwigEnvironment', 'createTwigFunction', 'createTwigFilter', 'setViewExtension']); + $view = $this->getView(['getTwigLoader', 'getTwigEnvironment', 'createTwigFunction', 'createTwigFilter', 'setViewExtension', 'setViewVariable']); list($request, $response) = $this->getRequests(); list($loader, $env) = $this->getTwigObjects(); @@ -32,7 +33,12 @@ class TwigTest extends PHPUnit_Framework_TestCase $view->expects($this->once())->method('getRequest')->will($this->returnValue($request)); $request->expects($this->once())->method('getUri')->will($this->returnValue($uri)); $uri->expects($this->once())->method('getPath')->will($this->returnValue($path)); - $env->expects($this->once())->method('addGlobal')->with($this->equalTo('current_url'), $this->equalTo($path)); + $view->expects($this->exactly(2))->method('setViewVariable')->withConsecutive( + [$this->equalTo('current_url'), $this->equalTo($path)], + [$this->equalTo('flash'), $this->callback(function($flash) { + return $flash instanceof Flash && empty($flash->get()); + })] + ); $result = $view->getTwig(); $resultSaved = $view->getTwig(); |