Skip to content

Commit 994fa92

Browse files
committed
class names are case sensitive (BC break)
1 parent f50dce6 commit 994fa92

9 files changed

+59
-39
lines changed

src/DI/Container.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -197,7 +197,7 @@ public function getByType($class, $need = TRUE)
197197
*/
198198
public function findByType($class, $autowired = TRUE)
199199
{
200-
$class = ltrim(strtolower($class), '\\');
200+
$class = ltrim($class, '\\');
201201
$meta = & $this->meta[self::TYPES];
202202
return array_merge(
203203
isset($meta[$class][TRUE]) ? $meta[$class][TRUE] : array(),

src/DI/ContainerBuilder.php

Lines changed: 29 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -164,15 +164,16 @@ public function getByType($class)
164164
return $this->currentService;
165165
}
166166

167-
$lower = ltrim(strtolower($class), '\\');
168-
if (!isset($this->classes[$lower][TRUE])) {
167+
$class = ltrim($class, '\\');
168+
if (!isset($this->classes[$class][TRUE])) {
169+
self::checkCase($class);
169170
return;
170171

171-
} elseif (count($this->classes[$lower][TRUE]) === 1) {
172-
return $this->classes[$lower][TRUE][0];
172+
} elseif (count($this->classes[$class][TRUE]) === 1) {
173+
return $this->classes[$class][TRUE][0];
173174

174175
} else {
175-
throw new ServiceCreationException("Multiple services of type $class found: " . implode(', ', $this->classes[$lower][TRUE]));
176+
throw new ServiceCreationException("Multiple services of type $class found: " . implode(', ', $this->classes[$class][TRUE]));
176177
}
177178
}
178179

@@ -184,7 +185,8 @@ public function getByType($class)
184185
*/
185186
public function findByType($class, $autowired = TRUE)
186187
{
187-
$class = ltrim(strtolower($class), '\\');
188+
$class = ltrim($class, '\\');
189+
self::checkCase($class);
188190
return array_merge(
189191
isset($this->classes[$class][TRUE]) ? $this->classes[$class][TRUE] : array(),
190192
!$autowired && isset($this->classes[$class][FALSE]) ? $this->classes[$class][FALSE] : array()
@@ -282,14 +284,14 @@ public function prepareClassList()
282284
// build auto-wiring list
283285
$excludedClasses = array();
284286
foreach ($this->excludedClasses as $class) {
285-
$excludedClasses += array_change_key_case(class_parents($class) + class_implements($class) + array($class => $class));
287+
self::checkCase($class);
288+
$excludedClasses += class_parents($class) + class_implements($class) + array($class => $class);
286289
}
287290

288291
$this->classes = array();
289292
foreach ($this->definitions as $name => $def) {
290293
if ($class = $def->getImplement() ?: $def->getClass()) {
291294
foreach (class_parents($class) + class_implements($class) + array($class) as $parent) {
292-
$parent = strtolower($parent);
293295
$this->classes[$parent][$def->isAutowired() && empty($excludedClasses[$parent])][] = (string) $name;
294296
}
295297
}
@@ -303,16 +305,16 @@ public function prepareClassList()
303305

304306
private function resolveImplement(ServiceDefinition $def, $name)
305307
{
306-
$implement = $def->getImplement();
307-
if (!interface_exists($implement)) {
308-
throw new ServiceCreationException("Interface $implement used in service '$name' not found.");
308+
$interface = $def->getImplement();
309+
if (!interface_exists($interface)) {
310+
throw new ServiceCreationException("Interface $interface used in service '$name' not found.");
309311
}
310-
$rc = Reflection\ClassType::from($implement);
312+
self::checkCase($interface);
313+
$rc = Reflection\ClassType::from($interface);
311314
$method = $rc->hasMethod('create') ? $rc->getMethod('create') : ($rc->hasMethod('get') ? $rc->getMethod('get') : NULL);
312315
if (count($rc->getMethods()) !== 1 || !$method || $method->isStatic()) {
313-
throw new ServiceCreationException("Interface $implement used in service '$name' must have just one non-static method create() or get().");
316+
throw new ServiceCreationException("Interface $interface used in service '$name' must have just one non-static method create() or get().");
314317
}
315-
$def->setImplement($rc->getName());
316318
$def->setImplementType($rc->hasMethod('create') ? 'create' : 'get');
317319

318320
if (!$def->getClass() && !$def->getEntity()) {
@@ -386,7 +388,7 @@ private function resolveServiceClass($name, $recursive = array())
386388
if (!class_exists($class) && !interface_exists($class)) {
387389
throw new ServiceCreationException("Class or interface $class used in service '$name' not found.");
388390
}
389-
$def->setClass(Reflection\ClassType::from($class)->getName());
391+
self::checkCase($class);
390392

391393
} elseif ($def->isAutowired()) {
392394
trigger_error("Type of service '$name' is unknown.", E_USER_NOTICE);
@@ -424,14 +426,14 @@ private function resolveEntityClass($entity, $recursive = array())
424426
}
425427

426428
$class = preg_replace('#[|\s].*#', '', $reflection->getAnnotation('return'));
427-
if ($class && $refClass) {
428-
$class = Reflection\AnnotationsParser::expandClassName($class, $refClass);
429+
if ($class) {
430+
$class = $refClass ? Reflection\AnnotationsParser::expandClassName($class, $refClass) : ltrim($class, '\\');
429431
}
430432
return $class;
431433

432434
} elseif ($service = $this->getServiceName($entity)) { // alias or factory
433435
if (Strings::contains($service, '\\')) { // @\Class
434-
return $service;
436+
return ltrim($service, '\\');
435437
}
436438
return $this->definitions[$service]->getImplement() ?: $this->resolveServiceClass($service, $recursive);
437439

@@ -440,7 +442,15 @@ private function resolveEntityClass($entity, $recursive = array())
440442
$name = array_slice(array_keys($recursive), -1);
441443
throw new ServiceCreationException("Class $entity used in service '$name[0]' not found or is not instantiable.");
442444
}
443-
return $entity;
445+
return ltrim($entity, '\\');
446+
}
447+
}
448+
449+
450+
private function checkCase($class)
451+
{
452+
if (class_exists($class) && ($rc = new \ReflectionClass($class)) && $class !== $rc->getName()) {
453+
throw new ServiceCreationException("Case mismatch on class name '$class', correct name is '{$rc->getName()}'.");
444454
}
445455
}
446456

tests/DI/Compiler.services.factory.phpt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ Assert::same( $container->getService('one'), $container->getService('calledServi
8787
Assert::type( 'Ipsum', $container->getService('calledServiceWithArgs') );
8888
Assert::notSame( $container->getService('one'), $container->getService('calledServiceWithArgs') );
8989

90-
Assert::type( 'stdClass', $container->getByType('stdClass') );
90+
Assert::type( 'stdClass', $container->getByType('\stdClass') );
9191

9292

9393
Assert::type( 'Ipsum', $container->getService('serviceAsParam') );

tests/DI/Compiler.services.tags.phpt

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,9 +28,9 @@ $prop->setAccessible(TRUE);
2828

2929
Assert::same(array(
3030
'types' => array(
31-
'stdclass' => array(1 => array('lorem')),
32-
'nette\\object' => array(1 => array('container')),
33-
'nette\\di\\container' => array(1 => array('container')),
31+
'stdClass' => array(1 => array('lorem')),
32+
'Nette\\Object' => array(1 => array('container')),
33+
'Nette\\DI\\Container' => array(1 => array('container')),
3434
),
3535
'services' => array('container' => 'Nette\\DI\\Container', 'lorem' => 'stdClass'),
3636
'tags' => array(

tests/DI/ContainerBuilder.accessor.phpt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,14 +42,14 @@ $builder->addDefinition('service2')
4242
->setFactory('stdClass');
4343

4444
$builder->addDefinition('one')
45-
->setImplement('stdClassAccessor')
45+
->setImplement('StdClassAccessor')
4646
->setClass('stdClass');
4747

4848
$builder->addDefinition('two')
4949
->setImplement('AnnotatedAccessor');
5050

5151
$builder->addDefinition('three')
52-
->setImplement('stdClassAccessor')
52+
->setImplement('StdClassAccessor')
5353
->setAutowired(FALSE)
5454
->setFactory('@service2');
5555

tests/DI/ContainerBuilder.error.phpt

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,3 +19,13 @@ $builder->addDefinition('one')
1919
Assert::exception(function() use ($builder) {
2020
$builder->generateClasses();
2121
}, 'Nette\InvalidStateException', "Service 'one': Expected function, method or property name, '1234' given.");
22+
23+
24+
25+
$builder = new DI\ContainerBuilder;
26+
$builder->addDefinition('one')
27+
->setClass('stdclass');
28+
29+
Assert::exception(function() use ($builder) {
30+
$builder->generateClasses();
31+
}, 'Nette\InvalidStateException', "Case mismatch on class name 'stdclass', correct name is 'stdClass'.");

tests/DI/ContainerBuilder.factory.params.phpt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,13 +19,13 @@ interface StdClassFactory
1919

2020
$builder = new DI\ContainerBuilder;
2121
$builder->addDefinition('one')
22-
->setImplement('stdClassFactory')
22+
->setImplement('StdClassFactory')
2323
->setFactory('stdClass')
2424
->addSetup('$a', array($builder::literal('$a')));
2525

2626
$builder->addDefinition('two')
2727
->setParameters(array('stdClass foo', 'array bar', 'foobar' => NULL))
28-
->setImplement('stdClassFactory')
28+
->setImplement('StdClassFactory')
2929
->setFactory('stdClass')
3030
->addSetup('$a', array($builder::literal('$foo')));
3131

tests/DI/ContainerBuilder.factory.phpt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ class FactoryReceiver
3131

3232
$builder = new DI\ContainerBuilder;
3333
$builder->addDefinition('one')
34-
->setImplement('stdClassFactory')
34+
->setImplement('StdClassFactory')
3535
->setFactory('stdClass');
3636

3737
$builder->addDefinition('two')

tests/DI/ContainerBuilder.getByType.phpt

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -33,14 +33,14 @@ $builder->addDefinition('three')
3333
// compile-time
3434
$builder->prepareClassList();
3535

36-
Assert::same( array('one'), $builder->findByType('service') );
37-
Assert::same( array('one'), $builder->findByType('service', FALSE) );
38-
Assert::same( array('two'), $builder->findByType('service2') );
39-
Assert::same( array('two', 'three'), $builder->findByType('service2', FALSE) );
36+
Assert::same( array('one'), $builder->findByType('\Service') );
37+
Assert::same( array('one'), $builder->findByType('Service', FALSE) );
38+
Assert::same( array('two'), $builder->findByType('Service2') );
39+
Assert::same( array('two', 'three'), $builder->findByType('Service2', FALSE) );
4040
Assert::same( array(), $builder->findByType('unknown') );
4141
Assert::same( array(), $builder->findByType('unknown', FALSE) );
4242

43-
Assert::same( 'one', $builder->getByType('service') );
43+
Assert::same( 'one', $builder->getByType('\Service') );
4444
Assert::null( $builder->getByType('unknown') );
4545
Assert::exception(function() use ($builder) {
4646
$builder->getByType('Nette\Object');
@@ -49,13 +49,13 @@ Assert::exception(function() use ($builder) {
4949

5050
$container = createContainer($builder);
5151

52-
Assert::type( 'Service', $container->getByType('service') );
52+
Assert::type( 'Service', $container->getByType('Service') );
5353
Assert::null( $container->getByType('unknown', FALSE) );
5454

55-
Assert::same( array('one'), $container->findByType('service') );
56-
Assert::same( array('one'), $container->findByType('service', FALSE) );
57-
Assert::same( array('two'), $container->findByType('service2') );
58-
Assert::same( array('two', 'three'), $container->findByType('service2', FALSE) );
55+
Assert::same( array('one'), $container->findByType('Service') );
56+
Assert::same( array('one'), $container->findByType('Service', FALSE) );
57+
Assert::same( array('two'), $container->findByType('Service2') );
58+
Assert::same( array('two', 'three'), $container->findByType('Service2', FALSE) );
5959
Assert::same( array(), $container->findByType('unknown') );
6060
Assert::same( array(), $container->findByType('unknown', FALSE) );
6161

0 commit comments

Comments
 (0)