diff --git a/src/Symfony/Bundle/WebProfilerBundle/CHANGELOG.md b/src/Symfony/Bundle/WebProfilerBundle/CHANGELOG.md index a27cdd8835..3ccdf96b86 100644 --- a/src/Symfony/Bundle/WebProfilerBundle/CHANGELOG.md +++ b/src/Symfony/Bundle/WebProfilerBundle/CHANGELOG.md @@ -1,6 +1,12 @@ CHANGELOG ========= +2.7.0 +----- + + * [BC BREAK] if you are using a DB to store profiles, the table must be dropped + * added the HTTP status code to profiles + 2.3.0 ----- diff --git a/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Profiler/results.html.twig b/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Profiler/results.html.twig index b86ea7482f..4bf4232a5e 100644 --- a/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Profiler/results.html.twig +++ b/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Profiler/results.html.twig @@ -12,6 +12,7 @@ Method URL Time + Status @@ -22,6 +23,13 @@ {{ elements.method }} {{ elements.url }} {{ elements.time|date('r') }} + + {% if elements.status_code is defined and elements.status_code %} + {{ elements.status_code }} + {% else %} + unknown + {% endif %} + {% endfor %} diff --git a/src/Symfony/Bundle/WebProfilerBundle/Tests/Controller/ProfilerControllerTest.php b/src/Symfony/Bundle/WebProfilerBundle/Tests/Controller/ProfilerControllerTest.php index c10449d323..1ed32ca676 100644 --- a/src/Symfony/Bundle/WebProfilerBundle/Tests/Controller/ProfilerControllerTest.php +++ b/src/Symfony/Bundle/WebProfilerBundle/Tests/Controller/ProfilerControllerTest.php @@ -73,4 +73,66 @@ class ProfilerControllerTest extends \PHPUnit_Framework_TestCase $response = $controller->toolbarAction(Request::create('/_wdt/notFound'), 'notFound'); $this->assertEquals(404, $response->getStatusCode()); } + + public function testSearchResult() + { + $urlGenerator = $this->getMock('Symfony\Component\Routing\Generator\UrlGeneratorInterface'); + $twig = $this->getMock('Twig_Environment'); + $profiler = $this + ->getMockBuilder('Symfony\Component\HttpKernel\Profiler\Profiler') + ->disableOriginalConstructor() + ->getMock(); + + $controller = new ProfilerController($urlGenerator, $profiler, $twig, array()); + + $tokens = array( + array( + 'token' => 'token1', + 'ip' => '127.0.0.1', + 'method' => 'GET', + 'url' => 'http://example.com/', + 'time' => 0, + 'parent' => null, + 'status_code' => 200, + ), + array( + 'token' => 'token2', + 'ip' => '127.0.0.1', + 'method' => 'GET', + 'url' => 'http://example.com/not_found', + 'time' => 0, + 'parent' => null, + 'status_code' => 404, + ), + ); + $profiler + ->expects($this->once()) + ->method('find') + ->will($this->returnValue($tokens)); + + $twig->expects($this->once()) + ->method('render') + ->with($this->stringEndsWith('results.html.twig'), $this->equalTo(array( + 'token' => 'empty', + 'profile' => null, + 'tokens' => $tokens, + 'ip' => '127.0.0.1', + 'method' => 'GET', + 'url' => 'http://example.com/', + 'start' => null, + 'end' => null, + 'limit' => 2, + 'panel' => null, + ))); + + $response = $controller->searchResultsAction( + Request::create( + '/_profiler/empty/search/results', + 'GET', + array('limit' => 2, 'ip' => '127.0.0.1', 'method' => 'GET', 'url' => 'http://example.com/') + ), + 'empty' + ); + $this->assertEquals(200, $response->getStatusCode()); + } } diff --git a/src/Symfony/Component/HttpKernel/CHANGELOG.md b/src/Symfony/Component/HttpKernel/CHANGELOG.md index 39d35f3c64..ad27886ac8 100644 --- a/src/Symfony/Component/HttpKernel/CHANGELOG.md +++ b/src/Symfony/Component/HttpKernel/CHANGELOG.md @@ -1,6 +1,11 @@ CHANGELOG ========= +2.7.0 +----- + + * added the HTTP status code to profiles + 2.6.0 ----- diff --git a/src/Symfony/Component/HttpKernel/Profiler/BaseMemcacheProfilerStorage.php b/src/Symfony/Component/HttpKernel/Profiler/BaseMemcacheProfilerStorage.php index f50b83e5d3..c6395bd67a 100644 --- a/src/Symfony/Component/HttpKernel/Profiler/BaseMemcacheProfilerStorage.php +++ b/src/Symfony/Component/HttpKernel/Profiler/BaseMemcacheProfilerStorage.php @@ -61,7 +61,9 @@ abstract class BaseMemcacheProfilerStorage implements ProfilerStorageInterface continue; } - list($itemToken, $itemIp, $itemMethod, $itemUrl, $itemTime, $itemParent) = explode("\t", $item, 6); + $values = explode("\t", $item, 7); + list($itemToken, $itemIp, $itemMethod, $itemUrl, $itemTime, $itemParent) = $values; + $statusCode = isset($values[6]) ? $values[6] : null; $itemTime = (int) $itemTime; @@ -84,6 +86,7 @@ abstract class BaseMemcacheProfilerStorage implements ProfilerStorageInterface 'url' => $itemUrl, 'time' => $itemTime, 'parent' => $itemParent, + 'status_code' => $statusCode, ); --$limit; } @@ -176,6 +179,7 @@ abstract class BaseMemcacheProfilerStorage implements ProfilerStorageInterface $profile->getUrl(), $profile->getTime(), $profile->getParentToken(), + $profile->getStatusCode(), ))."\n"; return $this->appendValue($indexName, $indexRow, $this->lifetime); diff --git a/src/Symfony/Component/HttpKernel/Profiler/FileProfilerStorage.php b/src/Symfony/Component/HttpKernel/Profiler/FileProfilerStorage.php index b08c4bdd45..55380bc465 100644 --- a/src/Symfony/Component/HttpKernel/Profiler/FileProfilerStorage.php +++ b/src/Symfony/Component/HttpKernel/Profiler/FileProfilerStorage.php @@ -61,7 +61,9 @@ class FileProfilerStorage implements ProfilerStorageInterface $result = array(); while (count($result) < $limit && $line = $this->readLineFromFile($file)) { - list($csvToken, $csvIp, $csvMethod, $csvUrl, $csvTime, $csvParent) = str_getcsv($line); + $values = str_getcsv($line); + list($csvToken, $csvIp, $csvMethod, $csvUrl, $csvTime, $csvParent) = $values; + $csvStatusCode = isset($values[6]) ? $values[6] : null; $csvTime = (int) $csvTime; @@ -84,6 +86,7 @@ class FileProfilerStorage implements ProfilerStorageInterface 'url' => $csvUrl, 'time' => $csvTime, 'parent' => $csvParent, + 'status_code' => $csvStatusCode, ); } @@ -167,6 +170,7 @@ class FileProfilerStorage implements ProfilerStorageInterface $profile->getUrl(), $profile->getTime(), $profile->getParentToken(), + $profile->getStatusCode(), )); fclose($file); } diff --git a/src/Symfony/Component/HttpKernel/Profiler/MongoDbProfilerStorage.php b/src/Symfony/Component/HttpKernel/Profiler/MongoDbProfilerStorage.php index 23224b4a6e..f35a7f7419 100644 --- a/src/Symfony/Component/HttpKernel/Profiler/MongoDbProfilerStorage.php +++ b/src/Symfony/Component/HttpKernel/Profiler/MongoDbProfilerStorage.php @@ -36,7 +36,7 @@ class MongoDbProfilerStorage implements ProfilerStorageInterface */ public function find($ip, $url, $limit, $method, $start = null, $end = null) { - $cursor = $this->getMongo()->find($this->buildQuery($ip, $url, $method, $start, $end), array('_id', 'parent', 'ip', 'method', 'url', 'time'))->sort(array('time' => -1))->limit($limit); + $cursor = $this->getMongo()->find($this->buildQuery($ip, $url, $method, $start, $end), array('_id', 'parent', 'ip', 'method', 'url', 'time', 'status_code'))->sort(array('time' => -1))->limit($limit); $tokens = array(); foreach ($cursor as $profile) { @@ -83,6 +83,7 @@ class MongoDbProfilerStorage implements ProfilerStorageInterface 'method' => $profile->getMethod(), 'url' => $profile->getUrl(), 'time' => $profile->getTime(), + 'status_code' => $profile->getStatusCode(), ); $result = $this->getMongo()->update(array('_id' => $profile->getToken()), array_filter($record, function ($v) { return !empty($v); }), array('upsert' => true)); @@ -212,6 +213,7 @@ class MongoDbProfilerStorage implements ProfilerStorageInterface 'url' => isset($data['url']) ? $data['url'] : null, 'time' => isset($data['time']) ? $data['time'] : null, 'data' => isset($data['data']) ? $data['data'] : null, + 'status_code' => isset($data['status_code']) ? $data['status_code'] : null, ); } diff --git a/src/Symfony/Component/HttpKernel/Profiler/MysqlProfilerStorage.php b/src/Symfony/Component/HttpKernel/Profiler/MysqlProfilerStorage.php index 69a865f9b5..92e8a1b062 100644 --- a/src/Symfony/Component/HttpKernel/Profiler/MysqlProfilerStorage.php +++ b/src/Symfony/Component/HttpKernel/Profiler/MysqlProfilerStorage.php @@ -33,7 +33,7 @@ class MysqlProfilerStorage extends PdoProfilerStorage } $db = new \PDO($this->dsn, $this->username, $this->password); - $db->exec('CREATE TABLE IF NOT EXISTS sf_profiler_data (token VARCHAR(255) PRIMARY KEY, data LONGTEXT, ip VARCHAR(64), method VARCHAR(6), url VARCHAR(255), time INTEGER UNSIGNED, parent VARCHAR(255), created_at INTEGER UNSIGNED, KEY (created_at), KEY (ip), KEY (method), KEY (url), KEY (parent))'); + $db->exec('CREATE TABLE IF NOT EXISTS sf_profiler_data (token VARCHAR(255) PRIMARY KEY, data LONGTEXT, ip VARCHAR(64), method VARCHAR(6), url VARCHAR(255), time INTEGER UNSIGNED, parent VARCHAR(255), created_at INTEGER UNSIGNED, status_code SMALLINT UNSIGNED, KEY (created_at), KEY (ip), KEY (method), KEY (url), KEY (parent))'); $this->db = $db; } diff --git a/src/Symfony/Component/HttpKernel/Profiler/PdoProfilerStorage.php b/src/Symfony/Component/HttpKernel/Profiler/PdoProfilerStorage.php index a545e6b44b..48f813f2e7 100644 --- a/src/Symfony/Component/HttpKernel/Profiler/PdoProfilerStorage.php +++ b/src/Symfony/Component/HttpKernel/Profiler/PdoProfilerStorage.php @@ -59,7 +59,7 @@ abstract class PdoProfilerStorage implements ProfilerStorageInterface $criteria = $criteria ? 'WHERE '.implode(' AND ', $criteria) : ''; $db = $this->initDb(); - $tokens = $this->fetch($db, 'SELECT token, ip, method, url, time, parent FROM sf_profiler_data '.$criteria.' ORDER BY time DESC LIMIT '.((int) $limit), $args); + $tokens = $this->fetch($db, 'SELECT token, ip, method, url, time, parent, status_code FROM sf_profiler_data '.$criteria.' ORDER BY time DESC LIMIT '.((int) $limit), $args); $this->close($db); return $tokens; @@ -94,13 +94,14 @@ abstract class PdoProfilerStorage implements ProfilerStorageInterface ':url' => $profile->getUrl(), ':time' => $profile->getTime(), ':created_at' => time(), + ':status_code' => $profile->getStatusCode(), ); try { if ($this->has($profile->getToken())) { - $this->exec($db, 'UPDATE sf_profiler_data SET parent = :parent, data = :data, ip = :ip, method = :method, url = :url, time = :time, created_at = :created_at WHERE token = :token', $args); + $this->exec($db, 'UPDATE sf_profiler_data SET parent = :parent, data = :data, ip = :ip, method = :method, url = :url, time = :time, created_at = :created_at, status_code = :status_code WHERE token = :token', $args); } else { - $this->exec($db, 'INSERT INTO sf_profiler_data (token, parent, data, ip, method, url, time, created_at) VALUES (:token, :parent, :data, :ip, :method, :url, :time, :created_at)', $args); + $this->exec($db, 'INSERT INTO sf_profiler_data (token, parent, data, ip, method, url, time, created_at, status_code) VALUES (:token, :parent, :data, :ip, :method, :url, :time, :created_at, :status_code)', $args); } $this->cleanup(); $status = true; diff --git a/src/Symfony/Component/HttpKernel/Profiler/Profile.php b/src/Symfony/Component/HttpKernel/Profiler/Profile.php index 85284bf296..a4e4ba6ad6 100644 --- a/src/Symfony/Component/HttpKernel/Profiler/Profile.php +++ b/src/Symfony/Component/HttpKernel/Profiler/Profile.php @@ -31,6 +31,7 @@ class Profile private $method; private $url; private $time; + private $statusCode; /** * @var Profile @@ -171,6 +172,22 @@ class Profile $this->time = $time; } + /** + * @param int $statusCode + */ + public function setStatusCode($statusCode) + { + $this->statusCode = $statusCode; + } + + /** + * @return int + */ + public function getStatusCode() + { + return $this->statusCode; + } + /** * Finds children profilers. * diff --git a/src/Symfony/Component/HttpKernel/Profiler/Profiler.php b/src/Symfony/Component/HttpKernel/Profiler/Profiler.php index 971bcfecde..864f624729 100644 --- a/src/Symfony/Component/HttpKernel/Profiler/Profiler.php +++ b/src/Symfony/Component/HttpKernel/Profiler/Profiler.php @@ -202,6 +202,7 @@ class Profiler $profile->setUrl($request->getUri()); $profile->setIp($request->getClientIp()); $profile->setMethod($request->getMethod()); + $profile->setStatusCode($response->getStatusCode()); $response->headers->set('X-Debug-Token', $profile->getToken()); diff --git a/src/Symfony/Component/HttpKernel/Profiler/RedisProfilerStorage.php b/src/Symfony/Component/HttpKernel/Profiler/RedisProfilerStorage.php index b05adcc72a..b0e14ea456 100644 --- a/src/Symfony/Component/HttpKernel/Profiler/RedisProfilerStorage.php +++ b/src/Symfony/Component/HttpKernel/Profiler/RedisProfilerStorage.php @@ -71,7 +71,9 @@ class RedisProfilerStorage implements ProfilerStorageInterface continue; } - list($itemToken, $itemIp, $itemMethod, $itemUrl, $itemTime, $itemParent) = explode("\t", $item, 6); + $values = explode("\t", $item, 7); + list($itemToken, $itemIp, $itemMethod, $itemUrl, $itemTime, $itemParent) = $values; + $statusCode = isset($values[6]) ? $values[6] : null; $itemTime = (int) $itemTime; @@ -94,6 +96,7 @@ class RedisProfilerStorage implements ProfilerStorageInterface 'url' => $itemUrl, 'time' => $itemTime, 'parent' => $itemParent, + 'status_code' => $statusCode, ); --$limit; } @@ -182,6 +185,7 @@ class RedisProfilerStorage implements ProfilerStorageInterface $profile->getUrl(), $profile->getTime(), $profile->getParentToken(), + $profile->getStatusCode(), ))."\n"; return $this->appendValue($indexName, $indexRow, $this->lifetime); diff --git a/src/Symfony/Component/HttpKernel/Profiler/SqliteProfilerStorage.php b/src/Symfony/Component/HttpKernel/Profiler/SqliteProfilerStorage.php index 0c25bc950c..4a996fd12d 100644 --- a/src/Symfony/Component/HttpKernel/Profiler/SqliteProfilerStorage.php +++ b/src/Symfony/Component/HttpKernel/Profiler/SqliteProfilerStorage.php @@ -40,7 +40,7 @@ class SqliteProfilerStorage extends PdoProfilerStorage } $db->exec('PRAGMA temp_store=MEMORY; PRAGMA journal_mode=MEMORY;'); - $db->exec('CREATE TABLE IF NOT EXISTS sf_profiler_data (token STRING, data STRING, ip STRING, method STRING, url STRING, time INTEGER, parent STRING, created_at INTEGER)'); + $db->exec('CREATE TABLE IF NOT EXISTS sf_profiler_data (token STRING, data STRING, ip STRING, method STRING, url STRING, time INTEGER, parent STRING, created_at INTEGER, status_code INTEGER)'); $db->exec('CREATE INDEX IF NOT EXISTS data_created_at ON sf_profiler_data (created_at)'); $db->exec('CREATE INDEX IF NOT EXISTS data_ip ON sf_profiler_data (ip)'); $db->exec('CREATE INDEX IF NOT EXISTS data_method ON sf_profiler_data (method)'); diff --git a/src/Symfony/Component/HttpKernel/Tests/Profiler/AbstractProfilerStorageTest.php b/src/Symfony/Component/HttpKernel/Tests/Profiler/AbstractProfilerStorageTest.php index 89d7503ffa..4049ec4e68 100644 --- a/src/Symfony/Component/HttpKernel/Tests/Profiler/AbstractProfilerStorageTest.php +++ b/src/Symfony/Component/HttpKernel/Tests/Profiler/AbstractProfilerStorageTest.php @@ -246,6 +246,22 @@ abstract class AbstractProfilerStorageTest extends \PHPUnit_Framework_TestCase $this->assertCount(3, $this->getStorage()->find('127.0.0.1', 'http://example.net/', 3, 'GET'), '->find() method returns incorrect number of entries'); } + public function testStatusCode() + { + $profile = new Profile('token1'); + $profile->setStatusCode(200); + $this->getStorage()->write($profile); + + $profile = new Profile('token2'); + $profile->setStatusCode(404); + $this->getStorage()->write($profile); + + $tokens = $this->getStorage()->find('', '', 10, ''); + $this->assertCount(2, $tokens); + $this->assertContains($tokens[0]['status_code'], array(200, 404)); + $this->assertContains($tokens[1]['status_code'], array(200, 404)); + } + /** * @return \Symfony\Component\HttpKernel\Profiler\ProfilerStorageInterface */ diff --git a/src/Symfony/Component/HttpKernel/Tests/Profiler/ProfilerTest.php b/src/Symfony/Component/HttpKernel/Tests/Profiler/ProfilerTest.php index 43a8960021..023ed18bd9 100644 --- a/src/Symfony/Component/HttpKernel/Tests/Profiler/ProfilerTest.php +++ b/src/Symfony/Component/HttpKernel/Tests/Profiler/ProfilerTest.php @@ -26,14 +26,15 @@ class ProfilerTest extends \PHPUnit_Framework_TestCase { $request = new Request(); $request->query->set('foo', 'bar'); - $response = new Response(); + $response = new Response('', 204); $collector = new RequestDataCollector(); $profiler = new Profiler($this->storage); $profiler->add($collector); $profile = $profiler->collect($request, $response); - $profile = $profiler->loadProfile($profile->getToken()); + $this->assertSame(204, $profile->getStatusCode()); + $this->assertSame('GET', $profile->getMethod()); $this->assertEquals(array('foo' => 'bar'), $profiler->get('request')->getRequestQuery()->all()); }