/** * @param Database $database */ public function generate(Database $database) { foreach ($database->getTables() as $table) { // Create namespace and inner class $namespace = new PhpNamespace($this->resolver->resolveRepositoryNamespace($table)); $class = $namespace->addClass($this->resolver->resolveRepositoryName($table)); // Detect extends class if (($extends = $this->config->get('repository.extends')) !== NULL) { $namespace->addUse($extends); $class->setExtends($extends); } // Save file $this->generateFile($this->resolver->resolveRepositoryFilename($table), (string) $namespace); } // Generate abstract base class if ($this->config->get('repository.extends') !== NULL) { // Create abstract class $namespace = new PhpNamespace($this->config->get('repository.namespace')); $class = $namespace->addClass(Helpers::extractShortName($this->config->get('repository.extends'))); $class->setAbstract(TRUE); // Add extends from ORM/Repository $extends = $this->config->get('nextras.orm.class.repository'); $namespace->addUse($extends); $class->setExtends($extends); // Save file $this->generateFile($this->resolver->resolveFilename(Helpers::extractShortName($this->config->get('repository.extends')), $this->config->get('repository.folder')), (string) $namespace); } }
public function afterCompile(ClassType $class) { $container = $this->getContainerBuilder(); $config = $this->getConfig($this->defaults); if ($config['panel'] && $container->parameters['debugMode']) { $init = $class->methods['initialize']; $init->addBody(Helpers::format('Foowie\\Cron\\Diagnostics\\Panel::register($this->getByType(?), $this->getByType(?));', 'Foowie\\Cron\\ICron', 'Nette\\Http\\Request')); } }
/** * @param string $content * @param string $id */ protected function write($content, $id) { $content = is_string($content) ? $content : Code\Helpers::dump($content); $file = $this->logDir . '/curl_' . @date('Y-m-d-H-i-s') . '_' . $id . '.dat'; foreach (Nette\Utils\Finder::findFiles("curl_*_{$id}.dat")->in($this->logDir) as $item) { /** @var \SplFileInfo $item */ $file = $item->getRealpath(); } if (!@file_put_contents($file, $content, FILE_APPEND)) { Debugger::log("Logging to {$file} failed."); } }
public function afterCompile(Code\ClassType $class) { $container = $this->getContainerBuilder(); if ($eventManager = $container->getByType('Kdyby\\Events\\EventManager')) { $methodName = 'createService' . ucfirst($this->name) . '__command'; $method = $class->methods[$methodName]; $body = explode(';', substr(trim($method->getBody()), 0, -1)); $return = array_pop($body); $body[] = Code\Helpers::format(PHP_EOL . '$service->setEventManager($this->getService(?))', $eventManager); $body[] = $return; $method->setBody(implode(';', $body) . ';'); } }
public function afterCompile(Nette\PhpGenerator\ClassType $class) { $config = $this->getConfig($this->defaults); Nette\Utils\Validators::assertField($config, 'enabled', 'boolean'); Nette\Utils\Validators::assertField($config, 'accessToken', 'string'); Nette\Utils\Validators::assertField($config, 'roomName', 'string'); Nette\Utils\Validators::assertField($config, 'filters', 'array'); if (!$config['enabled']) { return; } unset($config['enabled']); $init = $class->methods['initialize']; $init->addBody(Nette\PhpGenerator\Helpers::format(' $logger = new Vysinsky\\HipChat\\Bridges\\Tracy\\Logger(?, ?, ?, ?); Tracy\\Debugger::setLogger($logger); ', $config['accessToken'], $config['roomName'], $config['filters'], $config['linkFactory'])); }
/** * @param Database $database */ public function generate(Database $database) { foreach ($database->getTables() as $table) { // Create namespace and inner class $namespace = new PhpNamespace($this->resolver->resolveEntityNamespace($table)); $class = $namespace->addClass($this->resolver->resolveEntityName($table)); // Detect extends class if (($extends = $this->config->get('entity.extends')) === NULL) { $extends = $this->config->get('nextras.orm.class.entity'); } // Add namespace and extends class $namespace->addUse($extends); $class->setExtends($extends); // Add table columns foreach ($table->getColumns() as $column) { if ($this->config->get('generator.entity.exclude.primary')) { if ($column->isPrimary()) { continue; } } foreach ($this->decorators as $decorator) { $decorator->doDecorate($column, $class, $namespace); } } // Save file $this->generateFile($this->resolver->resolveEntityFilename($table), (string) $namespace); } // Generate abstract base class if ($this->config->get('entity.extends') !== NULL) { // Create abstract class $namespace = new PhpNamespace($this->config->get('entity.namespace')); $class = $namespace->addClass(Helpers::extractShortName($this->config->get('entity.extends'))); $class->setAbstract(TRUE); // Add extends from ORM/Entity $extends = $this->config->get('nextras.orm.class.entity'); $namespace->addUse($extends); $class->setExtends($extends); // Save file $this->generateFile($this->resolver->resolveFilename(Helpers::extractShortName($this->config->get('entity.extends')), $this->config->get('entity.folder')), (string) $namespace); } }
public function afterCompile(Nette\PhpGenerator\ClassType $class) { $initialize = $class->getMethod('initialize'); $container = $this->getContainerBuilder(); if ($this->debugMode && $this->config['debugger']) { $initialize->addBody($container->formatPhp('?;', array(new Nette\DI\Statement('@Tracy\\Bar::addPanel', array(new Nette\DI\Statement('Nette\\Bridges\\DITracy\\ContainerPanel')))))); } foreach (array_filter($container->findByTag('run')) as $name => $on) { $initialize->addBody('$this->getService(?);', array($name)); } if (!empty($this->config['accessors'])) { $definitions = $container->getDefinitions(); ksort($definitions); foreach ($definitions as $name => $def) { if (Nette\PhpGenerator\Helpers::isIdentifier($name)) { $type = $def->getImplement() ?: $def->getClass(); $class->addDocument("@property {$type} \${$name}"); } } } }
/** * @return self */ public function addBody($statement, array $args = NULL) { $this->body .= (func_num_args() > 1 ? Helpers::formatArgs($statement, $args) : $statement) . "\n"; return $this; }
/** * Formats PHP statement. * @return string * @internal */ public function formatPhp($statement, $args) { array_walk_recursive($args, function (&$val) { if ($val instanceof Statement) { $val = self::literal($this->formatStatement($val)); } elseif ($val === $this) { $val = self::literal('$this'); } elseif ($val instanceof ServiceDefinition) { $val = '@' . current(array_keys($this->getDefinitions(), $val, TRUE)); } if (!is_string($val)) { return; } elseif (substr($val, 0, 2) === '@@') { $val = substr($val, 1); } elseif (substr($val, 0, 1) === '@') { $pair = explode('::', $val, 2); $name = $this->getServiceName($pair[0]); if (isset($pair[1]) && preg_match('#^[A-Z][A-Z0-9_]*\\z#', $pair[1], $m)) { $val = $this->getDefinition($name)->getClass() . '::' . $pair[1]; } else { if ($name === self::THIS_CONTAINER) { $val = '$this'; } elseif ($name === $this->currentService) { $val = '$service'; } else { $val = $this->formatStatement(new Statement(['@' . self::THIS_CONTAINER, 'getService'], [$name])); } $val .= isset($pair[1]) ? PhpHelpers::formatArgs('->?', [$pair[1]]) : ''; } $val = self::literal($val); } }); return PhpHelpers::formatArgs($statement, $args); }
/** * @return string PHP code */ public function __toString() : string { $uses = []; asort($this->uses); foreach ($this->uses as $alias => $name) { $useNamespace = Helpers::extractNamespace($name); if ($this->name !== $useNamespace) { if ($alias === $name || substr($name, -(strlen($alias) + 1)) === '\\' . $alias) { $uses[] = "use {$name};"; } else { $uses[] = "use {$name} as {$alias};"; } } } $body = ($uses ? implode("\n", $uses) . "\n\n" : '') . implode("\n", $this->classes); if ($this->bracketedSyntax) { return 'namespace' . ($this->name ? ' ' . $this->name : '') . " {\n\n" . Strings::indent($body) . "\n}\n"; } else { return ($this->name ? "namespace {$this->name};\n\n" : '') . $body; } }
public function afterCompile(Nette\PhpGenerator\ClassType $class) { $initialize = $class->methods['initialize']; $container = $this->getContainerBuilder(); $config = $this->getConfig($this->defaults); // debugger foreach (array('email', 'editor', 'browser', 'strictMode', 'maxLen', 'maxDepth', 'showLocation', 'scream') as $key) { if (isset($config['debugger'][$key])) { $initialize->addBody('Nette\\Diagnostics\\Debugger::$? = ?;', array($key, $config['debugger'][$key])); } } if ($container->parameters['debugMode']) { if ($config['container']['debugger']) { $config['debugger']['bar'][] = 'Nette\\DI\\Diagnostics\\ContainerPanel'; } foreach ((array) $config['debugger']['bar'] as $item) { $initialize->addBody($container->formatPhp('Nette\\Diagnostics\\Debugger::getBar()->addPanel(?);', Nette\DI\Compiler::filterArguments(array(is_string($item) ? new Nette\DI\Statement($item) : $item)))); } foreach ((array) $config['debugger']['blueScreen'] as $item) { $initialize->addBody($container->formatPhp('Nette\\Diagnostics\\Debugger::getBlueScreen()->addPanel(?);', Nette\DI\Compiler::filterArguments(array($item)))); } } if (!empty($container->parameters['tempDir'])) { $initialize->addBody('Nette\\Caching\\Storages\\FileStorage::$useDirectories = ?;', array($this->checkTempDir($container->expand('%tempDir%/cache')))); } foreach ((array) $config['forms']['messages'] as $name => $text) { $initialize->addBody('Nette\\Forms\\Rules::$defaultMessages[Nette\\Forms\\Form::?] = ?;', array($name, $text)); } if ($config['session']['autoStart'] === 'smart') { $initialize->addBody('$this->getByType("Nette\\Http\\Session")->exists() && $this->getByType("Nette\\Http\\Session")->start();'); } elseif ($config['session']['autoStart']) { $initialize->addBody('$this->getByType("Nette\\Http\\Session")->start();'); } if ($config['latte']['xhtml']) { $initialize->addBody('Nette\\Utils\\Html::$xhtml = ?;', array(TRUE)); } if (isset($config['security']['frames']) && $config['security']['frames'] !== TRUE) { $frames = $config['security']['frames']; if ($frames === FALSE) { $frames = 'DENY'; } elseif (preg_match('#^https?:#', $frames)) { $frames = "ALLOW-FROM {$frames}"; } $initialize->addBody('header(?);', array("X-Frame-Options: {$frames}")); } foreach ($container->findByTag('run') as $name => $on) { if ($on) { $initialize->addBody('$this->getService(?);', array($name)); } } if (!empty($config['container']['accessors'])) { $definitions = $container->definitions; ksort($definitions); foreach ($definitions as $name => $def) { if (Nette\PhpGenerator\Helpers::isIdentifier($name)) { $type = $def->implement ?: $def->class; $class->addDocument("@property {$type} \${$name}"); } } } $initialize->addBody("@header('Content-Type: text/html; charset=utf-8');"); $initialize->addBody('Nette\\Utils\\SafeStream::register();'); }
/** * @param string * @return ClassType */ public function addTrait(string $name) : ClassType { return $this->addNamespace(Helpers::extractNamespace($name))->addTrait(Helpers::extractShortName($name)); }
protected function processConnection($name, array $defaults, $isDefault = FALSE) { $builder = $this->getContainerBuilder(); $config = $this->resolveConfig($defaults, $this->connectionDefaults, $this->managerDefaults); if ($isDefault) { $builder->parameters[$this->name]['dbal']['defaultConnection'] = $name; } if (isset($defaults['connection'])) { return $this->prefix('@' . $defaults['connection'] . '.connection'); } // config $configuration = $builder->addDefinition($this->prefix($name . '.dbalConfiguration'))->setClass('Doctrine\\DBAL\\Configuration')->addSetup('setResultCacheImpl', array($this->processCache($config['resultCache'], $name . '.dbalResult')))->addSetup('setSQLLogger', array(new Statement('Doctrine\\DBAL\\Logging\\LoggerChain')))->addSetup('setFilterSchemaAssetsExpression', array($config['schemaFilter']))->setAutowired(FALSE)->setInject(FALSE); // types Validators::assertField($config, 'types', 'array'); $schemaTypes = $dbalTypes = array(); foreach ($config['types'] as $dbType => $className) { $typeInst = Code\Helpers::createObject($className, array()); /** @var Doctrine\DBAL\Types\Type $typeInst */ $dbalTypes[$typeInst->getName()] = $className; $schemaTypes[$dbType] = $typeInst->getName(); } // connection $options = array_diff_key($config, array_flip(array('types', 'resultCache', 'connection', 'logging'))); $connection = $builder->addDefinition($connectionServiceId = $this->prefix($name . '.connection'))->setClass('Kdyby\\Doctrine\\Connection')->setFactory('Kdyby\\Doctrine\\Connection::create', array($options, $this->prefix('@' . $name . '.dbalConfiguration'), $this->prefix('@' . $name . '.evm')))->addSetup('setSchemaTypes', array($schemaTypes))->addSetup('setDbalTypes', array($dbalTypes))->addTag(self::TAG_CONNECTION)->setAutowired($isDefault)->setInject(FALSE); /** @var Nette\DI\ServiceDefinition $connection */ $this->configuredConnections[$name] = $connectionServiceId; if (!is_bool($config['logging'])) { $fileLogger = new Statement('Kdyby\\Doctrine\\Diagnostics\\FileLogger', array($builder->expand($config['logging']))); $configuration->addSetup('$service->getSQLLogger()->addLogger(?)', array($fileLogger)); } elseif ($config['logging']) { $connection->addSetup('Kdyby\\Doctrine\\Diagnostics\\Panel::register', array('@self')); } return $this->prefix('@' . $name . '.connection'); }
/** * Formats PHP statement. * @return string * @internal */ public function formatPhp($statement, $args) { array_walk_recursive($args, function (&$val) { if ($val instanceof Statement) { $val = new PhpLiteral($this->formatStatement($val)); } elseif (is_string($val) && substr($val, 0, 2) === '@@') { // escaped text @@ $val = substr($val, 1); } elseif (is_string($val) && substr($val, 0, 1) === '@' && strlen($val) > 1) { // service reference $name = substr($val, 1); if ($name === ContainerBuilder::THIS_CONTAINER) { $val = new PhpLiteral('$this'); } elseif ($name === $this->currentService) { $val = new PhpLiteral('$service'); } else { $val = new PhpLiteral($this->formatStatement(new Statement(['@' . ContainerBuilder::THIS_CONTAINER, 'getService'], [$name]))); } } }); return PhpHelpers::formatArgs($statement, $args); }
private function doSerializeValueResolve(ContainerBuilder $builder, $expression) { if ($expression instanceof Code\PhpLiteral) { $expression = self::resolveExpression($expression); } elseif (substr($expression, 0, 1) === '%') { $expression = $builder->expand($expression); } elseif (substr($expression, 0, 1) === '$') { $expression = new Code\PhpLiteral($expression); } else { if (!($m = self::shiftAccessPath($expression))) { return $expression; // it's probably some kind of expression } else { if ($m['context'] === 'this') { $targetObject = '$this'; } elseif ($m['context'] === 'context' && ($p = self::shiftAccessPath($m['path']))) { if (class_exists($p['context']) || interface_exists($p['context'])) { $targetObject = Code\Helpers::format('$this->_kdyby_aopContainer->getByType(?)', $p['context']); } else { $targetObject = Code\Helpers::format('$this->_kdyby_aopContainer->getService(?)', $p['context']); } $m['path'] = $p['path']; } else { throw new Kdyby\Aop\NotImplementedException(); } $expression = Code\Helpers::format('PropertyAccess::createPropertyAccessor()->getValue(?, ?)', new Code\PhpLiteral($targetObject), $m['path']); } $expression = new Code\PhpLiteral($expression); } return $expression; }
/** * Formats PHP statement. * @return string */ public function formatPhp($statement, $args) { $that = $this; array_walk_recursive($args, function (&$val) use($that) { if ($val instanceof Statement) { $val = ContainerBuilder::literal($that->formatStatement($val)); } elseif ($val === $that) { $val = ContainerBuilder::literal('$this'); } elseif ($val instanceof ServiceDefinition) { $val = '@' . current(array_keys($that->definitions, $val, TRUE)); } elseif (is_string($val) && preg_match('#^[\\w\\\\]*::[A-Z][A-Z0-9_]*\\z#', $val, $m)) { $val = ContainerBuilder::literal(ltrim($val, ':')); } if (is_string($val) && substr($val, 0, 1) === '@') { $pair = explode('::', $val, 2); $name = $that->getServiceName($pair[0]); if (isset($pair[1]) && preg_match('#^[A-Z][A-Z0-9_]*\\z#', $pair[1], $m)) { $val = $that->definitions[$name]->class . '::' . $pair[1]; } else { if ($name === ContainerBuilder::THIS_CONTAINER) { $val = '$this'; } elseif ($name === $that->currentService) { $val = '$service'; } else { $val = $that->formatStatement(new Statement(array('@' . ContainerBuilder::THIS_CONTAINER, 'getService'), array($name))); } $val .= isset($pair[1]) ? PhpHelpers::formatArgs('->?', array($pair[1])) : ''; } $val = ContainerBuilder::literal($val); } }); return PhpHelpers::formatArgs($statement, $args); }
/** * Generates configuration in PHP format. * @return string */ public function dump(array $data) { return "<?php // generated by Nette \nreturn " . Nette\PhpGenerator\Helpers::dump($data) . ';'; }
/** * @param Translator $translator * @param MessageCatalogueInterface[] $availableCatalogues * @param string $locale * @return string */ protected function compilePhpCache(Translator $translator, array &$availableCatalogues, $locale) { $fallbackContent = ''; $current = new Code\PhpLiteral(''); foreach ($this->fallbackResolver->compute($translator, $locale) as $fallback) { $fallbackSuffix = new Code\PhpLiteral(ucfirst(preg_replace('~[^a-z0-9_]~i', '_', $fallback))); $fallbackContent .= Code\Helpers::format(<<<EOF \$catalogue? = new MessageCatalogue(?, ?); \$catalogue?->addFallbackCatalogue(\$catalogue?); EOF , $fallbackSuffix, $fallback, $availableCatalogues[$fallback]->all(), $current, $fallbackSuffix); $current = $fallbackSuffix; } $content = Code\Helpers::format(<<<EOF use Kdyby\\Translation\\MessageCatalogue; \$catalogue = new MessageCatalogue(?, ?); ? return \$catalogue; EOF , $locale, $availableCatalogues[$locale]->all(), new Code\PhpLiteral($fallbackContent)); return '<?php' . "\n\n" . $content; }
/** @return string PHP code */ public function __toString() { $parameters = array(); foreach ($this->parameters as $param) { $parameters[] = ($param->typeHint ? $param->typeHint . ' ' : '') . ($param->reference ? '&' : '') . '$' . $param->name . ($param->optional ? ' = ' . Helpers::dump($param->defaultValue) : ''); } $uses = array(); foreach ($this->uses as $param) { $uses[] = ($param->reference ? '&' : '') . '$' . $param->name; } return ($this->documents ? str_replace("\n", "\n * ", "/**\n" . implode("\n", (array) $this->documents)) . "\n */\n" : '') . ($this->abstract ? 'abstract ' : '') . ($this->final ? 'final ' : '') . ($this->visibility ? $this->visibility . ' ' : '') . ($this->static ? 'static ' : '') . 'function' . ($this->returnReference ? ' &' : '') . ($this->name ? ' ' . $this->name : '') . '(' . implode(', ', $parameters) . ')' . ($this->uses ? ' use (' . implode(', ', $uses) . ')' : '') . ($this->abstract || $this->body === FALSE ? ';' : ($this->name ? "\n" : ' ') . "{\n" . Nette\Utils\Strings::indent(trim($this->body), 1) . "\n}"); }
public function afterCompile(Code\ClassType $class) { $init = $class->methods['initialize']; /** @hack This tries to add the event invokation right after the code, generated by NetteExtension. */ $foundNetteInitStart = $foundNetteInitEnd = FALSE; $lines = explode(";\n", trim($init->body)); $init->body = NULL; while (($line = array_shift($lines)) || $lines) { if ($foundNetteInitStart && !$foundNetteInitEnd && stripos($line, 'Nette\\') === FALSE && stripos($line, 'set_include_path') === FALSE && stripos($line, 'date_default_timezone_set') === FALSE) { $init->addBody(Code\Helpers::format('$this->getService(?)->createEvent(?)->dispatch($this);', $this->prefix('manager'), array('Nette\\DI\\Container', 'onInitialize'))); $foundNetteInitEnd = TRUE; } if (!$foundNetteInitEnd && (stripos($line, 'Nette\\') !== FALSE || stripos($line, 'set_include_path') !== FALSE || stripos($line, 'date_default_timezone_set') !== FALSE)) { $foundNetteInitStart = TRUE; } $init->addBody($line . ';'); } if (!$foundNetteInitEnd) { $init->addBody(Code\Helpers::format('$this->getService(?)->createEvent(?)->dispatch($this);', $this->prefix('manager'), array('Nette\\DI\\Container', 'onInitialize'))); } }
protected function processRepositoryFactoryEntities(Code\ClassType $class) { if (empty($this->postCompileRepositoriesQueue)) { return; } $dic = self::evalAndInstantiateContainer($class); foreach ($this->postCompileRepositoriesQueue as $manager => $items) { $config = $this->managerConfigs[$manager]; /** @var Kdyby\Doctrine\EntityManager $entityManager */ $entityManager = $dic->getService($this->configuredManagers[$manager]); /** @var Doctrine\ORM\Mapping\ClassMetadata $entityMetadata */ $metadataFactory = $entityManager->getMetadataFactory(); $allMetadata = []; foreach ($metadataFactory->getAllMetadata() as $entityMetadata) { if ($config['defaultRepositoryClassName'] === $entityMetadata->customRepositoryClassName || empty($entityMetadata->customRepositoryClassName)) { continue; } $allMetadata[ltrim($entityMetadata->customRepositoryClassName, '\\')] = $entityMetadata; } foreach ($items as $item) { if (!isset($allMetadata[$item[0]])) { throw new Nette\Utils\AssertionException(sprintf('Repository class %s have been found in DIC, but no entity has it assigned and it has no entity configured', $item[0])); } $entityMetadata = $allMetadata[$item[0]]; $serviceMethod = Nette\DI\Container::getMethodName($item[1]); $method = $class->getMethod($serviceMethod); $methodBody = $method->getBody(); $method->setBody(str_replace('"%entityName%"', Code\Helpers::format('?', $entityMetadata->getName()), $methodBody)); } } }
/** * @return string */ public function __toString() { $this->setBody(''); if (strtolower($this->getName()) === '__construct') { $this->addParameter('_kdyby_aopContainer')->setTypeHint('\\Nette\\DI\\Container'); $this->addBody('$this->_kdyby_aopContainer = $_kdyby_aopContainer;'); } $this->addBody('$__arguments = func_get_args(); $__exception = $__result = NULL;'); if ($this->before) { foreach ($this->before as $before) { $this->addBody($before); } } if ($this->afterThrowing || $this->after) { $this->addBody('try {'); } if (!$this->around) { $parentCall = Code\Helpers::format('$__result = call_user_func_array("parent::?", $__arguments);', $this->getName()); } else { $parentCall = Code\Helpers::format('$__around = new \\Kdyby\\Aop\\JoinPoint\\AroundMethod($this, __FUNCTION__, $__arguments);'); foreach ($this->around as $around) { $parentCall .= "\n" . $around; } $parentCall .= "\n" . Code\Helpers::format('$__result = $__around->proceed();'); } $this->addBody($this->afterThrowing || $this->after ? Nette\Utils\Strings::indent($parentCall) : $parentCall); if ($this->afterThrowing || $this->after) { $this->addBody('} catch (\\Exception $__exception) {'); } if ($this->afterThrowing) { foreach ($this->afterThrowing as $afterThrowing) { $this->addBody(Nette\Utils\Strings::indent($afterThrowing)); } } if ($this->afterThrowing || $this->after) { $this->addBody('}'); } if ($this->afterReturning) { if ($this->afterThrowing || $this->after) { $this->addBody('if (empty($__exception)) {'); } foreach ($this->afterReturning as $afterReturning) { $this->addBody($this->afterThrowing || $this->after ? Nette\Utils\Strings::indent($afterReturning) : $afterReturning); } if ($this->afterThrowing || $this->after) { $this->addBody('}'); } } if ($this->after) { foreach ($this->after as $after) { $this->addBody($after); } } if ($this->afterThrowing || $this->after) { $this->addBody('if ($__exception) { throw $__exception; }'); } $this->addBody('return $__result;'); return parent::__toString(); }
/** @return string PHP code */ public function __toString() { $consts = array(); foreach ($this->consts as $name => $value) { $consts[] = "const {$name} = " . Helpers::dump($value) . ";\n"; } $properties = array(); foreach ($this->properties as $property) { $properties[] = ($property->documents ? str_replace("\n", "\n * ", "/**\n" . implode("\n", (array) $property->documents)) . "\n */\n" : '') . $property->visibility . ($property->static ? ' static' : '') . ' $' . $property->name . ($property->value === NULL ? '' : ' = ' . Helpers::dump($property->value)) . ";\n"; } return Strings::normalize(($this->documents ? str_replace("\n", "\n * ", "/**\n" . implode("\n", (array) $this->documents)) . "\n */\n" : '') . ($this->abstract ? 'abstract ' : '') . ($this->final ? 'final ' : '') . $this->type . ' ' . $this->name . ' ' . ($this->extends ? 'extends ' . implode(', ', (array) $this->extends) . ' ' : '') . ($this->implements ? 'implements ' . implode(', ', (array) $this->implements) . ' ' : '') . "\n{\n\n" . Strings::indent(($this->traits ? "use " . implode(', ', (array) $this->traits) . ";\n\n" : '') . ($this->consts ? implode('', $consts) . "\n\n" : '') . ($this->properties ? implode("\n", $properties) . "\n\n" : '') . implode("\n\n\n", $this->methods), 1) . "\n\n}") . "\n"; }
/** * @param \Exception|RedisClientException $e * * @return array */ public static function renderException($e) { if ($e instanceof RedisClientException) { $panel = NULL; if ($e->request) { $panel .= '<h3>Redis Request</h3>' . '<pre class="nette-dump"><span class="php-string">' . nl2br(htmlSpecialChars(implode(' ', $e->request))) . '</span></pre>'; } if ($e->response) { $response = Code\Helpers::dump($e->response); $panel .= '<h3>Redis Response (' . strlen($e->response) . ')</h3>' . '<pre class="nette-dump"><span class="php-string">' . htmlSpecialChars($response) . '</span></pre>'; } if ($panel !== NULL) { $panel = ['tab' => 'Redis Response', 'panel' => $panel]; } return $panel; } }
/** * @return string PHP code */ public function __toString() { $consts = array(); foreach ($this->consts as $name => $value) { $consts[] = "const {$name} = " . Helpers::dump($value) . ";\n"; } $properties = array(); foreach ($this->properties as $property) { $doc = str_replace("\n", "\n * ", implode("\n", (array) $property->getDocuments())); $properties[] = ($property->getDocuments() ? strpos($doc, "\n") === FALSE ? "/** {$doc} */\n" : "/**\n * {$doc}\n */\n" : '') . $property->getVisibility() . ($property->isStatic() ? ' static' : '') . ' $' . $property->getName() . ($property->value === NULL ? '' : ' = ' . Helpers::dump($property->value)) . ";\n"; } $extends = $implements = $traits = array(); if ($this->namespace) { foreach ((array) $this->extends as $name) { $extends[] = $this->namespace->unresolveName($name); } foreach ((array) $this->implements as $name) { $implements[] = $this->namespace->unresolveName($name); } foreach ((array) $this->traits as $name) { $traits[] = $this->namespace->unresolveName($name); } } else { $extends = (array) $this->extends; $implements = (array) $this->implements; $traits = (array) $this->traits; } foreach ($this->methods as $method) { $method->setNamespace($this->namespace); } return Strings::normalize(($this->documents ? str_replace("\n", "\n * ", "/**\n" . implode("\n", (array) $this->documents)) . "\n */\n" : '') . ($this->abstract ? 'abstract ' : '') . ($this->final ? 'final ' : '') . $this->type . ' ' . $this->name . ' ' . ($this->extends ? 'extends ' . implode(', ', $extends) . ' ' : '') . ($this->implements ? 'implements ' . implode(', ', $implements) . ' ' : '') . "\n{\n\n" . Strings::indent(($this->traits ? 'use ' . implode(', ', $traits) . ";\n\n" : '') . ($this->consts ? implode('', $consts) . "\n\n" : '') . ($this->properties ? implode("\n", $properties) . "\n\n" : '') . implode("\n\n\n", $this->methods), 1) . "\n\n}") . "\n"; }
/** * @param string * @return ClassType */ public function addTrait($name) { return $this->addNamespace(Helpers::extractNamespace($name))->addTrait(Helpers::extractShortName($name)); }
/** * @return string PHP code */ public function __toString() { $consts = array(); foreach ($this->consts as $name => $value) { $consts[] = "const {$name} = " . Helpers::dump($value) . ";\n"; } $properties = array(); foreach ($this->properties as $property) { $doc = str_replace("\n", "\n * ", implode("\n", $property->getDocuments())); $properties[] = ($property->getDocuments() ? strpos($doc, "\n") === FALSE ? "/** {$doc} */\n" : "/**\n * {$doc}\n */\n" : '') . $property->getVisibility() . ($property->isStatic() ? ' static' : '') . ' $' . $property->getName() . ($property->value === NULL ? '' : ' = ' . Helpers::dump($property->value)) . ";\n"; } $namespace = $this->namespace; $mapper = function (array $arr) use($namespace) { return $namespace ? array_map(array($namespace, 'unresolveName'), $arr) : $arr; }; return Strings::normalize(($this->documents ? str_replace("\n", "\n * ", "/**\n" . implode("\n", $this->documents)) . "\n */\n" : '') . ($this->abstract ? 'abstract ' : '') . ($this->final ? 'final ' : '') . $this->type . ' ' . $this->name . ' ' . ($this->extends ? 'extends ' . implode(', ', $mapper((array) $this->extends)) . ' ' : '') . ($this->implements ? 'implements ' . implode(', ', $mapper($this->implements)) . ' ' : '') . "\n{\n" . Strings::indent(($this->traits ? 'use ' . implode(";\nuse ", $mapper($this->traits)) . ";\n\n" : '') . ($this->consts ? implode('', $consts) . "\n" : '') . ($this->properties ? implode("\n", $properties) . "\n" : '') . ($this->methods ? "\n" . implode("\n\n\n", $this->methods) . "\n\n" : ''), 1) . '}') . "\n"; }
/** * @return Statement */ public function completeStatement(Statement $statement) { $entity = $this->normalizeEntity($statement->getEntity()); $arguments = $statement->arguments; if (is_string($entity) && Strings::contains($entity, '?')) { // PHP literal } elseif ($service = $this->getServiceName($entity)) { // factory calling $params = []; foreach ($this->definitions[$service]->parameters as $k => $v) { $params[] = preg_replace('#\\w+\\z#', '\\$$0', is_int($k) ? $v : $k) . (is_int($k) ? '' : ' = ' . PhpHelpers::dump($v)); } $rm = new \ReflectionFunction(create_function(implode(', ', $params), '')); $arguments = Helpers::autowireArguments($rm, $arguments, $this); $entity = '@' . $service; } elseif ($entity === 'not') { // operator } elseif (is_string($entity)) { // class name if (!class_exists($entity)) { throw new ServiceCreationException("Class {$entity} not found."); } elseif ((new ReflectionClass($entity))->isAbstract()) { throw new ServiceCreationException("Class {$entity} is abstract."); } elseif (($rm = (new ReflectionClass($entity))->getConstructor()) !== NULL && !$rm->isPublic()) { $visibility = $rm->isProtected() ? 'protected' : 'private'; throw new ServiceCreationException("Class {$entity} has {$visibility} constructor."); } elseif ($constructor = (new ReflectionClass($entity))->getConstructor()) { $this->addDependency($constructor); $arguments = Helpers::autowireArguments($constructor, $arguments, $this); } elseif ($arguments) { throw new ServiceCreationException("Unable to pass arguments, class {$entity} has no constructor."); } } elseif (!Nette\Utils\Arrays::isList($entity) || count($entity) !== 2) { throw new ServiceCreationException(sprintf('Expected class, method or property, %s given.', PhpHelpers::dump($entity))); } elseif (!preg_match('#^\\$?' . PhpHelpers::PHP_IDENT . '(\\[\\])?\\z#', $entity[1])) { throw new ServiceCreationException("Expected function, method or property name, '{$entity['1']}' given."); } elseif ($entity[0] === '') { // globalFunc if (!Nette\Utils\Arrays::isList($arguments)) { throw new ServiceCreationException("Unable to pass specified arguments to {$entity['0']}."); } elseif (!function_exists($entity[1])) { throw new ServiceCreationException("Function {$entity['1']} doesn't exist."); } $rf = new \ReflectionFunction($entity[1]); $this->addDependency($rf); $arguments = Helpers::autowireArguments($rf, $arguments, $this); } else { if ($entity[0] instanceof Statement) { $entity[0] = $this->completeStatement($entity[0]); } elseif ($service = $this->getServiceName($entity[0])) { // service method $entity[0] = '@' . $service; } if ($entity[1][0] === '$') { // property getter, setter or appender Validators::assert($arguments, 'list:0..1', "setup arguments for '" . Nette\Utils\Callback::toString($entity) . "'"); if (!$arguments && substr($entity[1], -2) === '[]') { throw new ServiceCreationException("Missing argument for {$entity['1']}."); } } elseif ($class = empty($service) || $entity[1] === 'create' ? $this->resolveEntityClass($entity[0]) : $this->definitions[$service]->getClass()) { $arguments = $this->autowireArguments($class, $entity[1], $arguments); } } array_walk_recursive($arguments, function (&$val) { if ($val instanceof Statement) { $val = $this->completeStatement($val); } elseif ($val === $this) { trigger_error("Replace object ContainerBuilder in Statement arguments with '@container'.", E_USER_DEPRECATED); $val = self::literal('$this'); } elseif ($val instanceof ServiceDefinition) { $val = '@' . current(array_keys($this->getDefinitions(), $val, TRUE)); } elseif (is_string($val) && strlen($val) > 1 && $val[0] === '@' && $val[1] !== '@') { $pair = explode('::', $val, 2); $name = $this->getServiceName($pair[0]); if (!isset($pair[1])) { // @service $val = '@' . $name; } elseif (preg_match('#^[A-Z][A-Z0-9_]*\\z#', $pair[1], $m)) { // @service::CONSTANT $val = self::literal($this->getDefinition($name)->getClass() . '::' . $pair[1]); } else { // @service::property $val = new Statement(['@' . $name, '$' . $pair[1]]); } } }); return new Statement($entity, $arguments); }