8000 Merge branch '3.1' · symfony/symfony@cf4e2e9 · GitHub
[go: up one dir, main page]

Skip to content
8000

Commit cf4e2e9

Browse files
committed
Merge branch '3.1'
* 3.1: (24 commits) [Yaml] fix exception contexts Added people - person inflection People - person singularization [Yaml] properly handle unindented collections [Serializer] Add test for ignored attributes during denormalization chomp newlines only at the end of YAML documents Fixed server status command when port has been omitted Update UPGRADE FROM 2.x to 3.0 [Config] Allow schemed path in FileResource fix removed commands wording in upgrade file Catch \Throwable Catch \Throwable [DependencyInjection] Avoid generating call_user_func in more cases [Validator] Support for DateTimeImmutable [YAML] fixed "dump" signature in upgrade file [Cache] Rename nonce to version [FrameworkBundle] update upgrade instructions Use levenshtein level for better Bundle matching [WebProfilerBundle] Fix CORS ajax security issues remove methods that were needed for PHP 5.3 ...
2 parents b0a483e + 330c09b commit cf4e2e9

File tree

33 files changed

+451
-82
lines changed

33 files changed

+451
-82
lines changed

CHANGELOG-3.1.md

Lines changed: 136 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,136 @@
1+
CHANGELOG for 3.1.x
2+
===================
3+
4+
This changelog references the relevant changes (bug and security fixes) done
5+
in 3.1 minor versions.
6+
7+
To get the diff for a specific change, go to https://github.com/symfony/symfony/commit/XXX where XXX is the change hash
8+
To get the diff between two versions, go to https://github.com/symfony/symfony/compare/v3.1.0...v3.1.1
9+
10+
* 3.1.0-BETA1 (2016-05-13)
11+
12+
* feature #18725 [Ldap] Added the possibility to configure all available Ldap options for connection (csarrazi)
13+
* feature #18715 [FrameworkBundle] Default to Apcu+Filesystem cache chain (nicolas-grekas)
14+
* feature #18184 [DomCrawler] Expose getter for uri (hason)
15+
* feature #18654 [Bridge/Doctrine] Use better exception in the register mapping pass (dantleech)
16+
* feature #18676 [HttpKernel] Add request method to logger messages (gnat42)
17+
* feature #18716 [Cache] Add nonce based cache invalidation to ApcuAdapter (nicolas-grekas)
18+
* feature #18762 [Translation] XLIFF Add `id` to meta data. (SpacePossum)
19+
* feature #18689 [Cache] Add support for Predis, RedisArray and RedisCluster (nicolas-grekas)
20+
* feature #18667 [FrameworkBundle] Semantic config for app/system/pool caches (tgalopin, nicolas-grekas)
21+
* feature #18685 move event listener method type hint docs to @Event annotations defau… (Haehnchen)
22+
* feature #18681 [Cache] Add DSN based Redis connection factory (nicolas-grekas)
23+
* feature #18656 Updating the error message of an AuthenticationEntryPointInterface (weaverryan)
24+
* feature #18069 [DoctrineBridge] deprecate `MergeDoctrineCollectionListener::onBind()` (HeahDude)
25+
* feature #18492 [LDAP] Check whether an entry attribute exists (hiddewie)
26+
* feature #18359 [Form] [DoctrineBridge] optimized LazyChoiceList and DoctrineChoiceLoader (HeahDude)
27+
* feature #18357 [Form] Let `TextType` implement `DataTransformerInterface` (HeahDude)
28+
* feature #18631 [FrameworkBundle] Add optional logger to cache pools (nicolas-grekas)
29+
* feature #18597 [Cache] Add CacheItem::validateKey utility method (nicolas-grekas)
30+
* feature #17660 [Serializer] Integrate the PropertyInfo Component (recursive denormalization and hardening) (mihai-stancu, dunglas)
31+
* feature #18561 [FrameworkBundle] Fallback to default cache system in production for serializer (tgalopin)
32+
* feature #18567 [FrameworkBundle][Serializer] Fix APC cache service name (tgalopin)
33+
* feature #17959 [Serializer] Harden the ObjectNormalizer (dunglas)
34+
* feature #18547 DX: better error message if factory class is empty (dbu)
35+
* feature #18020 fix #17993 - Deprecated callable strings (hamza)
36+
* feature #18487 [Cache] Add DoctrineProvider, for using PSR-6 pools in Doctrine Cache (nicolas-grekas)
37+
* feature #18544 [FrameworkBundle] Fallback to default cache system in production for validation (tgalopin)
38+
* feature #18416 [FrameworkBundle] Calls support for debug:container (JhonnyL)
39+
* feature #18513 [Process] Turn getIterator() args to flags & add ITER_SKIP_OUT/ERR modes (nicolas-grekas)
40+
* feature #18371 [FrameworkBundle] integrate the Cache component (xabbuh, nicolas-grekas)
41+
* feature #18440 Add the kernel.controller_arguments event (stof)
42+
* feature #18308 Added an ArgumentResolver with clean extension point (iltar, HeahDude)
43+
* feature #18414 [Process] Implement IteratorAggregate to stream output (nicolas-grekas)
44+
* feature #18144 [DI] Only rebuild autowiring cache when actually needed (weaverryan)
45+
* feature #18386 [Process] Add InputStream to seamlessly feed running processes (nicolas-grekas)
46+
* feature #18167 [DependencyInjection] Fix a limitation of the PhpDumper (Ener-Getick)
47+
* feature #18387 [DX] [LDAP] Added default service name for the Security component's Ldap providers (csarrazi)
48+
* feature #18290 [Translation] deprecate the backup feature (xabbuh)
49+
* feature #18036 [Serializer] XmlEncoder: Make load flags configurable (dunglas)
50+
* feature #17589 [WebProfilerBundle] [DX] Feature allow forward and redirection detection in wdt (HeahDude)
51+
* feature #18260 Add F987 Inflector component (from StringUtil of PropertyAccess) (teohhanhui)
52+
* feature #18356 [FrameworkBundle] Deprecated form types as services (HeahDude)
53+
* feature #17458 Add strict image validation (Koc)
54+
* feature #18350 [Process] Accept Traversable input (nicolas-grekas)
55+
* feature #18135 [Security] Deprecate onAuthenticationSuccess() (weaverryan)
56+
* feature #18294 [Yaml] dump non UTF-8 encoded strings as binary data (xabbuh)
57+
* feature #18215 [Cache] Add a Chain adapter (dunglas, nicolas-grekas)
58+
* feature #18242 [FrameworkBundle][TwigBundle] Make EngineInterface autowirable (dunglas)
59+
* feature #18197 Make Request::isFromTrustedProxy() public. (Peter Bex)
60+
* feature #18211 [Security] Use auth trust resolver to determine anonymous in ContextListener (WouterJ)
61+
* feature #18232 [Bridge\PhpUnit] Add "disabled" mode to SYMFONY_DEPRECATIONS_HELPER (nicolas-grekas)
62+
* feature #18181 [PhpUnitBridge] Mock DNS functions (nicolas-grekas)
63+
* feature #18176 [Cache] Restrict flushes to namespace scopes (nicolas-grekas)
64+
* feature #18172 [Cache] Redis adapter (gcds, nicolas-grekas)
65+
* feature #18101 [Console] Allow to register commands privately (Ener-Getick)
66+
* feature #18143 [DomCrawler] Exposed getter for baseHref (AAstakhov)
67+
* feature #18034 [FrameworkBundle] Deprecate absolute template paths (jakzal)
68+
* feature #18105 [HttpFoundation] Add support for sending raw cookies in the response (jakzal)
69+
* feature #17255 [Console] ApplicationTester - test stdout and stderr (SpacePossum)
70+
* feature #18024 [Cache] Add namespace handling to all adapters (nicolas-grekas)
71+
* feature #17734 [Cache] Count cache hits/misses in ProxyAdapter (nicolas-grekas)
72+
* feature #17887 Show more information in the security profiler (javiereguiluz)
73+
* feature #17642 [FrameworkBundle] [DX] Add `Controller::json` method to make it easy to send json (mcfedr)
74+
* feature #17484 [FrameworkBundle][DX] Add Levenshtein suggesters to AbstractConfigCommand (kix)
75+
* feature #17690 [FrameworkBundle] Use canBeEnabled() instead of canBeUnset() for consistency (Ener-Getick)
76+
* feature #17714 Adding new TargetPathTrait to get/set the authentication "target_path" (weaverryan)
77+
* feature #17852 Improved the logger panel when the log context is very long (javiereguiluz)
78+
* feature #17761 [Console] Add non-auto column width functionality (akeeman)
79+
* feature #17943 [Yaml] option to dump multi line strings as scalar blocks (xabbuh)
80+
* feature #17553 [Validator] Added a format option to the DateTime constraint. (dosten)
81+
* feature #17728 [Yaml] add option to dump objects as maps (xabbuh)
82+
* feature #17863 [Yaml] add support for parsing the !!binary tag (xabbuh)
83+
* feature #17738 [PropertyAccess] Throw an InvalidArgumentException when the type do not match (dunglas)
84+
* feature #17531 [PropertyInfo] Use last version of reflection docblock (joelwurtz)
85+
* feature #17782 Support autowiring for Doctrine\Common\Annotations\Reader (maryo)
86+
* feature #17603 [Serializer] Add a normalizer that support JsonSerializable objects (mcfedr)
87+
* feature #17630 [FrameworkBundle] Register the DateTimeNormalizer (dunglas)
88+
* feature #17631 [FrameworkBundle] Register the DataUriNormalizer (dunglas)
89+
* feature #17545 [Serializer] Add normalizer / denormalizer awarness (joelwurtz)
90+
* feature #17877 [DependencyInjection] Improving autowiring error messages (weaverryan)
91+
* feature #17732 [DEPRECATION] : deprecated support for Traversable in method ResizeFormListener::PreSubmit (ybensacq)
92+
* feature #17721 [Cache] Add FilesystemAdapter (nicolas-grekas)
93+
* feature #17836 [Yaml] support to parse and dump DateTime objects (xabbuh)
94+
* feature #17809 [Yaml] deprecate starting plain scalars with characters (xabbuh)
95+
* feature #17817 [Ldap] Add write support for the Ldap component (csarrazi)
96+
* feature #17560 [Ldap] Improving the LDAP component (csarrazi)
97+
* feature #17726 [FrameworkBundle] Improve debug:container command (voronkovich)
98+
* feature #17743 [Yaml] dumper flag for enabling exceptions on invalid type (xabbuh)
99+
* feature #17746 [Yaml] deprecate the Dumper::setIndentation() method (xabbuh)
100+
* feature #17730 [Yaml] introduce flags to customize the parser behavior (xabbuh)
101+
* feature #17125 Webprofiler add status code to search form (oktapodia)
102+
* feature #17705 [TwigBridge] deprecate the boolean object support trigger (xabbuh)
103+
* feature #17578 [Yaml] dump customization option with dumper flags (xabbuh)
104+
* feature #17585 [DomCrawler] Abstract URI logic and crawl images (valeriangalliat)
105+
* feature #17654 [Cache] Don't clone, serialize (nicolas-grekas)
106+
* feature #16947 [FrameworkBundle] PropertyInfo: register the SerializerExtractor (dunglas)
107+
* feature #17611 [HttpKernel] Deprecate passing objects as URI attributes to the ESI and SSI renderers (jakzal)
108+
* feature #14288 [Console] Add getters for Application::$autoExit and $catchExceptions (VasekPurchart)
109+
* feature #17504 [Console] Show code when an exception is thrown (maidmaid)
110+
* feature #17540 [WebProfilerBundle] Add HTTP return code in the Ajax request list table (kucharovic)
111+
* feature #17446 [Serializer] Add PSR-6 adapter (dunglas)
112+
* feature #16917 [PropertyInfo] Cache support (dunglas)
113+
* feature #17532 [Asset] Version as service (ewgRa)
114+
* feature #17440 [Validator] Add a PSR-6 adapter (dunglas)
115+
* feature #17113 [Serializer] Add a MaxDepth option (dunglas)
116+
* feature #17530 [Cache] Handle and log errors properly (nicolas-grekas)
117+
* feature #17522 [Cache] Use generator in ArrayAdapter (gcds)
118+
* feature #16164 [Serializer] Add a data: URI normalizer (dunglas)
119+
* feature #15279 Added {{ value }} message placeholder to UniqueEntityValidator (jperovic)
120+
* feature #16652 [console] Add truncate method to FormatterHelper (mheki)
121+
* feature #17438 [Cache] Allow and use generators in AbstractAdapter (nicolas-grekas)
122+
* feature #17111 [HttpKernel] added a setter for the headers property in the HttpException (smatyas)
123+
* feature #17132 [DependencyInjection] Properly ignore invalid reference arguments in collection arguments (ogizanagi)
124+
* feature #17427 [Process] Allow a callback whenever the output is disabled (romainneutron)
125+
* feature #17327 Added support links to exception and toolbar (peterrehm)
126+
* feature #16909 Allows access to payload in callback validator (conradkleinespel)
127+
* feature #17402 [Profiler] make it possible to omit the link var (xabbuh)
128+
* feature #17411 [Serializer] Add a new DateTime normalizer (dunglas)
129+
* feature #17462 [Yaml] deprecate parsing the !!php/object tag (xabbuh)
130+
* feature #17408 [Cache] Symfony PSR-6 implementation (nicolas-grekas)
131+
* feature #17323 [DependencyInjection] Deprecate unsupported attributes/elements for alias (Ener-Getick)
132+
* feature #17305 [VarDumper] Add flags to allow fine tuning dumps representation (nicolas-grekas)
133+
* feature #17318 [HttpFoundation] Allow to get all the mime types associated to a format in the Request (Ener-Getick)
134+
* feature #17133 [DependencyInjection] Make YamlFileLoader raise a deprecation notice if a service definition contains unsupported keywords. (hhamon)
135+
* feature #17191 [Serializer] Move the normalization logic in an abstract class (dunglas)
136+
* feature #16994 [Form] Deprecate the "choices_as_values" option of ChoiceType (nicolas-grekas)

UPGRADE-3.0.md

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -398,8 +398,11 @@ UPGRADE FROM 2.x to 3.0
398398
</service>
399399
```
400400

401-
* The `ChoiceToBooleanArrayTransformer`, `ChoicesToBooleanArrayTransformer`,
402-
`FixRadioInputListener`, and `FixCheckboxInputListener` classes were removed.
401+
* The `max_length` option was removed. Use the `attr` option instead by setting it to
402+
an `array` with a `maxlength` key.
403+
404+
* The `ChoiceToBooleanArrayTransformer`, `ChoicesToBooleanArrayTransformer`,
405+
`FixRadioInputListener`, and `FixCheckboxInputListener` classes were removed.
403406

404407
* The `choice_list` option of `ChoiceType` was removed.
405408

@@ -636,6 +639,11 @@ UPGRADE FROM 2.x to 3.0
636639
be removed in Symfony 3.0. Use the `debug:config`, `debug:container`,
637640
`debug:router`, `debug:translation` and `lint:yaml` commands instead.
638641

642+
* The base `Controller`class is now abstract.
643+
644+
* The visibility of all methods of the base `Controller` class has been changed from
645+
`public` to `protected`.
646+
639647
* The `getRequest` method of the base `Controller` class has been deprecated
640648
since Symfony 2.4 and must be therefore removed in 3.0. The only reliable
641649
way to get the `Request` object is to inject it in the action method.
@@ -1737,8 +1745,7 @@ UPGRADE FROM 2.x to 3.0
17371745

17381746
### WebProfiler
17391747

1740-
* The `profiler:import` and `profiler:export` commands have been deprecated and
1741-
will be removed in 3.0.
1748+
* The `profiler:import` and `profiler:export` commands have been removed.
17421749

17431750
* All the profiler storages different than `FileProfilerStorage` have been
17441751
removed. The removed classes are:

UPGRADE-3.1.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -202,7 +202,7 @@ Yaml
202202
After:
203203

204204
```php
205-
Yaml::dump(array('foo' => new A(), 'bar' => 1), 0, 0, false, Yaml::DUMP_OBJECT);
205+
Yaml::dump(array('foo' => new A(), 'bar' => 1), 0, 0, Yaml::DUMP_OBJECT);
206206
```
207207

208208
* The `!!php/object` tag to indicate dumped PHP objects has been deprecated

src/Symfony/Bundle/FrameworkBundle/Command/ServerStatusCommand.php

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313

1414
use Symfony\Component\Console\Input\InputArgument;
1515
use Symfony\Component\Console\Input\InputInterface;
16+
use Symfony\Component\Console\Input\InputOption;
1617
use Symfony\Component\Console\Output\OutputInterface;
1718
use Symfony\Component\Console\Style\SymfonyStyle;
1819

@@ -32,6 +33,7 @@ protected function configure()
3233
$this
3334
->setDefinition(array(
3435
new InputArgument('address', InputArgument::OPTIONAL, 'Address:port', '127.0.0.1:8000'),
36+
new InputOption('port', 'p', InputOption::VALUE_REQUIRED, 'Address port number', '8000'),
3537
))
3638
->setName('server:status')
3739
->setDescription('Outputs the status of the built-in web server for the given address')
@@ -46,6 +48,10 @@ protected function execute(InputInterface $input, OutputInterface $output)
4648
$io = new SymfonyStyle($input, $output);
4749
$address = $input->getArgument('address');
4850

51+
if (false === strpos($address, ':')) {
52+
$address = $address.':'.$input->getOption('port');
53+
}
54+
4955
// remove an orphaned lock file
5056
if (file_exists($this->getLockFile($address)) && !$this->isServerRunning($address)) {
5157
unlink($this->getLockFile($address));

src/Symfony/Bundle/FrameworkBundle/Controller/ControllerNameParser.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,7 @@ private function findAlternative($nonExistentBundleName)
142142
$lev = levenshtein($nonExistentBundleName, $bundleName);
143143
if ($lev <= strlen($nonExistentBundleName) / 3 && ($alternative === null || $lev < $shortest)) {
144144
$alternative = $bundleName;
145+
$shortest = $lev;
145146
}
146147
}
147148

src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1037,9 +1037,9 @@ private function registerPropertyInfoConfiguration(array $config, ContainerBuild
10371037

10381038
private function registerCacheConfiguration(array $config, ContainerBuilder $container, XmlFileLoader $loader)
10391039
{
1040-
$nonce = substr(str_replace('/', '-', base64_encode(md5(uniqid(mt_rand(), true), true))), 0, -2);
1041-
$container->getDefinition('cache.adapter.apcu')->replaceArgument(2, $nonce);
1042-
$container->getDefinition('cache.adapter.system')->replaceArgument(2, $nonce);
1040+
$version = substr(str_replace('/', '-', base64_encode(md5(uniqid(mt_rand(), true), true))), 0, -2);
1041+
$container->getDefinition('cache.adapter.apcu')->replaceArgument(2, $version);
1042+
$container->getDefinition('cache.adapter.system')->replaceArgument(2, $version);
10431043
$container->getDefinition('cache.adapter.filesystem')->replaceArgument(2, $config['directory']);
10441044

10451045
foreach (array('doctrine', 'psr6', 'redis') as $name) {

src/Symfony/Bundle/FrameworkBundle/Resources/config/cache.xml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@
2828
<tag name="monolog.logger" channel="cache" />
2929
<argument /> <!-- namespace -->
3030
<argument /> <!-- default lifetime -->
31-
<argument /> <!-- nonce -->
31+
<argument /> <!-- version -->
3232
<argument>%kernel.cache_dir%/pools</argument>
3333
<argument type="service" id="logger" on-invalid="ignore" />
3434
</service>
@@ -38,7 +38,7 @@
3838
<tag name="monolog.logger" channel="cache" />
3939
<argument /> <!-- namespace -->
4040
<argument /> <!-- default lifetime -->
41-
<argument /> <!-- nonce -->
41+
<argument /> <!-- version -->
4242
<call method="setLogger">
4343
<argument type="service" id="logger" on-invalid="ignore" />
4444
</call>

src/Symfony/Bundle/FrameworkBundle/Tests/Controller/ControllerNameParserTest.php

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -59,8 +59,8 @@ public function testBuild()
5959
{
6060
$parser = $this->createParser();
6161

62-
$this->assertEquals('FooBundle:Default:index', $parser->build('TestBundle\FooBundle\Controller\DefaultController::indexAction'), '->parse() converts a class::method string to a short a:b:c notation string');
63-
$this->assertEquals('FooBundle:Sub\Default:index', $parser->build('TestBundle\FooBundle\Controller\Sub\DefaultController::indexAction'), '->parse() converts a class::method string to a short a:b:c notation string');
62+
$this->assertEquals('FoooooBundle:Default:index', $parser->build('TestBundle\FooBundle\Controller\DefaultController::indexAction'), '->parse() converts a class::method string to a short a:b:c notation string');
63+
$this->assertEquals('FoooooBundle:Sub\Default:index', $parser->build('TestBundle\FooBundle\Controller\Sub\DefaultController::indexAction'), '->parse() converts a class::method string to a short a:b:c notation string');
6464

6565
try {
6666
$parser->build('TestBundle\FooBundle\Controller\DefaultController::index');
@@ -132,8 +132,9 @@ public function testInvalidBundleName($bundleName, $suggestedBundleName)
132132
public function getInvalidBundleNameTests()
133133
{
134134
return array(
135-
array('FoodBundle:Default:index', 'FooBundle:Default:index'),
136-
array('CrazyBundle:Default:index', false),
135+
'Alternative will be found using levenshtein' => array('FoodBundle:Default:index', 'FooBundle:Default:index'),
136+
'Alternative will be found using partial match' => array('FabpotFooBund:Default:index', 'FabpotFooBundle:Default:index'),
137+
'Bundle does not exist at all' => array('CrazyBundle:Default:index', false),
137138
);
138139
}
139140

@@ -162,6 +163,7 @@ private function createParser()
162163
$bundles = array(
163164
'SensioFooBundle' => $this->getBundle('TestBundle\Fabpot\FooBundle', 'FabpotFooBundle'),
164165
'SensioCmsFooBundle' => $this->getBundle('TestBundle\Sensio\Cms\FooBundle', 'SensioCmsFooBundle'),
166+
'FoooooBundle' => $this->getBundle('TestBundle\FooBundle', 'FoooooBundle'),
165167
'FooBundle' => $this->getBundle('TestBundle\FooBundle', 'FooBundle'),
166168
'FabpotFooBundle' => $this->getBundle('TestBundle\Fabpot\FooBundle', 'FabpotFooBundle'),
167169
);

src/Symfony/Bundle/WebProfilerBundle/Resources/views/Profiler/base_js.html.twig

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,20 @@
8282
8383
requestStack = [],
8484
85+
extractHeaders = function(xhr, stackElement) {
86+
// Here we avoid to call xhr.getResponseHeader in order to
87+
// prevent polluting the console with CORS security errors
88+
var allHeaders = xhr.getAllResponseHeaders();
89+
var ret;
90+
91+
if (ret = allHeaders.match(/^x-debug-token:\s+(.*)$/im)) {
92+
stackElement.profile = ret[1];
93+
}
94+
if (ret = allHeaders.match(/^x-debug-token-link:\s+(.*)$/im)) {
95+
stackElement.profilerUrl = ret[1];
96+
}
97+
},
98+
8599
renderAjaxRequests = function() {
86100
var requestCounter = document.querySelectorAll('.sf-toolbar-ajax-requests');
87101
if (!requestCounter.length) {
@@ -255,8 +269,7 @@
255269
stackElement.loading = false;
256270
stackElement.error = self.status < 200 || self.status >= 400;
257271
stackElement.statusCode = self.status;
258-
stackElement.profile = self.getResponseHeader("X-Debug-Token");
259-
stackElement.profilerUrl = self.getResponseHeader("X-Debug-Token-Link");
272+
extractHeaders(self, stackElement);
260273
261274
Sfjs.renderAjaxRequests();
262275
}

0 commit comments

Comments
 (0)
0