Skip to content

Commit

Permalink
Merge pull request #327 from nextras/nette_3_0
Browse files Browse the repository at this point in the history
Add support for Nette 3.0 [closes #261]
  • Loading branch information
hrach committed Jan 6, 2019
2 parents 99ea55d + f1ee185 commit 9f6c117
Show file tree
Hide file tree
Showing 8 changed files with 93 additions and 58 deletions.
2 changes: 1 addition & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ before_script:

script:
- ./tests/run.sh -s $NTESTER_FLAGS ./tests/cases
- if [ "$TRAVIS_PHP_VERSION" == "7.2" ]; then vendor/bin/phpstan.phar analyse -l 7 -c .phpstan.neon src; fi
- if [ "$TRAVIS_PHP_VERSION" == "7.2" ] && [ "$dependencies" = "highest" ]; then vendor/bin/phpstan.phar analyse -l 7 -c .phpstan.neon src; fi

after_script:
- if [ "$TRAVIS_PHP_VERSION" == "7.2" ]; then
Expand Down
13 changes: 7 additions & 6 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,15 +20,16 @@
},
"require": {
"php": ">=7.1",
"nette/caching": "~2.5",
"nette/utils": "~2.5",
"nette/tokenizer": "~2.3",
"nette/caching": "~2.5 || ~3.0@rc",
"nette/utils": "~2.5 || ~3.0@rc",
"nette/tokenizer": "~2.3 || ~3.0@rc",
"nextras/dbal": "~3.0"
},
"require-dev": {
"nette/bootstrap": "~2.4",
"nette/di": "~2.4 >=2.4.7",
"nette/finder": "~2.4",
"nette/bootstrap": "~2.4 || ~3.0@rc",
"nette/di": "~2.4 >=2.4.10 || ~3.0@beta",
"nette/finder": "~2.4 || ~3.0@rc",
"nette/neon": "~2.4 || ~3.0@rc",
"nette/tester": "~2.1",
"marc-mabe/php-enum": "~3.0",
"mockery/mockery": "~1.2",
Expand Down
30 changes: 25 additions & 5 deletions src/Bridges/NetteDI/DIRepositoryFinder.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
namespace Nextras\Orm\Bridges\NetteDI;

use Nette\DI\ContainerBuilder;
use Nette\DI\ServiceDefinition;
use Nextras\Orm\InvalidStateException;
use Nextras\Orm\Repository\IRepository;


Expand Down Expand Up @@ -41,10 +41,27 @@ public function beforeCompile(): ?array
$repositories = [];
$repositoriesMap = [];
foreach ($types as $serviceName => $serviceDefinition) {
$serviceDefinition->addSetup('setModel', [$this->extension->prefix('@model')]);
$class = $serviceDefinition->getClass();
if ($serviceDefinition instanceof \Nette\DI\Definitions\FactoryDefinition) {
$serviceDefinition
->getResultDefinition()
->addSetup('setModel', [$this->extension->prefix('@model')]);
$name = $this->getRepositoryName($serviceName, $serviceDefinition);

} elseif ($serviceDefinition instanceof \Nette\DI\Definitions\ServiceDefinition || $serviceDefinition instanceof \Nette\DI\ServiceDefinition) {
$serviceDefinition
->addSetup('setModel', [$this->extension->prefix('@model')]);
$name = $this->getRepositoryName($serviceName, $serviceDefinition);

} else {
$type = $serviceDefinition->getType();
throw new InvalidStateException(
"It seems DI defined repository of type '$type' is not defined as one of supported DI services.
Orm can only work with ServiceDefinition or FactoryDefinition services."
);
}

$class = $serviceDefinition->getType();
assert($class !== null);
$name = $this->getRepositoryName($serviceName, $serviceDefinition);
$repositories[$name] = $class;
$repositoriesMap[$class] = $serviceName;
}
Expand All @@ -54,7 +71,10 @@ public function beforeCompile(): ?array
}


protected function getRepositoryName(string $serviceName, ServiceDefinition $serviceDefinition): string
/**
* @param \Nette\DI\Definitions\FactoryDefinition|\Nette\DI\Definitions\ServiceDefinition|\Nette\DI\ServiceDefinition $serviceDefinition
*/
protected function getRepositoryName(string $serviceName, $serviceDefinition): string
{
return $serviceName;
}
Expand Down
10 changes: 5 additions & 5 deletions src/Bridges/NetteDI/OrmExtension.php
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ protected function setupDependencyProvider()
}

$this->builder->addDefinition($providerName)
->setClass(DependencyProvider::class);
->setType(DependencyProvider::class);
}


Expand All @@ -114,7 +114,7 @@ protected function setupDbalMapperDependencies()
$name = $this->prefix('mapperCoordinator');
if (!$this->builder->hasDefinition($name)) {
$this->builder->addDefinition($name)
->setClass(DbalMapperCoordinator::class);
->setType(DbalMapperCoordinator::class);
}
}

Expand All @@ -127,7 +127,7 @@ protected function setupMetadataParserFactory()
}

$this->builder->addDefinition($factoryName)
->setClass(MetadataParserFactory::class);
->setType(MetadataParserFactory::class);
}


Expand All @@ -139,7 +139,7 @@ protected function setupMetadataStorage(array $entityClassMap)
}

$this->builder->addDefinition($metadataName)
->setClass(MetadataStorage::class)
->setType(MetadataStorage::class)
->setArguments([
'entityClassesMap' => $entityClassMap,
'cache' => $this->prefix('@cache'),
Expand All @@ -157,7 +157,7 @@ protected function setupModel(string $modelClass, array $repositoriesConfig)
}

$this->builder->addDefinition($modelName)
->setClass($modelClass)
->setType($modelClass)
->setArguments([
'configuration' => $repositoriesConfig,
'repositoryLoader' => $this->prefix('@repositoryLoader'),
Expand Down
4 changes: 3 additions & 1 deletion src/Bridges/NetteDI/PhpDocRepositoryFinder.php
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,9 @@ protected function findRepositories(string $modelClass): array
}

$modelReflection = new \ReflectionClass($modelClass);
$this->builder->addDependency($modelReflection->getFileName());
$classFileName = $modelReflection->getFileName();
assert($classFileName !== false);
$this->builder->addDependency($classFileName);

$repositories = [];
preg_match_all(
Expand Down
79 changes: 41 additions & 38 deletions src/Entity/Reflection/ModifierParser.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
use Nette\Tokenizer\Tokenizer;
use Nette\Utils\Reflection;
use Nextras\Orm\InvalidModifierDefinitionException;
use Nextras\Orm\InvalidStateException;
use ReflectionClass;


Expand Down Expand Up @@ -65,15 +66,15 @@ public function matchModifiers(string $input): array
*/
public function parse(string $string, ReflectionClass $reflectionClass): array
{
$iterator = $this->lex($string, $reflectionClass);
$iterator = $this->lex($string);
return [
$name = $this->processName($iterator),
$this->processArgs($iterator, $name, false),
$this->processArgs($iterator, $reflectionClass, $name, false),
];
}


private function lex(string $input, ReflectionClass $reflectionClass): Stream
private function lex(string $input): Stream
{
try {
$tokens = $this->tokenizer->tokenize($input)->tokens;
Expand All @@ -85,33 +86,7 @@ private function lex(string $input, ReflectionClass $reflectionClass): Stream
return $token->type !== self::TOKEN_WHITESPACE;
});
$tokens = array_values($tokens);

$expanded = [];
foreach ($tokens as $token) {
if ($token->type === self::TOKEN_STRING) {
$token->value = stripslashes(substr($token->value, 1, -1));
$expanded[] = $token;

} elseif ($token->type === self::TOKEN_KEYWORD) {
$values = $this->processKeyword($token->value, $reflectionClass);
if (is_array($values)) {
$count = count($values) - 1;
foreach ($values as $i => $value) {
$expanded[] = new Token($value, $token->type, $token->offset);
if ($i !== $count) {
$expanded[] = new Token(',', self::TOKEN_SEPARATOR, -1);
}
}
} else {
$expanded[] = new Token($values, $token->type, $token->offset);
}

} else {
$expanded[] = $token;
}
}

return new Stream($expanded);
return new Stream($tokens);
}


Expand All @@ -135,13 +110,12 @@ private function processName(Stream $iterator): string
}


private function processArgs(Stream $iterator, string $modifierName, bool $inArray)
private function processArgs(Stream $iterator, \ReflectionClass $reflectionClass, string $modifierName, bool $inArray)
{
$result = [];
while (($currentToken = $iterator->nextToken()) !== null) {
assert($currentToken !== null);
$type = $currentToken->type;
$value = $currentToken->value;

if ($type === self::TOKEN_RBRACKET) {
if ($inArray) {
Expand All @@ -160,25 +134,37 @@ private function processArgs(Stream $iterator, string $modifierName, bool $inArr
$nextTokenType = $nextToken ? $nextToken->type : null;

if ($nextTokenType === self::TOKEN_LBRACKET) {
$result[$value] = $this->processArgs($iterator, $modifierName, true);
$value = $this->processValue($currentToken, $reflectionClass);
assert(!is_array($value));
$result[$value] = $this->processArgs($iterator, $reflectionClass, $modifierName, true);
} elseif ($nextTokenType === self::TOKEN_STRING || $nextTokenType === self::TOKEN_KEYWORD) {
$result[$value] = $iterator->currentValue();
$value = $this->processValue($currentToken, $reflectionClass);
assert(!is_array($value));
assert($nextToken !== null);
$result[$value] = $this->processValue($nextToken, $reflectionClass);
} elseif ($nextTokenType !== null) {
throw new InvalidModifierDefinitionException("Modifier {{$modifierName}} has invalid token after =.");
}
} else {
$iterator->position--;
$result[] = $value;
$value = $this->processValue($currentToken, $reflectionClass);
if (is_array($value)) {
foreach ($value as $subValue) {
$result[] = $subValue;
}
} else {
$result[] = $value;
}
}
} elseif ($type === self::TOKEN_LBRACKET) {
$result[] = $this->processArgs($iterator, $modifierName, true);
$result[] = $this->processArgs($iterator, $reflectionClass, $modifierName, true);
} else {
throw new InvalidModifierDefinitionException("Modifier {{$modifierName}} has invalid token, expected string, keyword, or array.");
}

$iterator->position++;
$currentToken = $iterator->currentToken();
$type = $currentToken ? $currentToken->type : null;
$currentToken2 = $iterator->currentToken();
$type = $currentToken2 ? $currentToken2->type : null;
if ($type === self::TOKEN_RBRACKET && $inArray) {
return $result;
} elseif ($type !== null && $type !== self::TOKEN_SEPARATOR) {
Expand All @@ -194,6 +180,23 @@ private function processArgs(Stream $iterator, string $modifierName, bool $inArr
}


/**
* @return mixed
*/
private function processValue(Token $token, \ReflectionClass $reflectionClass)
{
if ($token->type === self::TOKEN_STRING) {
return stripslashes(substr($token->value, 1, -1));

} elseif ($token->type === self::TOKEN_KEYWORD) {
return $this->processKeyword($token->value, $reflectionClass);

} else {
throw new InvalidStateException();
}
}


private function processKeyword(string $value, ReflectionClass $reflectionClass)
{
if (strcasecmp($value, 'true') === 0) {
Expand Down
11 changes: 10 additions & 1 deletion src/Mapper/BaseMapper.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,9 @@

abstract class BaseMapper implements IMapper
{
use SmartObject;
use SmartObject {
__call as __smartCall;
}


/** @var string */
Expand Down Expand Up @@ -75,5 +77,12 @@ public function getStorageReflection(): IStorageReflection
}


// Workaround for "Declaration should be compatible" in PHP 7.1 and Nette 2.4 & 3.0
public function __call(string $name, array $args)
{
$this->__smartCall($name, $args);
}


abstract protected function createStorageReflection();
}
2 changes: 1 addition & 1 deletion src/TestHelper/TestMapper.php
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ public function addMethod(string $name, callable $callback)
}


public function __call($name, $args)
public function __call(string $name, array $args)
{
if (isset($this->methods[strtolower($name)])) {
return call_user_func_array($this->methods[strtolower($name)], $args);
Expand Down

0 comments on commit 9f6c117

Please sign in to comment.