Merge branch '2.7'
* 2.7: Minor hot fix [PROCESS] make sure /dev/tty is readable [PhpUnitBridge] Allow PHP 5.3.3 to use with Symfony 2.3 [2.3] require-dev PHPUnit bridge [FrameworkBundle] Fixed Shell logo [2.3] Update CONTRIBUTING.md [2.3][Process] Fixed PhpProcess::getCommandLine() result [Debug] Deprecations exception for Symfony internals [Console] explicit assertion for ArgvInput::getFirstArgument() with no arguments [PropertyAccess] unify and fix doc Enforce UTF-8 charset for core controllers Fix the toolbar JS for IE Conflicts: .travis.yml src/Symfony/Bridge/PhpUnit/composer.json
This commit is contained in:
commit
a01fd1b673
20
.travis.yml
20
.travis.yml
|
@ -6,9 +6,9 @@ matrix:
|
||||||
- php: 5.5
|
- php: 5.5
|
||||||
- php: 5.6
|
- php: 5.6
|
||||||
- php: 5.5.9
|
- php: 5.5.9
|
||||||
env: components=low
|
env: deps=low
|
||||||
- php: 5.6
|
- php: 5.6
|
||||||
env: components=high
|
env: deps=high
|
||||||
- php: hhvm-nightly
|
- php: hhvm-nightly
|
||||||
allow_failures:
|
allow_failures:
|
||||||
- php: hhvm-nightly
|
- php: hhvm-nightly
|
||||||
|
@ -18,8 +18,8 @@ services: mongodb
|
||||||
|
|
||||||
env:
|
env:
|
||||||
global:
|
global:
|
||||||
- components=no
|
- deps=no
|
||||||
- SYMFONY_DEPRECATIONS_HELPER=strict
|
- SYMFONY_DEPRECATIONS_HELPER=weak
|
||||||
|
|
||||||
before_install:
|
before_install:
|
||||||
- travis_retry sudo apt-get install parallel
|
- travis_retry sudo apt-get install parallel
|
||||||
|
@ -35,11 +35,11 @@ before_install:
|
||||||
- if [ "$TRAVIS_BRANCH" = "master" ]; then export COMPOSER_ROOT_VERSION=dev-master; else export COMPOSER_ROOT_VERSION="$TRAVIS_BRANCH".x-dev; fi;
|
- if [ "$TRAVIS_BRANCH" = "master" ]; then export COMPOSER_ROOT_VERSION=dev-master; else export COMPOSER_ROOT_VERSION="$TRAVIS_BRANCH".x-dev; fi;
|
||||||
|
|
||||||
install:
|
install:
|
||||||
- if [ "$components" = "no" ]; then composer --prefer-source install; fi;
|
- if [ "$deps" = "no" ]; then composer --prefer-source install; fi;
|
||||||
|
|
||||||
script:
|
script:
|
||||||
- if [ "$components" = "no" ]; then ls -d src/Symfony/*/* | parallel --gnu --keep-order 'echo -e "\\nRunning {} tests"; phpunit --exclude-group tty,benchmark,intl-data {} || (echo -e "\\e[41mKO\\e[0m {}" && $(exit 1));'; fi;
|
- if [ "$deps" = "no" ]; then export SYMFONY_DEPRECATIONS_HELPER=strict; fi;
|
||||||
- if [ "$components" = "no" ]; then echo -e "\\nRunning tests requiring tty"; phpunit --group tty || (echo -e "\\e[41mKO\\e[0m tty group" && $(exit 1)); fi;
|
- if [ "$deps" = "no" ]; then ls -d src/Symfony/*/* | parallel --gnu --keep-order 'echo -e "\\nRunning {} tests"; phpunit --exclude-group tty,benchmark,intl-data {} || (echo -e "\\e[41mKO\\e[0m {}" && $(exit 1));'; fi;
|
||||||
- if [ "$components" != "no" ]; then export SYMFONY_DEPRECATIONS_HELPER=weak; fi;
|
- if [ "$deps" = "no" ]; then echo -e "\\nRunning tests requiring tty"; phpunit --group tty || (echo -e "\\e[41mKO\\e[0m tty group" && $(exit 1)); fi;
|
||||||
- if [ "$components" = "high" ]; then find src/Symfony -mindepth 3 -type f -name phpunit.xml.dist | sed 's#\(.*\)/.*#\1#' | parallel --gnu --keep-order -j25% 'echo -e "\\nRunning {} tests"; cd {}; composer --prefer-source update; phpunit --exclude-group tty,benchmark,intl-data,legacy || (echo -e "\\e[41mKO\\e[0m {}" && $(exit 1));'; fi;
|
- if [ "$deps" = "high" ]; then find src/Symfony -mindepth 3 -type f -name phpunit.xml.dist | sed 's#\(.*\)/.*#\1#' | parallel --gnu --keep-order -j25% 'echo -e "\\nRunning {} tests"; cd {}; composer --prefer-source update; phpunit --exclude-group tty,benchmark,intl-data,legacy || (echo -e "\\e[41mKO\\e[0m {}" && $(exit 1));'; fi;
|
||||||
- if [ "$components" = "low" ]; then find src/Symfony -mindepth 3 -type f -name phpunit.xml.dist | sed 's#\(.*\)/.*#\1#' | parallel --gnu --keep-order -j25% 'echo -e "\\nRunning {} tests"; cd {}; composer --prefer-source --prefer-lowest --prefer-stable update; phpunit --exclude-group tty,benchmark,intl-data || (echo -e "\\e[41mKO\\e[0m {}" && $(exit 1));'; fi;
|
- if [ "$deps" = "low" ]; then find src/Symfony -mindepth 3 -type f -name phpunit.xml.dist | sed 's#\(.*\)/.*#\1#' | parallel --gnu --keep-order -j25% 'echo -e "\\nRunning {} tests"; cd {}; composer --prefer-source --prefer-lowest --prefer-stable update; phpunit --exclude-group tty,benchmark,intl-data || (echo -e "\\e[41mKO\\e[0m {}" && $(exit 1));'; fi;
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
Contributing
|
Contributing
|
||||||
------------
|
------------
|
||||||
|
|
||||||
Symfony2 is an open source, community-driven project.
|
Symfony is an open source, community-driven project.
|
||||||
|
|
||||||
If you'd like to contribute, please read the following documents:
|
If you'd like to contribute, please read the following documents:
|
||||||
|
|
||||||
|
@ -12,6 +12,19 @@ If you'd like to contribute, please read the following documents:
|
||||||
* [Pull Request Template][3]: Template header to use in your pull request
|
* [Pull Request Template][3]: Template header to use in your pull request
|
||||||
description;
|
description;
|
||||||
|
|
||||||
|
```markdown
|
||||||
|
| Q | A
|
||||||
|
| ------------- | ---
|
||||||
|
| Bug fix? | yes/no
|
||||||
|
| New feature? | yes/no
|
||||||
|
| BC breaks? | no
|
||||||
|
| Deprecations? | no
|
||||||
|
| Tests pass? | yes
|
||||||
|
| Fixed tickets | #1234
|
||||||
|
| License | MIT
|
||||||
|
| Doc PR | symfony/symfony-docs#1234
|
||||||
|
```
|
||||||
|
|
||||||
* [Backwards Compatibility][4]: Backward compatibility rules.
|
* [Backwards Compatibility][4]: Backward compatibility rules.
|
||||||
|
|
||||||
[1]: http://symfony.com/doc/current/contributing/code/index.html
|
[1]: http://symfony.com/doc/current/contributing/code/index.html
|
||||||
|
|
|
@ -29,12 +29,12 @@ class Shell extends BaseShell
|
||||||
{
|
{
|
||||||
return <<<EOF
|
return <<<EOF
|
||||||
<info>
|
<info>
|
||||||
_____ __ ___
|
_____ __
|
||||||
/ ____| / _| |__ \
|
/ ____| / _|
|
||||||
| (___ _ _ _ __ ___ | |_ ___ _ __ _ _ ) |
|
| (___ _ _ _ __ ___ | |_ ___ _ __ _ _
|
||||||
\___ \| | | | '_ ` _ \| _/ _ \| '_ \| | | | / /
|
\___ \| | | | '_ ` _ \| _/ _ \| '_ \| | | |
|
||||||
____) | |_| | | | | | | || (_) | | | | |_| |/ /_
|
____) | |_| | | | | | | || (_) | | | | |_| |
|
||||||
|_____/ \__, |_| |_| |_|_| \___/|_| |_|\__, |____|
|
|_____/ \__, |_| |_| |_|_| \___/|_| |_|\__, |
|
||||||
__/ | __/ |
|
__/ | __/ |
|
||||||
|___/ |___/
|
|___/ |___/
|
||||||
|
|
||||||
|
|
|
@ -62,7 +62,7 @@ class ExceptionController
|
||||||
|
|
||||||
$code = $exception->getStatusCode();
|
$code = $exception->getStatusCode();
|
||||||
|
|
||||||
return new Response($this->twig->render(
|
return Response::create($this->twig->render(
|
||||||
$this->findTemplate($request, $request->getRequestFormat(), $code, $showException),
|
$this->findTemplate($request, $request->getRequestFormat(), $code, $showException),
|
||||||
array(
|
array(
|
||||||
'status_code' => $code,
|
'status_code' => $code,
|
||||||
|
@ -71,7 +71,7 @@ class ExceptionController
|
||||||
'logger' => $logger,
|
'logger' => $logger,
|
||||||
'currentContent' => $currentContent,
|
'currentContent' => $currentContent,
|
||||||
)
|
)
|
||||||
));
|
))->setCharset('UTF-8');
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -40,7 +40,8 @@ class ExceptionControllerTest extends TestCase
|
||||||
$request->headers->set('X-Php-Ob-Level', 1);
|
$request->headers->set('X-Php-Ob-Level', 1);
|
||||||
|
|
||||||
$controller = new ExceptionController($twig, false);
|
$controller = new ExceptionController($twig, false);
|
||||||
$controller->showAction($request, $flatten);
|
$response = $controller->showAction($request, $flatten);
|
||||||
|
$this->assertEquals('UTF-8', $response->getCharset(), 'Request charset is explicitly set to UTF-8');
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testShowActionCanBeForcedToShowErrorPage()
|
public function testShowActionCanBeForcedToShowErrorPage()
|
||||||
|
|
|
@ -62,16 +62,17 @@ class ExceptionController
|
||||||
|
|
||||||
$code = $exception->getStatusCode();
|
$code = $exception->getStatusCode();
|
||||||
|
|
||||||
return new Response($this->twig->render(
|
return Response::create(
|
||||||
$template,
|
$this->twig->render($template, array(
|
||||||
array(
|
|
||||||
'status_code' => $code,
|
'status_code' => $code,
|
||||||
'status_text' => Response::$statusTexts[$code],
|
'status_text' => Response::$statusTexts[$code],
|
||||||
'exception' => $exception,
|
'exception' => $exception,
|
||||||
'logger' => null,
|
'logger' => null,
|
||||||
'currentContent' => '',
|
'currentContent' => '',
|
||||||
)
|
)),
|
||||||
), 200, array('Content-Type' => 'text/html'));
|
200,
|
||||||
|
array('Content-Type' => 'text/html')
|
||||||
|
)->setCharset('UTF-8');
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -97,10 +98,14 @@ class ExceptionController
|
||||||
if (!$this->templateExists($template)) {
|
if (!$this->templateExists($template)) {
|
||||||
$handler = new ExceptionHandler();
|
$handler = new ExceptionHandler();
|
||||||
|
|
||||||
return new Response($handler->getStylesheet($exception), 200, array('Content-Type' => 'text/css'));
|
$response = new Response($handler->getStylesheet($exception), 200, array('Content-Type' => 'text/css'));
|
||||||
|
} else {
|
||||||
|
$response = new Response($this->twig->render('@WebProfiler/Collector/exception.css.twig'), 200, array('Content-Type' => 'text/css'));
|
||||||
}
|
}
|
||||||
|
|
||||||
return new Response($this->twig->render('@WebProfiler/Collector/exception.css.twig'), 200, array('Content-Type' => 'text/css'));
|
$response->setCharset('UTF-8');
|
||||||
|
|
||||||
|
return $response;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function getTemplate()
|
protected function getTemplate()
|
||||||
|
|
|
@ -99,16 +99,20 @@ class ProfilerController
|
||||||
throw new NotFoundHttpException(sprintf('Panel "%s" is not available for token "%s".', $panel, $token));
|
throw new NotFoundHttpException(sprintf('Panel "%s" is not available for token "%s".', $panel, $token));
|
||||||
}
|
}
|
||||||
|
|
||||||
return new Response($this->twig->render($this->getTemplateManager()->getName($profile, $panel), array(
|
return Response::create(
|
||||||
'token' => $token,
|
$this->twig->render($this->getTemplateManager()->getName($profile, $panel), array(
|
||||||
'profile' => $profile,
|
'token' => $token,
|
||||||
'collector' => $profile->getCollector($panel),
|
'profile' => $profile,
|
||||||
'panel' => $panel,
|
'collector' => $profile->getCollector($panel),
|
||||||
'page' => $page,
|
'panel' => $panel,
|
||||||
'request' => $request,
|
'page' => $page,
|
||||||
'templates' => $this->getTemplateManager()->getTemplates($profile),
|
'request' => $request,
|
||||||
'is_ajax' => $request->isXmlHttpRequest(),
|
'templates' => $this->getTemplateManager()->getTemplates($profile),
|
||||||
)), 200, array('Content-Type' => 'text/html'));
|
'is_ajax' => $request->isXmlHttpRequest(),
|
||||||
|
)),
|
||||||
|
200,
|
||||||
|
array('Content-Type' => 'text/html')
|
||||||
|
)->setCharset('UTF-8');
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -147,9 +151,13 @@ class ProfilerController
|
||||||
|
|
||||||
$this->profiler->disable();
|
$this->profiler->disable();
|
||||||
|
|
||||||
return new Response($this->twig->render('@WebProfiler/Profiler/info.html.twig', array(
|
return Response::create(
|
||||||
'about' => $about,
|
$this->twig->render('@WebProfiler/Profiler/info.html.twig', array(
|
||||||
)), 200, array('Content-Type' => 'text/html'));
|
'about' => $about,
|
||||||
|
)),
|
||||||
|
200,
|
||||||
|
array('Content-Type' => 'text/html')
|
||||||
|
)->setCharset('UTF-8');
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -197,13 +205,17 @@ class ProfilerController
|
||||||
// the profiler is not enabled
|
// the profiler is not enabled
|
||||||
}
|
}
|
||||||
|
|
||||||
return new Response($this->twig->render('@WebProfiler/Profiler/toolbar.html.twig', array(
|
return Response::create(
|
||||||
'position' => $position,
|
$this->twig->render('@WebProfiler/Profiler/toolbar.html.twig', array(
|
||||||
'profile' => $profile,
|
'position' => $position,
|
||||||
'templates' => $this->getTemplateManager()->getTemplates($profile),
|
'profile' => $profile,
|
||||||
'profiler_url' => $url,
|
'templates' => $this->getTemplateManager()->getTemplates($profile),
|
||||||
'token' => $token,
|
'profiler_url' => $url,
|
||||||
)), 200, array('Content-Type' => 'text/html'));
|
'token' => $token,
|
||||||
|
)),
|
||||||
|
200,
|
||||||
|
array('Content-Type' => 'text/html')
|
||||||
|
)->setCharset('UTF-8');
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -241,16 +253,20 @@ class ProfilerController
|
||||||
$token = $session->get('_profiler_search_token');
|
$token = $session->get('_profiler_search_token');
|
||||||
}
|
}
|
||||||
|
|
||||||
return new Response($this->twig->render('@WebProfiler/Profiler/search.html.twig', array(
|
return Response::create(
|
||||||
'token' => $token,
|
$this->twig->render('@WebProfiler/Profiler/search.html.twig', array(
|
||||||
'ip' => $ip,
|
'token' => $token,
|
||||||
'method' => $method,
|
'ip' => $ip,
|
||||||
'url' => $url,
|
'method' => $method,
|
||||||
'start' => $start,
|
'url' => $url,
|
||||||
'end' => $end,
|
'start' => $start,
|
||||||
'limit' => $limit,
|
'end' => $end,
|
||||||
'request' => $request,
|
'limit' => $limit,
|
||||||
)), 200, array('Content-Type' => 'text/html'));
|
'request' => $request,
|
||||||
|
)),
|
||||||
|
200,
|
||||||
|
array('Content-Type' => 'text/html')
|
||||||
|
)->setCharset('UTF-8');
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -280,18 +296,22 @@ class ProfilerController
|
||||||
$end = $request->query->get('end', null);
|
$end = $request->query->get('end', null);
|
||||||
$limit = $request->query->get('limit');
|
$limit = $request->query->get('limit');
|
||||||
|
|
||||||
return new Response($this->twig->render('@WebProfiler/Profiler/results.html.twig', array(
|
return Response::create(
|
||||||
'token' => $token,
|
$this->twig->render('@WebProfiler/Profiler/results.html.twig', array(
|
||||||
'profile' => $profile,
|
'token' => $token,
|
||||||
'tokens' => $this->profiler->find($ip, $url, $limit, $method, $start, $end),
|
'profile' => $profile,
|
||||||
'ip' => $ip,
|
'tokens' => $this->profiler->find($ip, $url, $limit, $method, $start, $end),
|
||||||
'method' => $method,
|
'ip' => $ip,
|
||||||
'url' => $url,
|
'method' => $method,
|
||||||
'start' => $start,
|
'url' => $url,
|
||||||
'end' => $end,
|
'start' => $start,
|
||||||
'limit' => $limit,
|
'end' => $end,
|
||||||
'panel' => null,
|
'limit' => $limit,
|
||||||
)), 200, array('Content-Type' => 'text/html'));
|
'panel' => null,
|
||||||
|
)),
|
||||||
|
200,
|
||||||
|
array('Content-Type' => 'text/html')
|
||||||
|
)->setCharset('UTF-8');
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -365,7 +385,7 @@ class ProfilerController
|
||||||
phpinfo();
|
phpinfo();
|
||||||
$phpinfo = ob_get_clean();
|
$phpinfo = ob_get_clean();
|
||||||
|
|
||||||
return new Response($phpinfo, 200, array('Content-Type' => 'text/html'));
|
return Response::create($phpinfo, 200, array('Content-Type' => 'text/html'))->setCharset('UTF-8');
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -68,10 +68,14 @@ class RouterController
|
||||||
|
|
||||||
$request = $profile->getCollector('request');
|
$request = $profile->getCollector('request');
|
||||||
|
|
||||||
return new Response($this->twig->render('@WebProfiler/Router/panel.html.twig', array(
|
return Response::create(
|
||||||
'request' => $request,
|
$this->twig->render('@WebProfiler/Router/panel.html.twig', array(
|
||||||
'router' => $profile->getCollector('router'),
|
'request' => $request,
|
||||||
'traces' => $matcher->getTraces($request->getPathInfo()),
|
'router' => $profile->getCollector('router'),
|
||||||
)), 200, array('Content-Type' => 'text/html'));
|
'traces' => $matcher->getTraces($request->getPathInfo()),
|
||||||
|
)),
|
||||||
|
200,
|
||||||
|
array('Content-Type' => 'text/html')
|
||||||
|
)->setCharset('UTF-8');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -173,7 +173,8 @@
|
||||||
|
|
||||||
var addEventListener;
|
var addEventListener;
|
||||||
|
|
||||||
if (document.attachEvent) {
|
var el = document.createElement('div');
|
||||||
|
if (!'addEventListener' in el) {
|
||||||
addEventListener = function (element, eventName, callback) {
|
addEventListener = function (element, eventName, callback) {
|
||||||
element.attachEvent('on' + eventName, callback);
|
element.attachEvent('on' + eventName, callback);
|
||||||
};
|
};
|
||||||
|
@ -184,40 +185,42 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
{% if excluded_ajax_paths is defined %}
|
{% if excluded_ajax_paths is defined %}
|
||||||
var proxied = XMLHttpRequest.prototype.open;
|
if (window.XMLHttpRequest) {
|
||||||
|
var proxied = XMLHttpRequest.prototype.open;
|
||||||
|
|
||||||
XMLHttpRequest.prototype.open = function(method, url, async, user, pass) {
|
XMLHttpRequest.prototype.open = function(method, url, async, user, pass) {
|
||||||
var self = this;
|
var self = this;
|
||||||
|
|
||||||
/* prevent logging AJAX calls to static and inline files, like templates */
|
/* prevent logging AJAX calls to static and inline files, like templates */
|
||||||
if (url.substr(0, 1) === '/' && !url.match(new RegExp("{{ excluded_ajax_paths }}"))) {
|
if (url.substr(0, 1) === '/' && !url.match(new RegExp("{{ excluded_ajax_paths }}"))) {
|
||||||
var stackElement = {
|
var stackElement = {
|
||||||
loading: true,
|
loading: true,
|
||||||
error: false,
|
error: false,
|
||||||
url: url,
|
url: url,
|
||||||
method: method,
|
method: method,
|
||||||
start: new Date()
|
start: new Date()
|
||||||
};
|
};
|
||||||
|
|
||||||
requestStack.push(stackElement);
|
requestStack.push(stackElement);
|
||||||
|
|
||||||
addEventListener(this, 'readystatechange', function() {
|
this.addEventListener('readystatechange', function() {
|
||||||
if (self.readyState == 4) {
|
if (self.readyState == 4) {
|
||||||
stackElement.duration = new Date() - stackElement.start;
|
stackElement.duration = new Date() - stackElement.start;
|
||||||
stackElement.loading = false;
|
stackElement.loading = false;
|
||||||
stackElement.error = self.status < 200 || self.status >= 400;
|
stackElement.error = self.status < 200 || self.status >= 400;
|
||||||
stackElement.profile = self.getResponseHeader("X-Debug-Token");
|
stackElement.profile = self.getResponseHeader("X-Debug-Token");
|
||||||
stackElement.profilerUrl = self.getResponseHeader("X-Debug-Token-Link");
|
stackElement.profilerUrl = self.getResponseHeader("X-Debug-Token-Link");
|
||||||
|
|
||||||
Sfjs.renderAjaxRequests();
|
Sfjs.renderAjaxRequests();
|
||||||
}
|
}
|
||||||
});
|
}, false);
|
||||||
|
|
||||||
Sfjs.renderAjaxRequests();
|
Sfjs.renderAjaxRequests();
|
||||||
}
|
}
|
||||||
|
|
||||||
proxied.apply(this, Array.prototype.slice.call(arguments));
|
proxied.apply(this, Array.prototype.slice.call(arguments));
|
||||||
};
|
};
|
||||||
|
}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
|
|
@ -69,6 +69,7 @@ class ProfilerControllerTest extends \PHPUnit_Framework_TestCase
|
||||||
|
|
||||||
$response = $controller->toolbarAction(Request::create('/_wdt/found'), 'found');
|
$response = $controller->toolbarAction(Request::create('/_wdt/found'), 'found');
|
||||||
$this->assertEquals(200, $response->getStatusCode());
|
$this->assertEquals(200, $response->getStatusCode());
|
||||||
|
$this->assertEquals('UTF-8', $response->getCharset(), 'Request charset is explicitly set to UTF-8');
|
||||||
|
|
||||||
$response = $controller->toolbarAction(Request::create('/_wdt/notFound'), 'notFound');
|
$response = $controller->toolbarAction(Request::create('/_wdt/notFound'), 'notFound');
|
||||||
$this->assertEquals(404, $response->getStatusCode());
|
$this->assertEquals(404, $response->getStatusCode());
|
||||||
|
|
|
@ -257,7 +257,7 @@ class ArgvInputTest extends \PHPUnit_Framework_TestCase
|
||||||
public function testGetFirstArgument()
|
public function testGetFirstArgument()
|
||||||
{
|
{
|
||||||
$input = new ArgvInput(array('cli.php', '-fbbar'));
|
$input = new ArgvInput(array('cli.php', '-fbbar'));
|
||||||
$this->assertEquals('', $input->getFirstArgument(), '->getFirstArgument() returns the first argument from the raw input');
|
$this->assertNull($input->getFirstArgument(), '->getFirstArgument() returns null when there is no arguments');
|
||||||
|
|
||||||
$input = new ArgvInput(array('cli.php', '-fbbar', 'foo'));
|
$input = new ArgvInput(array('cli.php', '-fbbar', 'foo'));
|
||||||
$this->assertEquals('foo', $input->getFirstArgument(), '->getFirstArgument() returns the first argument from the raw input');
|
$this->assertEquals('foo', $input->getFirstArgument(), '->getFirstArgument() returns the first argument from the raw input');
|
||||||
|
|
|
@ -180,16 +180,28 @@ class DebugClassLoader
|
||||||
if (preg_match('#\n \* @deprecated (.*?)\r?\n \*(?: @|/$)#s', $refl->getDocComment(), $notice)) {
|
if (preg_match('#\n \* @deprecated (.*?)\r?\n \*(?: @|/$)#s', $refl->getDocComment(), $notice)) {
|
||||||
self::$deprecated[$name] = preg_replace('#\s*\r?\n \* +#', ' ', $notice[1]);
|
self::$deprecated[$name] = preg_replace('#\s*\r?\n \* +#', ' ', $notice[1]);
|
||||||
} else {
|
} else {
|
||||||
$len = 1 + (strpos($name, '\\', 1 + strpos($name, '\\')) ?: strpos($name, '_'));
|
if (2 > $len = 1 + (strpos($name, '\\', 1 + strpos($name, '\\')) ?: strpos($name, '_'))) {
|
||||||
|
$len = 0;
|
||||||
|
$ns = '';
|
||||||
|
} else {
|
||||||
|
switch ($ns = substr($name, 0, $len)) {
|
||||||
|
case 'Symfony\Bridge\\':
|
||||||
|
case 'Symfony\Bundle\\':
|
||||||
|
case 'Symfony\Component\\':
|
||||||
|
$ns = 'Symfony\\';
|
||||||
|
$len = strlen($ns);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
$parent = $refl->getParentClass();
|
$parent = $refl->getParentClass();
|
||||||
|
|
||||||
if (!$parent || $len < 2 || strncmp($name, $parent, $len)) {
|
if (!$parent || strncmp($ns, $parent, $len)) {
|
||||||
if ($parent && isset(self::$deprecated[$parent->name]) && ($len < 2 || strncmp($name, $parent->name, $len))) {
|
if ($parent && isset(self::$deprecated[$parent->name]) && strncmp($ns, $parent->name, $len)) {
|
||||||
trigger_error(sprintf('The %s class extends %s that is deprecated %s', $name, $parent->name, self::$deprecated[$parent->name]), E_USER_DEPRECATED);
|
trigger_error(sprintf('The %s class extends %s that is deprecated %s', $name, $parent->name, self::$deprecated[$parent->name]), E_USER_DEPRECATED);
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach ($refl->getInterfaceNames() as $interface) {
|
foreach ($refl->getInterfaceNames() as $interface) {
|
||||||
if (isset(self::$deprecated[$interface]) && ($len < 2 || strncmp($name, $interface, $len)) && !($parent && $parent->implementsInterface($interface))) {
|
if (isset(self::$deprecated[$interface]) && strncmp($ns, $interface, $len) && !($parent && $parent->implementsInterface($interface))) {
|
||||||
trigger_error(sprintf('The %s %s %s that is deprecated %s', $name, $refl->isInterface() ? 'interface extends' : 'class implements', $interface, self::$deprecated[$interface]), E_USER_DEPRECATED);
|
trigger_error(sprintf('The %s %s %s that is deprecated %s', $name, $refl->isInterface() ? 'interface extends' : 'class implements', $interface, self::$deprecated[$interface]), E_USER_DEPRECATED);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -193,7 +193,7 @@ class DebugClassLoaderTest extends \PHPUnit_Framework_TestCase
|
||||||
$e = error_reporting(0);
|
$e = error_reporting(0);
|
||||||
trigger_error('', E_USER_NOTICE);
|
trigger_error('', E_USER_NOTICE);
|
||||||
|
|
||||||
class_exists(__NAMESPACE__.'\Fixtures\ExtendsDeprecatedParent', true);
|
class_exists('Symfony\Bridge\Debug\Tests\Fixtures\ExtendsDeprecatedParent', true);
|
||||||
|
|
||||||
error_reporting($e);
|
error_reporting($e);
|
||||||
restore_error_handler();
|
restore_error_handler();
|
||||||
|
@ -239,8 +239,8 @@ class ClassLoader
|
||||||
return __DIR__.'/Fixtures/notPsr0Bis.php';
|
return __DIR__.'/Fixtures/notPsr0Bis.php';
|
||||||
} elseif (__NAMESPACE__.'\Fixtures\DeprecatedInterface' === $class) {
|
} elseif (__NAMESPACE__.'\Fixtures\DeprecatedInterface' === $class) {
|
||||||
return __DIR__.'/Fixtures/DeprecatedInterface.php';
|
return __DIR__.'/Fixtures/DeprecatedInterface.php';
|
||||||
} elseif (__NAMESPACE__.'\Fixtures\ExtendsDeprecatedParent' === $class) {
|
} elseif ('Symfony\Bridge\Debug\Tests\Fixtures\ExtendsDeprecatedParent' === $class) {
|
||||||
eval('namespace '.__NAMESPACE__.'\Fixtures; class ExtendsDeprecatedParent extends DeprecatedClass {}');
|
eval('namespace Symfony\Bridge\Debug\Tests\Fixtures; class ExtendsDeprecatedParent extends \\'.__NAMESPACE__.'\Fixtures\DeprecatedClass {}');
|
||||||
} elseif ('Test\\'.__NAMESPACE__.'\DeprecatedParentClass' === $class) {
|
} elseif ('Test\\'.__NAMESPACE__.'\DeprecatedParentClass' === $class) {
|
||||||
eval('namespace Test\\'.__NAMESPACE__.'; class DeprecatedParentClass extends \\'.__NAMESPACE__.'\Fixtures\DeprecatedClass {}');
|
eval('namespace Test\\'.__NAMESPACE__.'; class DeprecatedParentClass extends \\'.__NAMESPACE__.'\Fixtures\DeprecatedClass {}');
|
||||||
} elseif ('Test\\'.__NAMESPACE__.'\DeprecatedInterfaceClass' === $class) {
|
} elseif ('Test\\'.__NAMESPACE__.'\DeprecatedInterfaceClass' === $class) {
|
||||||
|
|
|
@ -107,7 +107,7 @@ class Client extends BaseClient
|
||||||
$code = <<<EOF
|
$code = <<<EOF
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
error_reporting($errorReporting);
|
error_reporting($errorReporting & ~E_USER_DEPRECATED);
|
||||||
|
|
||||||
require_once '$requirePath';
|
require_once '$requirePath';
|
||||||
|
|
||||||
|
|
|
@ -26,8 +26,6 @@ use Symfony\Component\Process\Exception\RuntimeException;
|
||||||
*/
|
*/
|
||||||
class PhpProcess extends Process
|
class PhpProcess extends Process
|
||||||
{
|
{
|
||||||
private $executableFinder;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor.
|
* Constructor.
|
||||||
*
|
*
|
||||||
|
@ -41,9 +39,12 @@ class PhpProcess extends Process
|
||||||
*/
|
*/
|
||||||
public function __construct($script, $cwd = null, array $env = array(), $timeout = 60, array $options = array())
|
public function __construct($script, $cwd = null, array $env = array(), $timeout = 60, array $options = array())
|
||||||
{
|
{
|
||||||
parent::__construct(null, $cwd, $env, $script, $timeout, $options);
|
$executableFinder = new PhpExecutableFinder();
|
||||||
|
if (false === $php = $executableFinder->find()) {
|
||||||
|
$php = null;
|
||||||
|
}
|
||||||
|
|
||||||
$this->executableFinder = new PhpExecutableFinder();
|
parent::__construct($php, $cwd, $env, $script, $timeout, $options);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -62,10 +63,7 @@ class PhpProcess extends Process
|
||||||
public function start($callback = null)
|
public function start($callback = null)
|
||||||
{
|
{
|
||||||
if (null === $this->getCommandLine()) {
|
if (null === $this->getCommandLine()) {
|
||||||
if (false === $php = $this->executableFinder->find()) {
|
throw new RuntimeException('Unable to find the PHP executable.');
|
||||||
throw new RuntimeException('Unable to find the PHP executable.');
|
|
||||||
}
|
|
||||||
$this->setCommandLine($php);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
parent::start($callback);
|
parent::start($callback);
|
||||||
|
|
|
@ -949,6 +949,9 @@ class Process
|
||||||
if ('\\' === DIRECTORY_SEPARATOR && $tty) {
|
if ('\\' === DIRECTORY_SEPARATOR && $tty) {
|
||||||
throw new RuntimeException('TTY mode is not supported on Windows platform.');
|
throw new RuntimeException('TTY mode is not supported on Windows platform.');
|
||||||
}
|
}
|
||||||
|
if ($tty && (!file_exists('/dev/tty') || !is_readable('/dev/tty'))) {
|
||||||
|
throw new RuntimeException('TTY mode requires /dev/tty to be readable.');
|
||||||
|
}
|
||||||
|
|
||||||
$this->tty = (bool) $tty;
|
$this->tty = (bool) $tty;
|
||||||
|
|
||||||
|
|
|
@ -11,6 +11,7 @@
|
||||||
|
|
||||||
namespace Symfony\Component\Process\Tests;
|
namespace Symfony\Component\Process\Tests;
|
||||||
|
|
||||||
|
use Symfony\Component\Process\PhpExecutableFinder;
|
||||||
use Symfony\Component\Process\PhpProcess;
|
use Symfony\Component\Process\PhpProcess;
|
||||||
|
|
||||||
class PhpProcessTest extends \PHPUnit_Framework_TestCase
|
class PhpProcessTest extends \PHPUnit_Framework_TestCase
|
||||||
|
@ -26,4 +27,23 @@ PHP
|
||||||
$process->wait();
|
$process->wait();
|
||||||
$this->assertEquals($expected, $process->getOutput());
|
$this->assertEquals($expected, $process->getOutput());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function testCommandLine()
|
||||||
|
{
|
||||||
|
$process = new PhpProcess(<<<PHP
|
||||||
|
<?php echo 'foobar';
|
||||||
|
PHP
|
||||||
|
);
|
||||||
|
|
||||||
|
$f = new PhpExecutableFinder();
|
||||||
|
$commandLine = $f->find();
|
||||||
|
|
||||||
|
$this->assertSame($commandLine, $process->getCommandLine(), '::getCommandLine() returns the command line of PHP before start');
|
||||||
|
|
||||||
|
$process->start();
|
||||||
|
$this->assertSame($commandLine, $process->getCommandLine(), '::getCommandLine() returns the command line of PHP after start');
|
||||||
|
|
||||||
|
$process->wait();
|
||||||
|
$this->assertSame($commandLine, $process->getCommandLine(), '::getCommandLine() returns the command line of PHP after wait');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -200,8 +200,9 @@ class PropertyAccessor implements PropertyAccessorInterface
|
||||||
if (!is_array($objectOrArray)) {
|
if (!is_array($objectOrArray)) {
|
||||||
if (!$objectOrArray instanceof \Traversable) {
|
if (!$objectOrArray instanceof \Traversable) {
|
||||||
throw new NoSuchIndexException(sprintf(
|
throw new NoSuchIndexException(sprintf(
|
||||||
'Cannot read property "%s".',
|
'Cannot read index "%s" while trying to traverse path "%s".',
|
||||||
$property
|
$property,
|
||||||
|
(string) $propertyPath
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -209,8 +210,9 @@ class PropertyAccessor implements PropertyAccessorInterface
|
||||||
}
|
}
|
||||||
|
|
||||||
throw new NoSuchIndexException(sprintf(
|
throw new NoSuchIndexException(sprintf(
|
||||||
'Cannot read property "%s". Available properties are "%s"',
|
'Cannot read index "%s" while trying to traverse path "%s". Available indices are "%s".',
|
||||||
$property,
|
$property,
|
||||||
|
(string) $propertyPath,
|
||||||
print_r(array_keys($objectOrArray), true)
|
print_r(array_keys($objectOrArray), true)
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
@ -250,7 +252,7 @@ class PropertyAccessor implements PropertyAccessorInterface
|
||||||
private function &readIndex(&$array, $index)
|
private function &readIndex(&$array, $index)
|
||||||
{
|
{
|
||||||
if (!$array instanceof \ArrayAccess && !is_array($array)) {
|
if (!$array instanceof \ArrayAccess && !is_array($array)) {
|
||||||
throw new NoSuchIndexException(sprintf('Index "%s" cannot be read from object of type "%s" because it doesn\'t implement \ArrayAccess', $index, get_class($array)));
|
throw new NoSuchIndexException(sprintf('Cannot read index "%s" from object of type "%s" because it doesn\'t implement \ArrayAccess.', $index, get_class($array)));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Use an array instead of an object since performance is very crucial here
|
// Use an array instead of an object since performance is very crucial here
|
||||||
|
@ -294,7 +296,7 @@ class PropertyAccessor implements PropertyAccessorInterface
|
||||||
);
|
);
|
||||||
|
|
||||||
if (!is_object($object)) {
|
if (!is_object($object)) {
|
||||||
throw new NoSuchPropertyException(sprintf('Cannot read property "%s" from an array. Maybe you should write the property path as "[%s]" instead?', $property, $property));
|
throw new NoSuchPropertyException(sprintf('Cannot read property "%s" from an array. Maybe you intended to write the property path as "[%s]" instead.', $property, $property));
|
||||||
}
|
}
|
||||||
|
|
||||||
$camelized = $this->camelize($property);
|
$camelized = $this->camelize($property);
|
||||||
|
@ -364,7 +366,7 @@ class PropertyAccessor implements PropertyAccessorInterface
|
||||||
private function writeIndex(&$array, $index, $value)
|
private function writeIndex(&$array, $index, $value)
|
||||||
{
|
{
|
||||||
if (!$array instanceof \ArrayAccess && !is_array($array)) {
|
if (!$array instanceof \ArrayAccess && !is_array($array)) {
|
||||||
throw new NoSuchIndexException(sprintf('Index "%s" cannot be modified in object of type "%s" because it doesn\'t implement \ArrayAccess', $index, get_class($array)));
|
throw new NoSuchIndexException(sprintf('Cannot modify index "%s" in object of type "%s" because it doesn\'t implement \ArrayAccess', $index, get_class($array)));
|
||||||
}
|
}
|
||||||
|
|
||||||
$array[$index] = $value;
|
$array[$index] = $value;
|
||||||
|
|
|
@ -12,7 +12,7 @@
|
||||||
namespace Symfony\Component\PropertyAccess;
|
namespace Symfony\Component\PropertyAccess;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A configurable builder for PropertyAccessorInterface objects.
|
* A configurable builder to create a PropertyAccessor.
|
||||||
*
|
*
|
||||||
* @author Jérémie Augustin <jeremie.augustin@pixel-cookers.com>
|
* @author Jérémie Augustin <jeremie.augustin@pixel-cookers.com>
|
||||||
*/
|
*/
|
||||||
|
@ -53,7 +53,7 @@ class PropertyAccessorBuilder
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return bool true if the use of "__call" by the PropertyAccessor is enabled
|
* @return bool whether the use of "__call" by the PropertyAccessor is enabled
|
||||||
*/
|
*/
|
||||||
public function isMagicCallEnabled()
|
public function isMagicCallEnabled()
|
||||||
{
|
{
|
||||||
|
@ -61,7 +61,10 @@ class PropertyAccessorBuilder
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Enables exceptions in read context for array by PropertyAccessor
|
* Enables exceptions when reading a non-existing index.
|
||||||
|
*
|
||||||
|
* This has no influence on writing non-existing indices with PropertyAccessorInterface::setValue()
|
||||||
|
* which are always created on-the-fly.
|
||||||
*
|
*
|
||||||
* @return PropertyAccessorBuilder The builder object
|
* @return PropertyAccessorBuilder The builder object
|
||||||
*/
|
*/
|
||||||
|
@ -73,7 +76,9 @@ class PropertyAccessorBuilder
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Disables exceptions in read context for array by PropertyAccessor
|
* Disables exceptions when reading a non-existing index.
|
||||||
|
*
|
||||||
|
* Instead, null is returned when calling PropertyAccessorInterface::getValue() on a non-existing index.
|
||||||
*
|
*
|
||||||
* @return PropertyAccessorBuilder The builder object
|
* @return PropertyAccessorBuilder The builder object
|
||||||
*/
|
*/
|
||||||
|
@ -85,7 +90,7 @@ class PropertyAccessorBuilder
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return bool true is exceptions in read context for array is enabled
|
* @return bool whether an exception is thrown or null is returned when reading a non-existing index
|
||||||
*/
|
*/
|
||||||
public function isExceptionOnInvalidIndexEnabled()
|
public function isExceptionOnInvalidIndexEnabled()
|
||||||
{
|
{
|
||||||
|
@ -93,9 +98,9 @@ class PropertyAccessorBuilder
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Builds and returns a new propertyAccessor object.
|
* Builds and returns a new PropertyAccessor object.
|
||||||
*
|
*
|
||||||
* @return PropertyAccessorInterface The built propertyAccessor
|
* @return PropertyAccessorInterface The built PropertyAccessor
|
||||||
*/
|
*/
|
||||||
public function getPropertyAccessor()
|
public function getPropertyAccessor()
|
||||||
{
|
{
|
||||||
|
|
Reference in New Issue