composer.json 0000666 00000002101 13533704046 0007271 0 ustar 00 { "name": "nette/bootstrap", "description": "Nette Bootstrap", "homepage": "https://nette.org", "license": ["BSD-3-Clause", "GPL-2.0", "GPL-3.0"], "authors": [ { "name": "David Grudl", "homepage": "https://davidgrudl.com" }, { "name": "Nette Community", "homepage": "https://nette.org/contributors" } ], "require": { "php": ">=5.6.0", "nette/di": "~2.4.0", "nette/utils": "~2.4" }, "suggest": { "nette/robot-loader": "to use Configurator::createRobotLoader()", "tracy/tracy": "to use Configurator::enableTracy()" }, "require-dev": { "nette/application": "~2.3", "nette/caching": "~2.3", "nette/database": "~2.3", "nette/forms": "~2.3", "nette/http": "~2.4.0", "nette/mail": "~2.3", "nette/robot-loader": "~2.2", "nette/safe-stream": "~2.2", "nette/security": "~2.3", "nette/tester": "~2.0", "latte/latte": "~2.2", "tracy/tracy": "^2.4.1" }, "conflict": { "nette/nette": "<2.2" }, "autoload": { "classmap": ["src/"] }, "minimum-stability": "dev", "extra": { "branch-alias": { "dev-master": "2.4-dev" } } } contributing.md 0000666 00000002321 13533704046 0007604 0 ustar 00 How to contribute & use the issue tracker ========================================= The issue tracker is the preferred channel for bug reports, features requests and submitting pull requests, but please respect the following restrictions: * Please **do not** use the issue tracker for personal support requests (use [Nette forum](https://forum.nette.org) or [Stack Overflow](http://stackoverflow.com)). * Please **do not** derail or troll issues. Keep the discussion on topic and respect the opinions of others. * Use the GitHub **issue search** — check if the issue has already been reported. A good **bug report** shouldn't leave others needing to chase you up for more information. Please try to be as detailed as possible in your report. **Feature requests** are welcome. But take a moment to find out whether your idea fits with the scope and aims of the project. It's up to *you* to make a strong case to convince the project's developers of the merits of this feature. Nette welcomes **pull requests**. If you'd like to contribute, please take a moment to [read the guidelines](https://nette.org/en/contributing) in order to make the contribution process easy and effective for everyone involved. Thanks! license.md 0000666 00000005244 13533704046 0006526 0 ustar 00 Licenses ======== Good news! You may use Nette Framework under the terms of either the New BSD License or the GNU General Public License (GPL) version 2 or 3. The BSD License is recommended for most projects. It is easy to understand and it places almost no restrictions on what you can do with the framework. If the GPL fits better to your project, you can use the framework under this license. You don't have to notify anyone which license you are using. You can freely use Nette Framework in commercial projects as long as the copyright header remains intact. Please be advised that the name "Nette Framework" is a protected trademark and its usage has some limitations. So please do not use word "Nette" in the name of your project or top-level domain, and choose a name that stands on its own merits. If your stuff is good, it will not take long to establish a reputation for yourselves. New BSD License --------------- Copyright (c) 2004, 2014 David Grudl (https://davidgrudl.com) All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of "Nette Framework" nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. This software is provided by the copyright holders and contributors "as is" and any express or implied warranties, including, but not limited to, the implied warranties of merchantability and fitness for a particular purpose are disclaimed. In no event shall the copyright owner or contributors be liable for any direct, indirect, incidental, special, exemplary, or consequential damages (including, but not limited to, procurement of substitute goods or services; loss of use, data, or profits; or business interruption) however caused and on any theory of liability, whether in contract, strict liability, or tort (including negligence or otherwise) arising in any way out of the use of this software, even if advised of the possibility of such damage. GNU General Public License -------------------------- GPL licenses are very very long, so instead of including them here we offer you URLs with full text: - [GPL version 2](http://www.gnu.org/licenses/gpl-2.0.html) - [GPL version 3](http://www.gnu.org/licenses/gpl-3.0.html) readme.md 0000666 00000004007 13533704046 0006335 0 ustar 00 Nette Bootstrap =============== [![Downloads this Month](https://img.shields.io/packagist/dm/nette/bootstrap.svg)](https://packagist.org/packages/nette/bootstrap) [![Build Status](https://travis-ci.org/nette/bootstrap.svg?branch=master)](https://travis-ci.org/nette/bootstrap) [![Coverage Status](https://coveralls.io/repos/github/nette/bootstrap/badge.svg?branch=master)](https://coveralls.io/github/nette/bootstrap?branch=master) [![Latest Stable Version](https://poser.pugx.org/nette/bootstrap/v/stable)](https://github.com/nette/bootstrap/releases) [![License](https://img.shields.io/badge/license-New%20BSD-blue.svg)](https://github.com/nette/bootstrap/blob/master/license.md) File `bootstrap.php` loads Nette Framework and all libraries that we depend on: ```php require __DIR__ . '/../vendor/autoload.php'; ``` Class `Configurator` creates so called DI container and handles application initialization. ```php $configurator = new Nette\Configurator; ``` Activates Tracy in strict mode: ```php //$configurator->setDebugMode(TRUE); $configurator->enableTracy(__DIR__ . '/../log'); ``` Setup directory for temporary files ```php $configurator->setTempDirectory(__DIR__ . '/../temp'); ``` Activate [autoloading](https://doc.nette.org/en/auto-loading#toc-nette-loaders-robotloader), that will automatically load all the files with our classes: ```php $configurator->createRobotLoader() ->addDirectory(__DIR__) ->addDirectory(__DIR__ . '/../vendor/others') ->register(); ``` And according to the configuration files it generates a DI container. Everything else depends on it. We will return this DI Container as a result of calling `app/boostrap.php` ```php $configurator->addConfig(__DIR__ . '/config/config.neon'); $configurator->addConfig(__DIR__ . '/config/config.local.neon'); return $configurator->createContainer(); ``` and we will store it as local variable in `www/index.php` and run the application: ```php $container = require __DIR__ . '/../app/bootstrap.php'; $container->getService('application')->run(); ``` That's it. src/Bootstrap/Configurator.php 0000666 00000023700 13533704046 0012476 0 ustar 00 Nette\DI\Extensions\PhpExtension::class, 'constants' => Nette\DI\Extensions\ConstantsExtension::class, 'extensions' => Nette\DI\Extensions\ExtensionsExtension::class, 'application' => [Nette\Bridges\ApplicationDI\ApplicationExtension::class, ['%debugMode%', ['%appDir%'], '%tempDir%/cache']], 'decorator' => Nette\DI\Extensions\DecoratorExtension::class, 'cache' => [Nette\Bridges\CacheDI\CacheExtension::class, ['%tempDir%']], 'database' => [Nette\Bridges\DatabaseDI\DatabaseExtension::class, ['%debugMode%']], 'di' => [Nette\DI\Extensions\DIExtension::class, ['%debugMode%']], 'forms' => Nette\Bridges\FormsDI\FormsExtension::class, 'http' => [Nette\Bridges\HttpDI\HttpExtension::class, ['%consoleMode%']], 'latte' => [Nette\Bridges\ApplicationDI\LatteExtension::class, ['%tempDir%/cache/latte', '%debugMode%']], 'mail' => Nette\Bridges\MailDI\MailExtension::class, 'routing' => [Nette\Bridges\ApplicationDI\RoutingExtension::class, ['%debugMode%']], 'security' => [Nette\Bridges\SecurityDI\SecurityExtension::class, ['%debugMode%']], 'session' => [Nette\Bridges\HttpDI\SessionExtension::class, ['%debugMode%', '%consoleMode%']], 'tracy' => [Tracy\Bridges\Nette\TracyExtension::class, ['%debugMode%', '%consoleMode%']], 'inject' => Nette\DI\Extensions\InjectExtension::class, ]; /** @var string[] of classes which shouldn't be autowired */ public $autowireExcludedClasses = [ 'stdClass', ]; /** @var array */ protected $parameters; /** @var array */ protected $services = []; /** @var array [file|array, section] */ protected $files = []; public function __construct() { $this->parameters = $this->getDefaultParameters(); } /** * Set parameter %debugMode%. * @param bool|string|array * @return static */ public function setDebugMode($value) { if (is_string($value) || is_array($value)) { $value = static::detectDebugMode($value); } elseif (!is_bool($value)) { throw new Nette\InvalidArgumentException(sprintf('Value must be either a string, array, or boolean, %s given.', gettype($value))); } $this->parameters['debugMode'] = $value; $this->parameters['productionMode'] = !$this->parameters['debugMode']; // compatibility return $this; } /** * @return bool */ public function isDebugMode() { return $this->parameters['debugMode']; } /** * Sets path to temporary directory. * @return static */ public function setTempDirectory($path) { $this->parameters['tempDir'] = $path; return $this; } /** * Sets the default timezone. * @return static */ public function setTimeZone($timezone) { date_default_timezone_set($timezone); @ini_set('date.timezone', $timezone); // @ - function may be disabled return $this; } /** * Adds new parameters. The %params% will be expanded. * @return static */ public function addParameters(array $params) { $this->parameters = DI\Config\Helpers::merge($params, $this->parameters); return $this; } /** * Add instances of services. * @return static */ public function addServices(array $services) { $this->services = $services + $this->services; return $this; } /** * @return array */ protected function getDefaultParameters() { $trace = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS); $last = end($trace); $debugMode = static::detectDebugMode(); return [ 'appDir' => isset($trace[1]['file']) ? dirname($trace[1]['file']) : NULL, 'wwwDir' => isset($last['file']) ? dirname($last['file']) : NULL, 'debugMode' => $debugMode, 'productionMode' => !$debugMode, 'consoleMode' => PHP_SAPI === 'cli', ]; } /** * @param string error log directory * @param string administrator email * @return void */ public function enableTracy($logDirectory = NULL, $email = NULL) { $this->enableDebugger($logDirectory, $email); } /** * Alias for enableTracy() */ public function enableDebugger($logDirectory = NULL, $email = NULL) { Tracy\Debugger::$strictMode = TRUE; Tracy\Debugger::enable(!$this->parameters['debugMode'], $logDirectory, $email); Nette\Bridges\Framework\TracyBridge::initialize(); } /** * @return Nette\Loaders\RobotLoader * @throws Nette\NotSupportedException if RobotLoader is not available */ public function createRobotLoader() { if (!class_exists(Nette\Loaders\RobotLoader::class)) { throw new Nette\NotSupportedException('RobotLoader not found, do you have `nette/robot-loader` package installed?'); } $loader = new Nette\Loaders\RobotLoader; $loader->setCacheStorage(new Nette\Caching\Storages\FileStorage($this->getCacheDirectory())); $loader->autoRebuild = $this->parameters['debugMode']; return $loader; } /** * Adds configuration file. * @return static */ public function addConfig($file) { $section = func_num_args() > 1 ? func_get_arg(1) : NULL; if ($section !== NULL) { trigger_error('Sections in config file are deprecated.', E_USER_DEPRECATED); } $this->files[] = [$file, $section === self::AUTO ? ($this->parameters['debugMode'] ? 'development' : 'production') : $section]; return $this; } /** * Returns system DI container. * @return DI\Container */ public function createContainer() { $class = $this->loadContainer(); $container = new $class(); foreach ($this->services as $name => $service) { $container->addService($name, $service); } $container->initialize(); if (class_exists(Nette\Environment::class)) { Nette\Environment::setContext($container); // back compatibility } return $container; } /** * Loads system DI container class and returns its name. * @return string */ public function loadContainer() { $loader = new DI\ContainerLoader( $this->getCacheDirectory() . '/Nette.Configurator', $this->parameters['debugMode'] ); $class = $loader->load( [$this, 'generateContainer'], [$this->parameters, $this->files, PHP_VERSION_ID - PHP_RELEASE_VERSION] ); return $class; } /** * @return string * @internal */ public function generateContainer(DI\Compiler $compiler) { $loader = $this->createLoader(); $compiler->addConfig(['parameters' => $this->parameters]); $fileInfo = []; foreach ($this->files as $info) { if (is_scalar($info[0])) { $fileInfo[] = "// source: $info[0] $info[1]"; $info[0] = $loader->load($info[0], $info[1]); } $compiler->addConfig($this->fixCompatibility($info[0])); } $compiler->addDependencies($loader->getDependencies()); $builder = $compiler->getContainerBuilder(); $builder->addExcludedClasses($this->autowireExcludedClasses); foreach ($this->defaultExtensions as $name => $extension) { list($class, $args) = is_string($extension) ? [$extension, []] : $extension; if (class_exists($class)) { $args = DI\Helpers::expand($args, $this->parameters, TRUE); $compiler->addExtension($name, (new \ReflectionClass($class))->newInstanceArgs($args)); } } $this->onCompile($this, $compiler); $classes = $compiler->compile(); return implode("\n", $fileInfo) . "\n\n" . $classes; } /** * @return DI\Config\Loader */ protected function createLoader() { return new DI\Config\Loader; } protected function getCacheDirectory() { if (empty($this->parameters['tempDir'])) { throw new Nette\InvalidStateException('Set path to temporary directory using setTempDirectory().'); } $dir = $this->parameters['tempDir'] . '/cache'; if (!is_dir($dir)) { @mkdir($dir); // @ - directory may already exist } return $dir; } /** * Back compatibility with < v2.3 * @return array */ protected function fixCompatibility($config) { if (isset($config['nette']['security']['frames'])) { $config['nette']['http']['frames'] = $config['nette']['security']['frames']; unset($config['nette']['security']['frames']); } foreach (['application', 'cache', 'database', 'di' => 'container', 'forms', 'http', 'latte', 'mail' => 'mailer', 'routing', 'security', 'session', 'tracy' => 'debugger'] as $new => $old) { if (isset($config['nette'][$old])) { $new = is_int($new) ? $old : $new; if (isset($config[$new])) { throw new Nette\DeprecatedException("You can use (deprecated) section 'nette.$old' or new section '$new', but not both of them."); } else { trigger_error("Configuration section 'nette.$old' is deprecated, use section '$new' (without 'nette')", E_USER_DEPRECATED); } $config[$new] = $config['nette'][$old]; unset($config['nette'][$old]); } } if (isset($config['nette']['xhtml'])) { trigger_error("Configuration option 'nette.xhtml' is deprecated, use section 'latte.xhtml' instead.", E_USER_DEPRECATED); $config['latte']['xhtml'] = $config['nette']['xhtml']; unset($config['nette']['xhtml']); } if (empty($config['nette'])) { unset($config['nette']); } return $config; } /********************* tools ****************d*g**/ /** * Detects debug mode by IP address. * @param string|array IP addresses or computer names whitelist detection * @return bool */ public static function detectDebugMode($list = NULL) { $addr = isset($_SERVER['REMOTE_ADDR']) ? $_SERVER['REMOTE_ADDR'] : php_uname('n'); $secret = isset($_COOKIE[self::COOKIE_SECRET]) && is_string($_COOKIE[self::COOKIE_SECRET]) ? $_COOKIE[self::COOKIE_SECRET] : NULL; $list = is_string($list) ? preg_split('#[,\s]+#', $list) : (array) $list; if (!isset($_SERVER['HTTP_X_FORWARDED_FOR'])) { $list[] = '127.0.0.1'; $list[] = '::1'; } return in_array($addr, $list, TRUE) || in_array("$secret@$addr", $list, TRUE); } } src/Bridges/Framework/TracyBridge.php 0000666 00000003700 13533704046 0013570 0 ustar 00 getPanel('Tracy:info')->data['Nette Framework'] = $version; $blueScreen->info[] = "Nette Framework $version"; } $blueScreen->addPanel(function ($e) { if ($e instanceof Latte\CompileException) { return [ 'tab' => 'Template', 'panel' => (preg_match('#\n|\?#', $e->sourceName) ? '' : '
' . (@is_file($e->sourceName) // @ - may trigger error ? 'File: ' . Helpers::editorLink($e->sourceName, $e->sourceLine) : '' . htmlspecialchars($e->sourceName . ($e->sourceLine ? ':' . $e->sourceLine : '')) . '') . '
') . '', ]; } }); $blueScreen->addPanel(function ($e) { if ($e instanceof Nette\Neon\Exception && preg_match('#line (\d+)#', $e->getMessage(), $m) && ($trace = Helpers::findTrace($e->getTrace(), 'Nette\Neon\Decoder::decode')) ) { return [ 'tab' => 'NEON', 'panel' => ($trace2 = Helpers::findTrace($e->getTrace(), 'Nette\DI\Config\Adapters\NeonAdapter::load')) ? '' . BlueScreen::highlightLine(htmlspecialchars($e->sourceCode, ENT_IGNORE, 'UTF-8'), $e->sourceLine) . '
File: ' . Helpers::editorLink($trace2['args'][0], $m[1]) . '
' . BlueScreen::highlightFile($trace2['args'][0], $m[1]) : BlueScreen::highlightPhp($trace['args'][0], $m[1]), ]; } }); } }