contributing.md 0000666 00000002317 13436750770 0007620 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](http://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](http://nette.org/en/contributing) in order to make the contribution process easy and effective for everyone involved. Thanks! src/Bootstrap/Configurator.php 0000666 00000024267 13436750770 0012516 0 ustar 00 'Nette\DI\Extensions\PhpExtension', 'constants' => 'Nette\DI\Extensions\ConstantsExtension', 'extensions' => 'Nette\DI\Extensions\ExtensionsExtension', 'decorator' => 'Nette\DI\Extensions\DecoratorExtension', 'application' => array('Nette\Bridges\ApplicationDI\ApplicationExtension', array('%debugMode%', array('%appDir%'))), 'cache' => array('Nette\Bridges\CacheDI\CacheExtension', array('%tempDir%')), 'database' => array('Nette\Bridges\DatabaseDI\DatabaseExtension', array('%debugMode%')), 'di' => array('Nette\DI\Extensions\DIExtension', array('%debugMode%')), 'forms' => 'Nette\Bridges\FormsDI\FormsExtension', 'http' => 'Nette\Bridges\HttpDI\HttpExtension', 'latte' => array('Nette\Bridges\ApplicationDI\LatteExtension', array('%tempDir%/cache/latte', '%debugMode%')), 'mail' => 'Nette\Bridges\MailDI\MailExtension', 'reflection' => array('Nette\Bridges\ReflectionDI\ReflectionExtension', array('%debugMode%')), 'routing' => array('Nette\Bridges\ApplicationDI\RoutingExtension', array('%debugMode%')), 'security' => array('Nette\Bridges\SecurityDI\SecurityExtension', array('%debugMode%')), 'session' => array('Nette\Bridges\HttpDI\SessionExtension', array('%debugMode%')), 'tracy' => array('Tracy\Bridges\Nette\TracyExtension', array('%debugMode%')), 'inject' => 'Nette\DI\Extensions\InjectExtension', ); /** @var string[] of classes which shouldn't be autowired */ public $autowireExcludedClasses = array( 'stdClass', ); /** @var array */ protected $parameters; /** @var array */ protected $services = array(); /** @var array [file|array, section] */ protected $files = array(); public function __construct() { $this->parameters = $this->getDefaultParameters(); } /** * Set parameter %debugMode%. * @param bool|string|array * @return self */ 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 $this->parameters['environment'] = $this->parameters['debugMode'] ? 'development' : 'production'; return $this; } /** * @return bool */ public function isDebugMode() { return $this->parameters['debugMode']; } /** * Sets path to temporary directory. * @return self */ public function setTempDirectory($path) { $this->parameters['tempDir'] = $path; return $this; } /** * Adds new parameters. The %params% will be expanded. * @return self */ public function addParameters(array $params) { $this->parameters = DI\Config\Helpers::merge($params, $this->parameters); return $this; } /** * Add instances of services. * @return self */ public function addServices(array $services) { $this->services = $services + $this->services; return $this; } /** * @return array */ protected function getDefaultParameters() { $trace = debug_backtrace(PHP_VERSION_ID >= 50306 ? DEBUG_BACKTRACE_IGNORE_ARGS : FALSE); $last = end($trace); $debugMode = static::detectDebugMode(); return array( 'appDir' => isset($trace[1]['file']) ? dirname($trace[1]['file']) : NULL, 'wwwDir' => isset($last['file']) ? dirname($last['file']) : NULL, 'debugMode' => $debugMode, 'productionMode' => !$debugMode, 'environment' => $debugMode ? 'development' : 'production', 'consoleMode' => PHP_SAPI === 'cli', 'container' => array( 'class' => NULL, 'parent' => NULL, ) ); } /** * @param string error log directory * @param string administrator email * @return void */ 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')) { 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 self */ public function addConfig($file, $section = NULL) { if ($section === NULL && is_string($file) && $this->parameters['debugMode']) { // back compatibility try { $loader = new DI\Config\Loader; $loader->load($file, $this->parameters['environment']); trigger_error("Config file '$file' has sections, call addConfig() with second parameter Configurator::AUTO.", E_USER_WARNING); $section = $this->parameters['environment']; } catch (\Exception $e) {} } $this->files[] = array($file, $section === self::AUTO ? $this->parameters['environment'] : $section); return $this; } /** * Returns system DI container. * @return DI\Container */ public function createContainer() { $loader = new DI\ContainerLoader( $this->getCacheDirectory() . '/Nette.Configurator', $this->parameters['debugMode'] ); $class = $loader->load( array($this->parameters, $this->files), array($this, 'generateContainer') ); $container = new $class; foreach ($this->services as $name => $service) { $container->addService($name, $service); } $container->initialize(); if (class_exists('Nette\Environment')) { Nette\Environment::setContext($container); // back compatibility } return $container; } /** * @return string * @internal */ public function generateContainer(DI\Compiler $compiler) { $loader = $this->createLoader(); $compiler->addConfig(array('parameters' => $this->parameters)); $fileInfo = array(); 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) ? array($extension, array()) : $extension; if (class_exists($class)) { $rc = new \ReflectionClass($class); $args = DI\Helpers::expand($args, $this->parameters, TRUE); $compiler->addExtension($name, $args ? $rc->newInstanceArgs($args) : $rc->newInstance()); } } $this->onCompile($this, $compiler); $classes = $compiler->compile(); if (!empty($builder->parameters['container']['parent'])) { $classes[0]->setExtends($builder->parameters['container']['parent']); } return implode("\n", $fileInfo) . "\n\n" . implode("\n\n\n", $classes) . (($tmp = $builder->parameters['container']['class']) ? "\nclass $tmp extends {$builder->getClassName()} {}\n" : ''); } /** * @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 compatiblity 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 (array('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."); } $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 00000003315 13436750770 0013601 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 array( 'tab' => 'Template', 'panel' => (@is_file($e->sourceName) // @ - may trigger error ? '
File: ' . Helpers::editorLink($e->sourceName, $e->sourceLine) . '
' : '') . '' . BlueScreen::highlightLine(htmlspecialchars($e->sourceCode, ENT_IGNORE, 'UTF-8'), $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 array( 'tab' => 'NEON', 'panel' => ($trace2 = Helpers::findTrace($e->getTrace(), 'Nette\DI\Config\Adapters\NeonAdapter::load')) ? '
File: ' . Helpers::editorLink($trace2['args'][0], $m[1]) . '
' . BlueScreen::highlightFile($trace2['args'][0], $m[1]) : BlueScreen::highlightPhp($trace['args'][0], $m[1]) ); } }); } } readme.md 0000666 00000003164 13436750770 0006347 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) 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->enableDebugger(__DIR__ . '/../log'); ``` Setup directory for temporary files ```php $configurator->setTempDirectory(__DIR__ . '/../temp'); ``` Activate [autoloading](http://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. composer.json 0000666 00000002073 13436750770 0007310 0 ustar 00 { "name": "nette/bootstrap", "description": "Nette Bootstrap", "homepage": "http://nette.org", "license": ["BSD-3-Clause", "GPL-2.0", "GPL-3.0"], "authors": [ { "name": "David Grudl", "homepage": "http://davidgrudl.com" }, { "name": "Nette Community", "homepage": "http://nette.org/contributors" } ], "require": { "php": ">=5.3.1", "nette/di": "~2.3", "nette/utils": "~2.2" }, "suggest": { "nette/robot-loader": "to use Configurator::createRobotLoader()", "tracy/tracy": "to use Configurator::enableDebugger()" }, "require-dev": { "nette/application": "~2.3", "nette/caching": "~2.3", "nette/database": "~2.3", "nette/forms": "~2.3", "nette/http": "~2.3", "nette/mail": "~2.3", "nette/robot-loader": "~2.2", "nette/safe-stream": "~2.2", "nette/security": "~2.3", "nette/tester": "~1.3", "latte/latte": "~2.2", "tracy/tracy": "~2.3" }, "conflict": { "nette/nette": "<2.2" }, "autoload": { "classmap": ["src/"] }, "minimum-stability": "dev", "extra": { "branch-alias": { "dev-master": "2.3-dev" } } } license.md 0000666 00000005243 13436750770 0006534 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 (http://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)