├── .bowerrc
├── .gitignore
├── .travis.yml
├── LICENSE
├── README.md
├── app
├── MicroKernel.php
├── Resources
│ └── views
│ │ ├── index.html.twig
│ │ └── layout.html.twig
├── autoload.php
├── config
│ ├── config.yml
│ ├── config_dev.yml
│ ├── config_prod.yml
│ ├── config_test.yml
│ └── parameters.yml.dist
└── phpunit.xml.dist
├── bin
├── console
└── symfony_requirements
├── bower.json
├── composer.json
├── src
└── AppBundle
│ ├── AppBundle.php
│ ├── Controller
│ └── DefaultController.php
│ └── Tests
│ └── Controller
│ └── DefaultControllerTest.php
├── var
├── .gitkeep
└── SymfonyRequirements.php
└── web
├── app.php
├── app_dev.php
├── apple-touch-icon.png
├── css
└── main.css
├── favicon.ico
└── robots.txt
/.bowerrc:
--------------------------------------------------------------------------------
1 | {
2 | "directory": "src/AppBundle/Resources/public/components"
3 | }
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Cache and logs (Symfony2)
2 | /app/cache/*
3 | /app/logs/*
4 | !app/cache/.gitkeep
5 | !app/logs/.gitkeep
6 |
7 | # Cache and logs (Symfony3)
8 | /var/cache/*
9 | /var/logs/*
10 | !/var/.gitkeep
11 | !var/cache/.gitkeep
12 | !var/logs/.gitkeep
13 |
14 | # Parameters
15 | /app/config/parameters.yml
16 | /app/config/parameters.ini
17 |
18 | # Managed by Composer
19 | /app/bootstrap.php.cache
20 | /var/bootstrap.php.cache
21 | /bin/*
22 | !bin/console
23 | !bin/symfony_requirements
24 | /vendor/
25 |
26 | # Assets and user uploads
27 | /web/bundles/
28 | /web/uploads/
29 |
30 | # PHPUnit
31 | /app/phpunit.xml
32 | /phpunit.xml
33 |
34 | # Build data
35 | /build/
36 |
37 | # Composer PHAR
38 | /composer.phar
39 |
40 | .idea
41 | composer.lock
42 |
43 | # bundle bower assets
44 | src/AppBundle/Resources/public/components
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | language: php
2 |
3 | php:
4 | - '5.6'
5 | - '7.0'
6 | - hhvm
7 | - nightly
8 |
9 | before_script: composer install --dev
10 |
11 | script: phpunit -c app
12 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2015-2016 Aleksandr Zamiatin
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
23 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # symfony-micro
2 | Symfony micro applicatin based on ```\Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait```
3 |
4 | [Symfony as a Microframework](http://symfony.com/blog/new-in-symfony-2-8-symfony-as-a-microframework)
5 |
6 | [](https://packagist.org/packages/cawakharkov/symfony-micro) [](https://packagist.org/packages/cawakharkov/symfony-micro) [](https://packagist.org/packages/cawakharkov/symfony-micro) [](https://packagist.org/packages/cawakharkov/symfony-micro)
7 | []()
8 | []()
9 |
10 | # What's included
11 | - Symfony v3.0.*
12 | - Doctrine 2.5
13 | - Generator-bundle
14 | - Uikit
15 | - FontAwesome
16 |
17 |
18 | # Usage
19 | * Create project
20 | ```bash
21 | composer create-project cawakharkov/symfony-micro:dev-master
22 | ```
23 | * Bower
24 | ```bash
25 | bower install
26 | ```
27 | * Run with built in server .
28 | ```bash
29 | bin/console server:run localhost
30 | ```
31 |
32 | ## Small benchmark
33 | ```
34 | -> % siege -b -t30S -c 20 http://prod.micro.local/
35 | ** SIEGE 3.0.8
36 | ** Preparing 20 concurrent users for battle.
37 | The server is now under siege...
38 | Lifting the server siege... done.
39 |
40 | Transactions: 11252 hits
41 | Availability: 100.00 %
42 | Elapsed time: 29.09 secs
43 | Data transferred: 4.79 MB
44 | Response time: 0.05 secs
45 | Transaction rate: 386.80 trans/sec
46 | Throughput: 0.16 MB/sec
47 | Concurrency: 19.96
48 | Successful transactions: 11252
49 | Failed transactions: 0
50 | Longest transaction: 0.12
51 | Shortest transaction: 0.03
52 | ```
53 |
--------------------------------------------------------------------------------
/app/MicroKernel.php:
--------------------------------------------------------------------------------
1 | getEnvironment(), array('dev', 'test'), true)) {
24 | $bundles[] = new Symfony\Bundle\WebProfilerBundle\WebProfilerBundle();
25 | $bundles[] = new Sensio\Bundle\GeneratorBundle\SensioGeneratorBundle();
26 | }
27 |
28 | return $bundles;
29 | }
30 |
31 | protected function configureRoutes(RouteCollectionBuilder $routes)
32 | {
33 | if (in_array($this->getEnvironment(), array('dev', 'test'), true)) {
34 | $routes->import('@WebProfilerBundle/Resources/config/routing/wdt.xml', '/_wdt');
35 | $routes->import('@WebProfilerBundle/Resources/config/routing/profiler.xml', '/_profiler');
36 | }
37 |
38 | $routes->import('@AppBundle/Controller', '/', 'annotation');
39 | }
40 |
41 | protected function configureContainer(ContainerBuilder $c, LoaderInterface $loader)
42 | {
43 | $loader->load(__DIR__.'/config/config_'.$this->getEnvironment().'.yml');
44 | }
45 |
46 | public function getRootDir()
47 | {
48 | return __DIR__;
49 | }
50 |
51 | public function getCacheDir()
52 | {
53 | return dirname(__DIR__).'/var/cache/'.$this->environment;
54 | }
55 |
56 | public function getLogDir()
57 | {
58 | return dirname(__DIR__).'/var/logs';
59 | }
60 | }
61 |
--------------------------------------------------------------------------------
/app/Resources/views/index.html.twig:
--------------------------------------------------------------------------------
1 | {% extends "layout.html.twig" %}
2 |
3 | {% block content %}
4 | Welcome to your new Symfony Application!
5 | {% endblock %}
6 |
--------------------------------------------------------------------------------
/app/Resources/views/layout.html.twig:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | {% block title '' %} - My Symfony Application
5 |
6 |
7 |
8 |
9 |
10 |
20 |
21 |
22 | {% block content %}{% endblock %}
23 |
24 |
25 |
26 |
27 |
28 |
--------------------------------------------------------------------------------
/app/autoload.php:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
10 |
11 |
12 | ../src/AppBundle/Tests
13 |
14 |
15 |
16 |
17 |
18 |
23 |
38 |
39 |
--------------------------------------------------------------------------------
/bin/console:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env php
2 | getParameterOption(array('--env', '-e'), getenv('SYMFONY_ENV') ?: 'dev');
23 | $debug = getenv('SYMFONY_DEBUG') !== '0' && !$input->hasParameterOption(array('--no-debug', '')) && $env !== 'prod';
24 |
25 | if ($debug) {
26 | Debug::enable();
27 | }
28 |
29 | $kernel = new MicroKernel($env, $debug);
30 | $application = new Application($kernel);
31 | $application->run($input);
32 |
--------------------------------------------------------------------------------
/bin/symfony_requirements:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env php
2 | getPhpIniConfigPath();
9 |
10 | echo_title('Symfony2 Requirements Checker');
11 |
12 | echo '> PHP is using the following php.ini file:'.PHP_EOL;
13 | if ($iniPath) {
14 | echo_style('green', ' '.$iniPath);
15 | } else {
16 | echo_style('warning', ' WARNING: No configuration file (php.ini) used by PHP!');
17 | }
18 |
19 | echo PHP_EOL.PHP_EOL;
20 |
21 | echo '> Checking Symfony requirements:'.PHP_EOL.' ';
22 |
23 | $messages = array();
24 | foreach ($symfonyRequirements->getRequirements() as $req) {
25 | /** @var $req Requirement */
26 | if ($helpText = get_error_message($req, $lineSize)) {
27 | echo_style('red', 'E');
28 | $messages['error'][] = $helpText;
29 | } else {
30 | echo_style('green', '.');
31 | }
32 | }
33 |
34 | $checkPassed = empty($messages['error']);
35 |
36 | foreach ($symfonyRequirements->getRecommendations() as $req) {
37 | if ($helpText = get_error_message($req, $lineSize)) {
38 | echo_style('yellow', 'W');
39 | $messages['warning'][] = $helpText;
40 | } else {
41 | echo_style('green', '.');
42 | }
43 | }
44 |
45 | if ($checkPassed) {
46 | echo_block('success', 'OK', 'Your system is ready to run Symfony2 projects');
47 | } else {
48 | echo_block('error', 'ERROR', 'Your system is not ready to run Symfony2 projects');
49 |
50 | echo_title('Fix the following mandatory requirements', 'red');
51 |
52 | foreach ($messages['error'] as $helpText) {
53 | echo ' * '.$helpText.PHP_EOL;
54 | }
55 | }
56 |
57 | if (!empty($messages['warning'])) {
58 | echo_title('Optional recommendations to improve your setup', 'yellow');
59 |
60 | foreach ($messages['warning'] as $helpText) {
61 | echo ' * '.$helpText.PHP_EOL;
62 | }
63 | }
64 |
65 | echo PHP_EOL;
66 | echo_style('title', 'Note');
67 | echo ' The command console could use a different php.ini file'.PHP_EOL;
68 | echo_style('title', '~~~~');
69 | echo ' than the one used with your web server. To be on the'.PHP_EOL;
70 | echo ' safe side, please check the requirements from your web'.PHP_EOL;
71 | echo ' server using the ';
72 | echo_style('yellow', 'web/config.php');
73 | echo ' script.'.PHP_EOL;
74 | echo PHP_EOL;
75 |
76 | exit($checkPassed ? 0 : 1);
77 |
78 | function get_error_message(Requirement $requirement, $lineSize)
79 | {
80 | if ($requirement->isFulfilled()) {
81 | return;
82 | }
83 |
84 | $errorMessage = wordwrap($requirement->getTestMessage(), $lineSize - 3, PHP_EOL.' ').PHP_EOL;
85 | $errorMessage .= ' > '.wordwrap($requirement->getHelpText(), $lineSize - 5, PHP_EOL.' > ').PHP_EOL;
86 |
87 | return $errorMessage;
88 | }
89 |
90 | function echo_title($title, $style = null)
91 | {
92 | $style = $style ?: 'title';
93 |
94 | echo PHP_EOL;
95 | echo_style($style, $title.PHP_EOL);
96 | echo_style($style, str_repeat('~', strlen($title)).PHP_EOL);
97 | echo PHP_EOL;
98 | }
99 |
100 | function echo_style($style, $message)
101 | {
102 | // ANSI color codes
103 | $styles = array(
104 | 'reset' => "\033[0m",
105 | 'red' => "\033[31m",
106 | 'green' => "\033[32m",
107 | 'yellow' => "\033[33m",
108 | 'error' => "\033[37;41m",
109 | 'success' => "\033[37;42m",
110 | 'title' => "\033[34m",
111 | );
112 | $supports = has_color_support();
113 |
114 | echo($supports ? $styles[$style] : '').$message.($supports ? $styles['reset'] : '');
115 | }
116 |
117 | function echo_block($style, $title, $message)
118 | {
119 | $message = ' '.trim($message).' ';
120 | $width = strlen($message);
121 |
122 | echo PHP_EOL.PHP_EOL;
123 |
124 | echo_style($style, str_repeat(' ', $width).PHP_EOL);
125 | echo_style($style, str_pad(' ['.$title.']', $width, ' ', STR_PAD_RIGHT).PHP_EOL);
126 | echo_style($style, str_pad($message, $width, ' ', STR_PAD_RIGHT).PHP_EOL);
127 | echo_style($style, str_repeat(' ', $width).PHP_EOL);
128 | }
129 |
130 | function has_color_support()
131 | {
132 | static $support;
133 |
134 | if (null === $support) {
135 | if (DIRECTORY_SEPARATOR == '\\') {
136 | $support = false !== getenv('ANSICON') || 'ON' === getenv('ConEmuANSI');
137 | } else {
138 | $support = function_exists('posix_isatty') && @posix_isatty(STDOUT);
139 | }
140 | }
141 |
142 | return $support;
143 | }
144 |
--------------------------------------------------------------------------------
/bower.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "symfony-micro",
3 | "homepage": "https://github.com/CawaKharkov/symfony-micro",
4 | "authors": [
5 | "Aleksandr Zamiatin "
6 | ],
7 | "description": "Symfony micro applicatin based on Kernel\\MicroKernelTrait.",
8 | "main": "",
9 | "moduleType": [],
10 | "keywords": [
11 | "symfony",
12 | "php",
13 | "js",
14 | "micro",
15 | "framework"
16 | ],
17 | "license": "MIT",
18 | "ignore": [
19 | "**/.*",
20 | "node_modules",
21 | "bower_components",
22 | "test",
23 | "tests"
24 | ],
25 | "dependencies": {
26 | "uikit": "~2.24.3",
27 | "font-awesome": "~4.5.0"
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/composer.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "cawakharkov/symfony-micro",
3 | "license": "MIT",
4 | "type": "project",
5 | "description": "Demo for Symfony micro trait application",
6 | "autoload": {
7 | "psr-4": {
8 | "": "src/"
9 | },
10 | "classmap": [
11 | "app/MicroKernel.php"
12 | ]
13 | },
14 | "autoload-dev": {
15 | "psr-4": {
16 | "Tests\\": "tests/"
17 | }
18 | },
19 | "require": {
20 | "php": ">=5.6.0",
21 | "symfony/symfony": "3.0.*",
22 | "symfony/monolog-bundle": "~2.4",
23 | "sensio/distribution-bundle": "~5.0",
24 | "sensio/framework-extra-bundle": "^3.0.2",
25 | "incenteev/composer-parameter-handler": "~2.0",
26 | "doctrine/doctrine-bundle": "^1.6",
27 | "doctrine/orm": "^2.5"
28 | },
29 | "require-dev": {
30 | "sensio/generator-bundle": "^3.0",
31 | "phpunit/phpunit": "5.1.4"
32 | },
33 | "scripts": {
34 | "post-install-cmd": [
35 | "Incenteev\\ParameterHandler\\ScriptHandler::buildParameters",
36 | "Sensio\\Bundle\\DistributionBundle\\Composer\\ScriptHandler::buildBootstrap",
37 | "Sensio\\Bundle\\DistributionBundle\\Composer\\ScriptHandler::clearCache",
38 | "Sensio\\Bundle\\DistributionBundle\\Composer\\ScriptHandler::installAssets",
39 | "Sensio\\Bundle\\DistributionBundle\\Composer\\ScriptHandler::installRequirementsFile",
40 | "Sensio\\Bundle\\DistributionBundle\\Composer\\ScriptHandler::prepareDeploymentTarget"
41 | ],
42 | "post-update-cmd": [
43 | "Incenteev\\ParameterHandler\\ScriptHandler::buildParameters",
44 | "Sensio\\Bundle\\DistributionBundle\\Composer\\ScriptHandler::buildBootstrap",
45 | "Sensio\\Bundle\\DistributionBundle\\Composer\\ScriptHandler::clearCache",
46 | "Sensio\\Bundle\\DistributionBundle\\Composer\\ScriptHandler::installAssets",
47 | "Sensio\\Bundle\\DistributionBundle\\Composer\\ScriptHandler::installRequirementsFile",
48 | "Sensio\\Bundle\\DistributionBundle\\Composer\\ScriptHandler::prepareDeploymentTarget"
49 | ]
50 | },
51 | "extra": {
52 | "symfony-app-dir": "app",
53 | "symfony-bin-dir": "bin",
54 | "symfony-var-dir": "var",
55 | "symfony-web-dir": "web",
56 | "symfony-tests-dir": "tests",
57 | "symfony-assets-install": "relative",
58 | "incenteev-parameters": {
59 | "file": "app/config/parameters.yml"
60 | },
61 | "branch-alias": {
62 | "dev-master": "0.1-dev"
63 | }
64 | }
65 | }
66 |
--------------------------------------------------------------------------------
/src/AppBundle/AppBundle.php:
--------------------------------------------------------------------------------
1 | render('index.html.twig');
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/src/AppBundle/Tests/Controller/DefaultControllerTest.php:
--------------------------------------------------------------------------------
1 | request('GET', '/');
14 |
15 | $this->assertContains('My Symfony Application', $client->getResponse()->getContent());
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/var/.gitkeep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cawa87/symfony-micro/ac3e0378db4365119f38a0e1e556942c2b8c315c/var/.gitkeep
--------------------------------------------------------------------------------
/var/SymfonyRequirements.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | /*
13 | * Users of PHP 5.2 should be able to run the requirements checks.
14 | * This is why the file and all classes must be compatible with PHP 5.2+
15 | * (e.g. not using namespaces and closures).
16 | *
17 | * ************** CAUTION **************
18 | *
19 | * DO NOT EDIT THIS FILE as it will be overridden by Composer as part of
20 | * the installation/update process. The original file resides in the
21 | * SensioDistributionBundle.
22 | *
23 | * ************** CAUTION **************
24 | */
25 |
26 | /**
27 | * Represents a single PHP requirement, e.g. an installed extension.
28 | * It can be a mandatory requirement or an optional recommendation.
29 | * There is a special subclass, named PhpIniRequirement, to check a php.ini configuration.
30 | *
31 | * @author Tobias Schultze
32 | */
33 | class Requirement
34 | {
35 | private $fulfilled;
36 | private $testMessage;
37 | private $helpText;
38 | private $helpHtml;
39 | private $optional;
40 |
41 | /**
42 | * Constructor that initializes the requirement.
43 | *
44 | * @param bool $fulfilled Whether the requirement is fulfilled
45 | * @param string $testMessage The message for testing the requirement
46 | * @param string $helpHtml The help text formatted in HTML for resolving the problem
47 | * @param string|null $helpText The help text (when null, it will be inferred from $helpHtml, i.e. stripped from HTML tags)
48 | * @param bool $optional Whether this is only an optional recommendation not a mandatory requirement
49 | */
50 | public function __construct($fulfilled, $testMessage, $helpHtml, $helpText = null, $optional = false)
51 | {
52 | $this->fulfilled = (bool) $fulfilled;
53 | $this->testMessage = (string) $testMessage;
54 | $this->helpHtml = (string) $helpHtml;
55 | $this->helpText = null === $helpText ? strip_tags($this->helpHtml) : (string) $helpText;
56 | $this->optional = (bool) $optional;
57 | }
58 |
59 | /**
60 | * Returns whether the requirement is fulfilled.
61 | *
62 | * @return bool true if fulfilled, otherwise false
63 | */
64 | public function isFulfilled()
65 | {
66 | return $this->fulfilled;
67 | }
68 |
69 | /**
70 | * Returns the message for testing the requirement.
71 | *
72 | * @return string The test message
73 | */
74 | public function getTestMessage()
75 | {
76 | return $this->testMessage;
77 | }
78 |
79 | /**
80 | * Returns the help text for resolving the problem.
81 | *
82 | * @return string The help text
83 | */
84 | public function getHelpText()
85 | {
86 | return $this->helpText;
87 | }
88 |
89 | /**
90 | * Returns the help text formatted in HTML.
91 | *
92 | * @return string The HTML help
93 | */
94 | public function getHelpHtml()
95 | {
96 | return $this->helpHtml;
97 | }
98 |
99 | /**
100 | * Returns whether this is only an optional recommendation and not a mandatory requirement.
101 | *
102 | * @return bool true if optional, false if mandatory
103 | */
104 | public function isOptional()
105 | {
106 | return $this->optional;
107 | }
108 | }
109 |
110 | /**
111 | * Represents a PHP requirement in form of a php.ini configuration.
112 | *
113 | * @author Tobias Schultze
114 | */
115 | class PhpIniRequirement extends Requirement
116 | {
117 | /**
118 | * Constructor that initializes the requirement.
119 | *
120 | * @param string $cfgName The configuration name used for ini_get()
121 | * @param bool|callback $evaluation Either a boolean indicating whether the configuration should evaluate to true or false,
122 | * or a callback function receiving the configuration value as parameter to determine the fulfillment of the requirement
123 | * @param bool $approveCfgAbsence If true the Requirement will be fulfilled even if the configuration option does not exist, i.e. ini_get() returns false.
124 | * This is helpful for abandoned configs in later PHP versions or configs of an optional extension, like Suhosin.
125 | * Example: You require a config to be true but PHP later removes this config and defaults it to true internally.
126 | * @param string|null $testMessage The message for testing the requirement (when null and $evaluation is a boolean a default message is derived)
127 | * @param string|null $helpHtml The help text formatted in HTML for resolving the problem (when null and $evaluation is a boolean a default help is derived)
128 | * @param string|null $helpText The help text (when null, it will be inferred from $helpHtml, i.e. stripped from HTML tags)
129 | * @param bool $optional Whether this is only an optional recommendation not a mandatory requirement
130 | */
131 | public function __construct($cfgName, $evaluation, $approveCfgAbsence = false, $testMessage = null, $helpHtml = null, $helpText = null, $optional = false)
132 | {
133 | $cfgValue = ini_get($cfgName);
134 |
135 | if (is_callable($evaluation)) {
136 | if (null === $testMessage || null === $helpHtml) {
137 | throw new InvalidArgumentException('You must provide the parameters testMessage and helpHtml for a callback evaluation.');
138 | }
139 |
140 | $fulfilled = call_user_func($evaluation, $cfgValue);
141 | } else {
142 | if (null === $testMessage) {
143 | $testMessage = sprintf('%s %s be %s in php.ini',
144 | $cfgName,
145 | $optional ? 'should' : 'must',
146 | $evaluation ? 'enabled' : 'disabled'
147 | );
148 | }
149 |
150 | if (null === $helpHtml) {
151 | $helpHtml = sprintf('Set %s to %s in php.ini*.',
152 | $cfgName,
153 | $evaluation ? 'on' : 'off'
154 | );
155 | }
156 |
157 | $fulfilled = $evaluation == $cfgValue;
158 | }
159 |
160 | parent::__construct($fulfilled || ($approveCfgAbsence && false === $cfgValue), $testMessage, $helpHtml, $helpText, $optional);
161 | }
162 | }
163 |
164 | /**
165 | * A RequirementCollection represents a set of Requirement instances.
166 | *
167 | * @author Tobias Schultze
168 | */
169 | class RequirementCollection implements IteratorAggregate
170 | {
171 | private $requirements = array();
172 |
173 | /**
174 | * Gets the current RequirementCollection as an Iterator.
175 | *
176 | * @return Traversable A Traversable interface
177 | */
178 | public function getIterator()
179 | {
180 | return new ArrayIterator($this->requirements);
181 | }
182 |
183 | /**
184 | * Adds a Requirement.
185 | *
186 | * @param Requirement $requirement A Requirement instance
187 | */
188 | public function add(Requirement $requirement)
189 | {
190 | $this->requirements[] = $requirement;
191 | }
192 |
193 | /**
194 | * Adds a mandatory requirement.
195 | *
196 | * @param bool $fulfilled Whether the requirement is fulfilled
197 | * @param string $testMessage The message for testing the requirement
198 | * @param string $helpHtml The help text formatted in HTML for resolving the problem
199 | * @param string|null $helpText The help text (when null, it will be inferred from $helpHtml, i.e. stripped from HTML tags)
200 | */
201 | public function addRequirement($fulfilled, $testMessage, $helpHtml, $helpText = null)
202 | {
203 | $this->add(new Requirement($fulfilled, $testMessage, $helpHtml, $helpText, false));
204 | }
205 |
206 | /**
207 | * Adds an optional recommendation.
208 | *
209 | * @param bool $fulfilled Whether the recommendation is fulfilled
210 | * @param string $testMessage The message for testing the recommendation
211 | * @param string $helpHtml The help text formatted in HTML for resolving the problem
212 | * @param string|null $helpText The help text (when null, it will be inferred from $helpHtml, i.e. stripped from HTML tags)
213 | */
214 | public function addRecommendation($fulfilled, $testMessage, $helpHtml, $helpText = null)
215 | {
216 | $this->add(new Requirement($fulfilled, $testMessage, $helpHtml, $helpText, true));
217 | }
218 |
219 | /**
220 | * Adds a mandatory requirement in form of a php.ini configuration.
221 | *
222 | * @param string $cfgName The configuration name used for ini_get()
223 | * @param bool|callback $evaluation Either a boolean indicating whether the configuration should evaluate to true or false,
224 | * or a callback function receiving the configuration value as parameter to determine the fulfillment of the requirement
225 | * @param bool $approveCfgAbsence If true the Requirement will be fulfilled even if the configuration option does not exist, i.e. ini_get() returns false.
226 | * This is helpful for abandoned configs in later PHP versions or configs of an optional extension, like Suhosin.
227 | * Example: You require a config to be true but PHP later removes this config and defaults it to true internally.
228 | * @param string $testMessage The message for testing the requirement (when null and $evaluation is a boolean a default message is derived)
229 | * @param string $helpHtml The help text formatted in HTML for resolving the problem (when null and $evaluation is a boolean a default help is derived)
230 | * @param string|null $helpText The help text (when null, it will be inferred from $helpHtml, i.e. stripped from HTML tags)
231 | */
232 | public function addPhpIniRequirement($cfgName, $evaluation, $approveCfgAbsence = false, $testMessage = null, $helpHtml = null, $helpText = null)
233 | {
234 | $this->add(new PhpIniRequirement($cfgName, $evaluation, $approveCfgAbsence, $testMessage, $helpHtml, $helpText, false));
235 | }
236 |
237 | /**
238 | * Adds an optional recommendation in form of a php.ini configuration.
239 | *
240 | * @param string $cfgName The configuration name used for ini_get()
241 | * @param bool|callback $evaluation Either a boolean indicating whether the configuration should evaluate to true or false,
242 | * or a callback function receiving the configuration value as parameter to determine the fulfillment of the requirement
243 | * @param bool $approveCfgAbsence If true the Requirement will be fulfilled even if the configuration option does not exist, i.e. ini_get() returns false.
244 | * This is helpful for abandoned configs in later PHP versions or configs of an optional extension, like Suhosin.
245 | * Example: You require a config to be true but PHP later removes this config and defaults it to true internally.
246 | * @param string $testMessage The message for testing the requirement (when null and $evaluation is a boolean a default message is derived)
247 | * @param string $helpHtml The help text formatted in HTML for resolving the problem (when null and $evaluation is a boolean a default help is derived)
248 | * @param string|null $helpText The help text (when null, it will be inferred from $helpHtml, i.e. stripped from HTML tags)
249 | */
250 | public function addPhpIniRecommendation($cfgName, $evaluation, $approveCfgAbsence = false, $testMessage = null, $helpHtml = null, $helpText = null)
251 | {
252 | $this->add(new PhpIniRequirement($cfgName, $evaluation, $approveCfgAbsence, $testMessage, $helpHtml, $helpText, true));
253 | }
254 |
255 | /**
256 | * Adds a requirement collection to the current set of requirements.
257 | *
258 | * @param RequirementCollection $collection A RequirementCollection instance
259 | */
260 | public function addCollection(RequirementCollection $collection)
261 | {
262 | $this->requirements = array_merge($this->requirements, $collection->all());
263 | }
264 |
265 | /**
266 | * Returns both requirements and recommendations.
267 | *
268 | * @return array Array of Requirement instances
269 | */
270 | public function all()
271 | {
272 | return $this->requirements;
273 | }
274 |
275 | /**
276 | * Returns all mandatory requirements.
277 | *
278 | * @return array Array of Requirement instances
279 | */
280 | public function getRequirements()
281 | {
282 | $array = array();
283 | foreach ($this->requirements as $req) {
284 | if (!$req->isOptional()) {
285 | $array[] = $req;
286 | }
287 | }
288 |
289 | return $array;
290 | }
291 |
292 | /**
293 | * Returns the mandatory requirements that were not met.
294 | *
295 | * @return array Array of Requirement instances
296 | */
297 | public function getFailedRequirements()
298 | {
299 | $array = array();
300 | foreach ($this->requirements as $req) {
301 | if (!$req->isFulfilled() && !$req->isOptional()) {
302 | $array[] = $req;
303 | }
304 | }
305 |
306 | return $array;
307 | }
308 |
309 | /**
310 | * Returns all optional recommendations.
311 | *
312 | * @return array Array of Requirement instances
313 | */
314 | public function getRecommendations()
315 | {
316 | $array = array();
317 | foreach ($this->requirements as $req) {
318 | if ($req->isOptional()) {
319 | $array[] = $req;
320 | }
321 | }
322 |
323 | return $array;
324 | }
325 |
326 | /**
327 | * Returns the recommendations that were not met.
328 | *
329 | * @return array Array of Requirement instances
330 | */
331 | public function getFailedRecommendations()
332 | {
333 | $array = array();
334 | foreach ($this->requirements as $req) {
335 | if (!$req->isFulfilled() && $req->isOptional()) {
336 | $array[] = $req;
337 | }
338 | }
339 |
340 | return $array;
341 | }
342 |
343 | /**
344 | * Returns whether a php.ini configuration is not correct.
345 | *
346 | * @return bool php.ini configuration problem?
347 | */
348 | public function hasPhpIniConfigIssue()
349 | {
350 | foreach ($this->requirements as $req) {
351 | if (!$req->isFulfilled() && $req instanceof PhpIniRequirement) {
352 | return true;
353 | }
354 | }
355 |
356 | return false;
357 | }
358 |
359 | /**
360 | * Returns the PHP configuration file (php.ini) path.
361 | *
362 | * @return string|false php.ini file path
363 | */
364 | public function getPhpIniConfigPath()
365 | {
366 | return get_cfg_var('cfg_file_path');
367 | }
368 | }
369 |
370 | /**
371 | * This class specifies all requirements and optional recommendations that
372 | * are necessary to run the Symfony Standard Edition.
373 | *
374 | * @author Tobias Schultze
375 | * @author Fabien Potencier
376 | */
377 | class SymfonyRequirements extends RequirementCollection
378 | {
379 | const REQUIRED_PHP_VERSION = '5.3.3';
380 |
381 | /**
382 | * Constructor that initializes the requirements.
383 | */
384 | public function __construct()
385 | {
386 | /* mandatory requirements follow */
387 |
388 | $installedPhpVersion = phpversion();
389 |
390 | $this->addRequirement(
391 | version_compare($installedPhpVersion, self::REQUIRED_PHP_VERSION, '>='),
392 | sprintf('PHP version must be at least %s (%s installed)', self::REQUIRED_PHP_VERSION, $installedPhpVersion),
393 | sprintf('You are running PHP version "%s", but Symfony needs at least PHP "%s" to run.
394 | Before using Symfony, upgrade your PHP installation, preferably to the latest version.',
395 | $installedPhpVersion, self::REQUIRED_PHP_VERSION),
396 | sprintf('Install PHP %s or newer (installed version is %s)', self::REQUIRED_PHP_VERSION, $installedPhpVersion)
397 | );
398 |
399 | $this->addRequirement(
400 | version_compare($installedPhpVersion, '5.3.16', '!='),
401 | 'PHP version must not be 5.3.16 as Symfony won\'t work properly with it',
402 | 'Install PHP 5.3.17 or newer (or downgrade to an earlier PHP version)'
403 | );
404 |
405 | $this->addRequirement(
406 | is_dir(__DIR__.'/../vendor/composer'),
407 | 'Vendor libraries must be installed',
408 | 'Vendor libraries are missing. Install composer following instructions from http://getcomposer.org/. '.
409 | 'Then run "php composer.phar install" to install them.'
410 | );
411 |
412 | $cacheDir = is_dir(__DIR__.'/../var/cache') ? __DIR__.'/../var/cache' : __DIR__.'/cache';
413 |
414 | $this->addRequirement(
415 | is_writable($cacheDir),
416 | 'app/cache/ or var/cache/ directory must be writable',
417 | 'Change the permissions of either "app/cache/" or "var/cache/" directory so that the web server can write into it.'
418 | );
419 |
420 | $logsDir = is_dir(__DIR__.'/../var/logs') ? __DIR__.'/../var/logs' : __DIR__.'/logs';
421 |
422 | $this->addRequirement(
423 | is_writable($logsDir),
424 | 'app/logs/ or var/logs/ directory must be writable',
425 | 'Change the permissions of either "app/logs/" or "var/logs/" directory so that the web server can write into it.'
426 | );
427 |
428 | $this->addPhpIniRequirement(
429 | 'date.timezone', true, false,
430 | 'date.timezone setting must be set',
431 | 'Set the "date.timezone" setting in php.ini* (like Europe/Paris).'
432 | );
433 |
434 | if (version_compare($installedPhpVersion, self::REQUIRED_PHP_VERSION, '>=')) {
435 | $timezones = array();
436 | foreach (DateTimeZone::listAbbreviations() as $abbreviations) {
437 | foreach ($abbreviations as $abbreviation) {
438 | $timezones[$abbreviation['timezone_id']] = true;
439 | }
440 | }
441 |
442 | $this->addRequirement(
443 | isset($timezones[@date_default_timezone_get()]),
444 | sprintf('Configured default timezone "%s" must be supported by your installation of PHP', @date_default_timezone_get()),
445 | 'Your default timezone is not supported by PHP. Check for typos in your php.ini file and have a look at the list of deprecated timezones at http://php.net/manual/en/timezones.others.php.'
446 | );
447 | }
448 |
449 | $this->addRequirement(
450 | function_exists('iconv'),
451 | 'iconv() must be available',
452 | 'Install and enable the iconv extension.'
453 | );
454 |
455 | $this->addRequirement(
456 | function_exists('json_encode'),
457 | 'json_encode() must be available',
458 | 'Install and enable the JSON extension.'
459 | );
460 |
461 | $this->addRequirement(
462 | function_exists('session_start'),
463 | 'session_start() must be available',
464 | 'Install and enable the session extension.'
465 | );
466 |
467 | $this->addRequirement(
468 | function_exists('ctype_alpha'),
469 | 'ctype_alpha() must be available',
470 | 'Install and enable the ctype extension.'
471 | );
472 |
473 | $this->addRequirement(
474 | function_exists('token_get_all'),
475 | 'token_get_all() must be available',
476 | 'Install and enable the Tokenizer extension.'
477 | );
478 |
479 | $this->addRequirement(
480 | function_exists('simplexml_import_dom'),
481 | 'simplexml_import_dom() must be available',
482 | 'Install and enable the SimpleXML extension.'
483 | );
484 |
485 | if (function_exists('apc_store') && ini_get('apc.enabled')) {
486 | if (version_compare($installedPhpVersion, '5.4.0', '>=')) {
487 | $this->addRequirement(
488 | version_compare(phpversion('apc'), '3.1.13', '>='),
489 | 'APC version must be at least 3.1.13 when using PHP 5.4',
490 | 'Upgrade your APC extension (3.1.13+).'
491 | );
492 | } else {
493 | $this->addRequirement(
494 | version_compare(phpversion('apc'), '3.0.17', '>='),
495 | 'APC version must be at least 3.0.17',
496 | 'Upgrade your APC extension (3.0.17+).'
497 | );
498 | }
499 | }
500 |
501 | $this->addPhpIniRequirement('detect_unicode', false);
502 |
503 | if (extension_loaded('suhosin')) {
504 | $this->addPhpIniRequirement(
505 | 'suhosin.executor.include.whitelist',
506 | create_function('$cfgValue', 'return false !== stripos($cfgValue, "phar");'),
507 | false,
508 | 'suhosin.executor.include.whitelist must be configured correctly in php.ini',
509 | 'Add "phar" to suhosin.executor.include.whitelist in php.ini*.'
510 | );
511 | }
512 |
513 | if (extension_loaded('xdebug')) {
514 | $this->addPhpIniRequirement(
515 | 'xdebug.show_exception_trace', false, true
516 | );
517 |
518 | $this->addPhpIniRequirement(
519 | 'xdebug.scream', false, true
520 | );
521 |
522 | $this->addPhpIniRecommendation(
523 | 'xdebug.max_nesting_level',
524 | create_function('$cfgValue', 'return $cfgValue > 100;'),
525 | true,
526 | 'xdebug.max_nesting_level should be above 100 in php.ini',
527 | 'Set "xdebug.max_nesting_level" to e.g. "250" in php.ini* to stop Xdebug\'s infinite recursion protection erroneously throwing a fatal error in your project.'
528 | );
529 | }
530 |
531 | $pcreVersion = defined('PCRE_VERSION') ? (float) PCRE_VERSION : null;
532 |
533 | $this->addRequirement(
534 | null !== $pcreVersion,
535 | 'PCRE extension must be available',
536 | 'Install the PCRE extension (version 8.0+).'
537 | );
538 |
539 | if (extension_loaded('mbstring')) {
540 | $this->addPhpIniRequirement(
541 | 'mbstring.func_overload',
542 | create_function('$cfgValue', 'return (int) $cfgValue === 0;'),
543 | true,
544 | 'string functions should not be overloaded',
545 | 'Set "mbstring.func_overload" to 0 in php.ini* to disable function overloading by the mbstring extension.'
546 | );
547 | }
548 |
549 | /* optional recommendations follow */
550 |
551 | if (file_exists(__DIR__.'/../vendor/composer')) {
552 | require_once __DIR__.'/../vendor/autoload.php';
553 |
554 | try {
555 | $r = new ReflectionClass('Sensio\Bundle\DistributionBundle\SensioDistributionBundle');
556 |
557 | $contents = file_get_contents(dirname($r->getFileName()).'/Resources/skeleton/app/SymfonyRequirements.php');
558 | } catch (ReflectionException $e) {
559 | $contents = '';
560 | }
561 | $this->addRecommendation(
562 | file_get_contents(__FILE__) === $contents,
563 | 'Requirements file should be up-to-date',
564 | 'Your requirements file is outdated. Run composer install and re-check your configuration.'
565 | );
566 | }
567 |
568 | $this->addRecommendation(
569 | version_compare($installedPhpVersion, '5.3.4', '>='),
570 | 'You should use at least PHP 5.3.4 due to PHP bug #52083 in earlier versions',
571 | 'Your project might malfunction randomly due to PHP bug #52083 ("Notice: Trying to get property of non-object"). Install PHP 5.3.4 or newer.'
572 | );
573 |
574 | $this->addRecommendation(
575 | version_compare($installedPhpVersion, '5.3.8', '>='),
576 | 'When using annotations you should have at least PHP 5.3.8 due to PHP bug #55156',
577 | 'Install PHP 5.3.8 or newer if your project uses annotations.'
578 | );
579 |
580 | $this->addRecommendation(
581 | version_compare($installedPhpVersion, '5.4.0', '!='),
582 | 'You should not use PHP 5.4.0 due to the PHP bug #61453',
583 | 'Your project might not work properly due to the PHP bug #61453 ("Cannot dump definitions which have method calls"). Install PHP 5.4.1 or newer.'
584 | );
585 |
586 | $this->addRecommendation(
587 | version_compare($installedPhpVersion, '5.4.11', '>='),
588 | 'When using the logout handler from the Symfony Security Component, you should have at least PHP 5.4.11 due to PHP bug #63379 (as a workaround, you can also set invalidate_session to false in the security logout handler configuration)',
589 | 'Install PHP 5.4.11 or newer if your project uses the logout handler from the Symfony Security Component.'
590 | );
591 |
592 | $this->addRecommendation(
593 | (version_compare($installedPhpVersion, '5.3.18', '>=') && version_compare($installedPhpVersion, '5.4.0', '<'))
594 | ||
595 | version_compare($installedPhpVersion, '5.4.8', '>='),
596 | 'You should use PHP 5.3.18+ or PHP 5.4.8+ to always get nice error messages for fatal errors in the development environment due to PHP bug #61767/#60909',
597 | 'Install PHP 5.3.18+ or PHP 5.4.8+ if you want nice error messages for all fatal errors in the development environment.'
598 | );
599 |
600 | if (null !== $pcreVersion) {
601 | $this->addRecommendation(
602 | $pcreVersion >= 8.0,
603 | sprintf('PCRE extension should be at least version 8.0 (%s installed)', $pcreVersion),
604 | 'PCRE 8.0+ is preconfigured in PHP since 5.3.2 but you are using an outdated version of it. Symfony probably works anyway but it is recommended to upgrade your PCRE extension.'
605 | );
606 | }
607 |
608 | $this->addRecommendation(
609 | class_exists('DomDocument'),
610 | 'PHP-DOM and PHP-XML modules should be installed',
611 | 'Install and enable the PHP-DOM and the PHP-XML modules.'
612 | );
613 |
614 | $this->addRecommendation(
615 | function_exists('mb_strlen'),
616 | 'mb_strlen() should be available',
617 | 'Install and enable the mbstring extension.'
618 | );
619 |
620 | $this->addRecommendation(
621 | function_exists('iconv'),
622 | 'iconv() should be available',
623 | 'Install and enable the iconv extension.'
624 | );
625 |
626 | $this->addRecommendation(
627 | function_exists('utf8_decode'),
628 | 'utf8_decode() should be available',
629 | 'Install and enable the XML extension.'
630 | );
631 |
632 | $this->addRecommendation(
633 | function_exists('filter_var'),
634 | 'filter_var() should be available',
635 | 'Install and enable the filter extension.'
636 | );
637 |
638 | if (!defined('PHP_WINDOWS_VERSION_BUILD')) {
639 | $this->addRecommendation(
640 | function_exists('posix_isatty'),
641 | 'posix_isatty() should be available',
642 | 'Install and enable the php_posix extension (used to colorize the CLI output).'
643 | );
644 | }
645 |
646 | $this->addRecommendation(
647 | extension_loaded('intl'),
648 | 'intl extension should be available',
649 | 'Install and enable the intl extension (used for validators).'
650 | );
651 |
652 | if (extension_loaded('intl')) {
653 | // in some WAMP server installations, new Collator() returns null
654 | $this->addRecommendation(
655 | null !== new Collator('fr_FR'),
656 | 'intl extension should be correctly configured',
657 | 'The intl extension does not behave properly. This problem is typical on PHP 5.3.X x64 WIN builds.'
658 | );
659 |
660 | // check for compatible ICU versions (only done when you have the intl extension)
661 | if (defined('INTL_ICU_VERSION')) {
662 | $version = INTL_ICU_VERSION;
663 | } else {
664 | $reflector = new ReflectionExtension('intl');
665 |
666 | ob_start();
667 | $reflector->info();
668 | $output = strip_tags(ob_get_clean());
669 |
670 | preg_match('/^ICU version +(?:=> )?(.*)$/m', $output, $matches);
671 | $version = $matches[1];
672 | }
673 |
674 | $this->addRecommendation(
675 | version_compare($version, '4.0', '>='),
676 | 'intl ICU version should be at least 4+',
677 | 'Upgrade your intl extension with a newer ICU version (4+).'
678 | );
679 |
680 | $this->addPhpIniRecommendation(
681 | 'intl.error_level',
682 | create_function('$cfgValue', 'return (int) $cfgValue === 0;'),
683 | true,
684 | 'intl.error_level should be 0 in php.ini',
685 | 'Set "intl.error_level" to "0" in php.ini* to inhibit the messages when an error occurs in ICU functions.'
686 | );
687 | }
688 |
689 | $accelerator =
690 | (extension_loaded('eaccelerator') && ini_get('eaccelerator.enable'))
691 | ||
692 | (extension_loaded('apc') && ini_get('apc.enabled'))
693 | ||
694 | (extension_loaded('Zend Optimizer+') && ini_get('zend_optimizerplus.enable'))
695 | ||
696 | (extension_loaded('Zend OPcache') && ini_get('opcache.enable'))
697 | ||
698 | (extension_loaded('xcache') && ini_get('xcache.cacher'))
699 | ||
700 | (extension_loaded('wincache') && ini_get('wincache.ocenabled'))
701 | ;
702 |
703 | $this->addRecommendation(
704 | $accelerator,
705 | 'a PHP accelerator should be installed',
706 | 'Install and/or enable a PHP accelerator (highly recommended).'
707 | );
708 |
709 | if (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN') {
710 | $this->addRecommendation(
711 | $this->getRealpathCacheSize() > 1000,
712 | 'realpath_cache_size should be above 1024 in php.ini',
713 | 'Set "realpath_cache_size" to e.g. "1024" in php.ini* to improve performance on windows.'
714 | );
715 | }
716 |
717 | $this->addPhpIniRecommendation('short_open_tag', false);
718 |
719 | $this->addPhpIniRecommendation('magic_quotes_gpc', false, true);
720 |
721 | $this->addPhpIniRecommendation('register_globals', false, true);
722 |
723 | $this->addPhpIniRecommendation('session.auto_start', false);
724 |
725 | $this->addRecommendation(
726 | class_exists('PDO'),
727 | 'PDO should be installed',
728 | 'Install PDO (mandatory for Doctrine).'
729 | );
730 |
731 | if (class_exists('PDO')) {
732 | $drivers = PDO::getAvailableDrivers();
733 | $this->addRecommendation(
734 | count($drivers) > 0,
735 | sprintf('PDO should have some drivers installed (currently available: %s)', count($drivers) ? implode(', ', $drivers) : 'none'),
736 | 'Install PDO drivers (mandatory for Doctrine).'
737 | );
738 | }
739 | }
740 |
741 | /**
742 | * Loads realpath_cache_size from php.ini and converts it to int.
743 | *
744 | * (e.g. 16k is converted to 16384 int)
745 | *
746 | * @return int
747 | */
748 | protected function getRealpathCacheSize()
749 | {
750 | $size = ini_get('realpath_cache_size');
751 | $size = trim($size);
752 | $unit = strtolower(substr($size, -1, 1));
753 | switch ($unit) {
754 | case 'g':
755 | return $size * 1024 * 1024 * 1024;
756 | case 'm':
757 | return $size * 1024 * 1024;
758 | case 'k':
759 | return $size * 1024;
760 | default:
761 | return (int) $size;
762 | }
763 | }
764 | }
765 |
--------------------------------------------------------------------------------
/web/app.php:
--------------------------------------------------------------------------------
1 | loadClassCache();
9 |
10 | $request = Request::createFromGlobals();
11 | $response = $app->handle($request);
12 | $response->send();
13 |
14 | $app->terminate($request, $response);
15 |
--------------------------------------------------------------------------------
/web/app_dev.php:
--------------------------------------------------------------------------------
1 | loadClassCache();
27 |
28 | $request = Request::createFromGlobals();
29 | $response = $app->handle($request);
30 | $response->send();
31 |
32 | $app->terminate($request, $response);
33 |
--------------------------------------------------------------------------------
/web/apple-touch-icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cawa87/symfony-micro/ac3e0378db4365119f38a0e1e556942c2b8c315c/web/apple-touch-icon.png
--------------------------------------------------------------------------------
/web/css/main.css:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cawa87/symfony-micro/ac3e0378db4365119f38a0e1e556942c2b8c315c/web/css/main.css
--------------------------------------------------------------------------------
/web/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cawa87/symfony-micro/ac3e0378db4365119f38a0e1e556942c2b8c315c/web/favicon.ico
--------------------------------------------------------------------------------
/web/robots.txt:
--------------------------------------------------------------------------------
1 | # www.robotstxt.org/
2 | # www.google.com/support/webmasters/bin/answer.py?hl=en&answer=156449
3 |
4 | User-agent: *
5 |
--------------------------------------------------------------------------------