├── .bowerrc ├── .gitignore ├── .travis.yml ├── LICENSE ├── README.md ├── app ├── .htaccess ├── AppCache.php ├── AppKernel.php ├── Resources │ └── views │ │ └── base.html.twig ├── SymfonyRequirements.php ├── autoload.php ├── cache │ └── .gitkeep ├── check.php ├── config │ ├── assets.json │ ├── config.php │ ├── config.yml │ ├── config_dev.yml │ ├── config_prod.yml │ ├── config_test.yml │ ├── parameters.yml.dist │ ├── routing.yml │ ├── routing_dev.yml │ └── security.yml ├── console ├── logs │ └── .gitkeep └── phpunit.xml.dist ├── bower.json ├── composer.json ├── gruntfile.js ├── package.json ├── src ├── .htaccess └── Acme │ └── DemoBundle │ ├── AcmeDemoBundle.php │ ├── Controller │ └── DemoController.php │ └── Resources │ ├── config │ └── routing.yml │ └── views │ ├── Demo │ └── index.html.twig │ └── layout.html.twig └── web ├── .htaccess ├── app.php ├── app_dev.php ├── apple-touch-icon.png ├── config.php ├── css └── main.css ├── favicon.ico ├── js └── script.js └── robots.txt /.bowerrc: -------------------------------------------------------------------------------- 1 | { 2 | "directory": "web/vendor" 3 | } 4 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /web/bundles/ 2 | /web/vendor/ 3 | /web/_static/ 4 | /node_modules/ 5 | /app/bootstrap.php.cache 6 | /app/cache/* 7 | /app/config/parameters.yml 8 | /app/logs/* 9 | !app/cache/.gitkeep 10 | !app/logs/.gitkeep 11 | /build/ 12 | /vendor/ 13 | /bin/ 14 | /composer.phar 15 | /composer.lock 16 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: php 2 | 3 | php: 4 | - 5.3.3 5 | - 5.3 6 | - 5.4 7 | 8 | before_script: composer install -n 9 | 10 | script: phpunit -c app 11 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2004-2013 Fabien Potencier 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the "Software"), to deal 5 | in the Software without restriction, including without limitation the rights 6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | copies of the Software, and to permit persons to whom the Software is furnished 8 | to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in all 11 | copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | THE SOFTWARE. 20 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Symfony Grunt Edition 2 | ===================== 3 | 4 | This is a Symfony Edition that replaces Assetic with a grunt configuration. I have some taken some 5 | liberties based on my development style. When doing frontend development, I don't like waiting for 6 | some kind of *watch* task. I like my updates to be instant. This edition allows for your frontend 7 | assets to be linked to the source in development and linked to the minified version in production. 8 | 9 | ## Requirements 10 | 11 | - npm 12 | - bower (`sudo npm install -g bower`) 13 | - grunt (`sudo npm install -g grunt-cli`) 14 | 15 | ## Installation 16 | 17 | ``` 18 | > composer install 19 | > bower install 20 | > npm install 21 | > grunt 22 | ``` 23 | 24 | ## Grunt Tasks 25 | 26 | - `clean`: removes `web/_static` contents 27 | - `jshint`: detect errors in your javascipt 28 | - `uglify`: minify your javascipt 29 | - `cssmin`: minify your css 30 | - `modernizr`: install/configure modernizr based on your javascript files\ 31 | - *(default)*: runs all the above 32 | 33 | ## Configuration 34 | 35 | To configure the assets for you project, add them to `app/config/assets.json`. Both Symfony2 and grunt use 36 | this configuration. 37 | 38 | ## Summary of changes from the Symfony Standard Edition 39 | 40 | ### New Files 41 | 42 | - `bower.json`: bower package configuration 43 | - `.bowerrc`: bower configuration to install frontend assets to `web/vendor` 44 | - `package.json`: npm package configuration (for grunt) 45 | - `app/config/assets.json`: global asset configuration 46 | - `app/config/config.php`: sets a Symfony2 parameter based on the above `assets.json` configuration 47 | - `gruntfile.js`: configures grunt, assets for minification are pulled from the above `assets.json` 48 | - `web/css/main.css`/`web/js/script.js`: test assets 49 | 50 | ### Modified Files 51 | 52 | - `app/config/config.yml`: added twig global variable `app_assets` which is set to the parameter set in `config.php` 53 | - `app/Resources/views/base.html.twig`: modified the `stylesheets` and `javascripts` block to load these assets 54 | based on the above `app_assets` configuration (`app.debug=true`: source is used, `app.debug=false`: min is used) 55 | 56 | ### Other Changes 57 | 58 | - Removed Assetic 59 | - Simplifed DemoBundle 60 | - Removed `bootstrap.php.cache` - use composer's `--optimize-autoloader` option 61 | -------------------------------------------------------------------------------- /app/.htaccess: -------------------------------------------------------------------------------- 1 | deny from all -------------------------------------------------------------------------------- /app/AppCache.php: -------------------------------------------------------------------------------- 1 | getEnvironment(), array('dev', 'test'))) { 21 | $bundles[] = new Acme\DemoBundle\AcmeDemoBundle(); 22 | $bundles[] = new Symfony\Bundle\WebProfilerBundle\WebProfilerBundle(); 23 | $bundles[] = new Sensio\Bundle\DistributionBundle\SensioDistributionBundle(); 24 | $bundles[] = new Sensio\Bundle\GeneratorBundle\SensioGeneratorBundle(); 25 | } 26 | 27 | return $bundles; 28 | } 29 | 30 | public function registerContainerConfiguration(LoaderInterface $loader) 31 | { 32 | $loader->load(__DIR__.'/config/config_'.$this->getEnvironment().'.yml'); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /app/Resources/views/base.html.twig: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | {% block title %}Welcome!{% endblock %} 6 | {% block stylesheets %} 7 | {% set css_assets = app.debug ? app_assets.css.dev : [app_assets.css.prod] %} 8 | 9 | {% for asset in css_assets %} 10 | 11 | {% endfor %} 12 | {% endblock %} 13 | 14 | 15 | 16 | 17 | {% block body %}{% endblock %} 18 | {% block javascripts %} 19 | {% set js_assets = app.debug ? app_assets.js.dev : [app_assets.js.prod] %} 20 | 21 | {% for asset in js_assets %} 22 | 23 | {% endfor %} 24 | {% endblock %} 25 | 26 | 27 | -------------------------------------------------------------------------------- /app/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 Boolean $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 Boolean $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 = (Boolean) $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 = (Boolean) $optional; 57 | } 58 | 59 | /** 60 | * Returns whether the requirement is fulfilled. 61 | * 62 | * @return Boolean 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 Boolean 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 Boolean|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 Boolean $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 Boolean $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 Boolean $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 Boolean $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 Boolean|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 Boolean $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 Boolean|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 Boolean $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 Boolean 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 | $baseDir = basename(__DIR__); 413 | 414 | $this->addRequirement( 415 | is_writable(__DIR__.'/cache'), 416 | "$baseDir/cache/ directory must be writable", 417 | "Change the permissions of the \"$baseDir/cache/\" directory so that the web server can write into it." 418 | ); 419 | 420 | $this->addRequirement( 421 | is_writable(__DIR__.'/logs'), 422 | "$baseDir/logs/ directory must be writable", 423 | "Change the permissions of the \"$baseDir/logs/\" directory so that the web server can write into it." 424 | ); 425 | 426 | $this->addPhpIniRequirement( 427 | 'date.timezone', true, false, 428 | 'date.timezone setting must be set', 429 | 'Set the "date.timezone" setting in php.ini* (like Europe/Paris).' 430 | ); 431 | 432 | if (version_compare($installedPhpVersion, self::REQUIRED_PHP_VERSION, '>=')) { 433 | $timezones = array(); 434 | foreach (DateTimeZone::listAbbreviations() as $abbreviations) { 435 | foreach ($abbreviations as $abbreviation) { 436 | $timezones[$abbreviation['timezone_id']] = true; 437 | } 438 | } 439 | 440 | $this->addRequirement( 441 | isset($timezones[date_default_timezone_get()]), 442 | sprintf('Configured default timezone "%s" must be supported by your installation of PHP', date_default_timezone_get()), 443 | '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.' 444 | ); 445 | } 446 | 447 | $this->addRequirement( 448 | function_exists('json_encode'), 449 | 'json_encode() must be available', 450 | 'Install and enable the JSON extension.' 451 | ); 452 | 453 | $this->addRequirement( 454 | function_exists('session_start'), 455 | 'session_start() must be available', 456 | 'Install and enable the session extension.' 457 | ); 458 | 459 | $this->addRequirement( 460 | function_exists('ctype_alpha'), 461 | 'ctype_alpha() must be available', 462 | 'Install and enable the ctype extension.' 463 | ); 464 | 465 | $this->addRequirement( 466 | function_exists('token_get_all'), 467 | 'token_get_all() must be available', 468 | 'Install and enable the Tokenizer extension.' 469 | ); 470 | 471 | $this->addRequirement( 472 | function_exists('simplexml_import_dom'), 473 | 'simplexml_import_dom() must be available', 474 | 'Install and enable the SimpleXML extension.' 475 | ); 476 | 477 | if (function_exists('apc_store') && ini_get('apc.enabled')) { 478 | if (version_compare($installedPhpVersion, '5.4.0', '>=')) { 479 | $this->addRequirement( 480 | version_compare(phpversion('apc'), '3.1.13', '>='), 481 | 'APC version must be at least 3.1.13 when using PHP 5.4', 482 | 'Upgrade your APC extension (3.1.13+).' 483 | ); 484 | } else { 485 | $this->addRequirement( 486 | version_compare(phpversion('apc'), '3.0.17', '>='), 487 | 'APC version must be at least 3.0.17', 488 | 'Upgrade your APC extension (3.0.17+).' 489 | ); 490 | } 491 | } 492 | 493 | $this->addPhpIniRequirement('detect_unicode', false); 494 | 495 | if (extension_loaded('suhosin')) { 496 | $this->addPhpIniRequirement( 497 | 'suhosin.executor.include.whitelist', 498 | create_function('$cfgValue', 'return false !== stripos($cfgValue, "phar");'), 499 | false, 500 | 'suhosin.executor.include.whitelist must be configured correctly in php.ini', 501 | 'Add "phar" to suhosin.executor.include.whitelist in php.ini*.' 502 | ); 503 | } 504 | 505 | if (extension_loaded('xdebug')) { 506 | $this->addPhpIniRequirement( 507 | 'xdebug.show_exception_trace', false, true 508 | ); 509 | 510 | $this->addPhpIniRequirement( 511 | 'xdebug.scream', false, true 512 | ); 513 | 514 | $this->addPhpIniRecommendation( 515 | 'xdebug.max_nesting_level', 516 | create_function('$cfgValue', 'return $cfgValue > 100;'), 517 | true, 518 | 'xdebug.max_nesting_level should be above 100 in php.ini', 519 | '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.' 520 | ); 521 | } 522 | 523 | $pcreVersion = defined('PCRE_VERSION') ? (float) PCRE_VERSION : null; 524 | 525 | $this->addRequirement( 526 | null !== $pcreVersion, 527 | 'PCRE extension must be available', 528 | 'Install the PCRE extension (version 8.0+).' 529 | ); 530 | 531 | /* optional recommendations follow */ 532 | 533 | $this->addRecommendation( 534 | file_get_contents(__FILE__) === file_get_contents(__DIR__.'/../vendor/sensio/distribution-bundle/Sensio/Bundle/DistributionBundle/Resources/skeleton/app/SymfonyRequirements.php'), 535 | 'Requirements file should be up-to-date', 536 | 'Your requirements file is outdated. Run composer install and re-check your configuration.' 537 | ); 538 | 539 | $this->addRecommendation( 540 | version_compare($installedPhpVersion, '5.3.4', '>='), 541 | 'You should use at least PHP 5.3.4 due to PHP bug #52083 in earlier versions', 542 | '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.' 543 | ); 544 | 545 | $this->addRecommendation( 546 | version_compare($installedPhpVersion, '5.3.8', '>='), 547 | 'When using annotations you should have at least PHP 5.3.8 due to PHP bug #55156', 548 | 'Install PHP 5.3.8 or newer if your project uses annotations.' 549 | ); 550 | 551 | $this->addRecommendation( 552 | version_compare($installedPhpVersion, '5.4.0', '!='), 553 | 'You should not use PHP 5.4.0 due to the PHP bug #61453', 554 | '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.' 555 | ); 556 | 557 | $this->addRecommendation( 558 | version_compare($installedPhpVersion, '5.4.11', '>='), 559 | '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)', 560 | 'Install PHP 5.4.11 or newer if your project uses the logout handler from the Symfony Security Component.' 561 | ); 562 | 563 | $this->addRecommendation( 564 | (version_compare($installedPhpVersion, '5.3.18', '>=') && version_compare($installedPhpVersion, '5.4.0', '<')) 565 | || 566 | version_compare($installedPhpVersion, '5.4.8', '>='), 567 | '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', 568 | 'Install PHP 5.3.18+ or PHP 5.4.8+ if you want nice error messages for all fatal errors in the development environment.' 569 | ); 570 | 571 | if (null !== $pcreVersion) { 572 | $this->addRecommendation( 573 | $pcreVersion >= 8.0, 574 | sprintf('PCRE extension should be at least version 8.0 (%s installed)', $pcreVersion), 575 | '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.' 576 | ); 577 | } 578 | 579 | $this->addRecommendation( 580 | class_exists('DomDocument'), 581 | 'PHP-XML module should be installed', 582 | 'Install and enable the PHP-XML module.' 583 | ); 584 | 585 | $this->addRecommendation( 586 | function_exists('mb_strlen'), 587 | 'mb_strlen() should be available', 588 | 'Install and enable the mbstring extension.' 589 | ); 590 | 591 | $this->addRecommendation( 592 | function_exists('iconv'), 593 | 'iconv() should be available', 594 | 'Install and enable the iconv extension.' 595 | ); 596 | 597 | $this->addRecommendation( 598 | function_exists('utf8_decode'), 599 | 'utf8_decode() should be available', 600 | 'Install and enable the XML extension.' 601 | ); 602 | 603 | if (!defined('PHP_WINDOWS_VERSION_BUILD')) { 604 | $this->addRecommendation( 605 | function_exists('posix_isatty'), 606 | 'posix_isatty() should be available', 607 | 'Install and enable the php_posix extension (used to colorize the CLI output).' 608 | ); 609 | } 610 | 611 | $this->addRecommendation( 612 | class_exists('Locale'), 613 | 'intl extension should be available', 614 | 'Install and enable the intl extension (used for validators).' 615 | ); 616 | 617 | if (class_exists('Collator')) { 618 | $this->addRecommendation( 619 | null !== new Collator('fr_FR'), 620 | 'intl extension should be correctly configured', 621 | 'The intl extension does not behave properly. This problem is typical on PHP 5.3.X x64 WIN builds.' 622 | ); 623 | } 624 | 625 | if (class_exists('Locale')) { 626 | if (defined('INTL_ICU_VERSION')) { 627 | $version = INTL_ICU_VERSION; 628 | } else { 629 | $reflector = new ReflectionExtension('intl'); 630 | 631 | ob_start(); 632 | $reflector->info(); 633 | $output = strip_tags(ob_get_clean()); 634 | 635 | preg_match('/^ICU version +(?:=> )?(.*)$/m', $output, $matches); 636 | $version = $matches[1]; 637 | } 638 | 639 | $this->addRecommendation( 640 | version_compare($version, '4.0', '>='), 641 | 'intl ICU version should be at least 4+', 642 | 'Upgrade your intl extension with a newer ICU version (4+).' 643 | ); 644 | } 645 | 646 | $accelerator = 647 | (extension_loaded('eaccelerator') && ini_get('eaccelerator.enable')) 648 | || 649 | (extension_loaded('apc') && ini_get('apc.enabled')) 650 | || 651 | (extension_loaded('Zend OPcache') && ini_get('opcache.enable')) 652 | || 653 | (extension_loaded('xcache') && ini_get('xcache.cacher')) 654 | || 655 | (extension_loaded('wincache') && ini_get('wincache.ocenabled')) 656 | ; 657 | 658 | $this->addRecommendation( 659 | $accelerator, 660 | 'a PHP accelerator should be installed', 661 | 'Install and enable a PHP accelerator like APC (highly recommended).' 662 | ); 663 | 664 | $this->addPhpIniRecommendation('short_open_tag', false); 665 | 666 | $this->addPhpIniRecommendation('magic_quotes_gpc', false, true); 667 | 668 | $this->addPhpIniRecommendation('register_globals', false, true); 669 | 670 | $this->addPhpIniRecommendation('session.auto_start', false); 671 | 672 | $this->addRecommendation( 673 | class_exists('PDO'), 674 | 'PDO should be installed', 675 | 'Install PDO (mandatory for Doctrine).' 676 | ); 677 | 678 | if (class_exists('PDO')) { 679 | $drivers = PDO::getAvailableDrivers(); 680 | $this->addRecommendation( 681 | count($drivers), 682 | sprintf('PDO should have some drivers installed (currently available: %s)', count($drivers) ? implode(', ', $drivers) : 'none'), 683 | 'Install PDO drivers (mandatory for Doctrine).' 684 | ); 685 | } 686 | } 687 | } 688 | -------------------------------------------------------------------------------- /app/autoload.php: -------------------------------------------------------------------------------- 1 | getPhpIniConfigPath(); 8 | 9 | echo "********************************\n"; 10 | echo "* *\n"; 11 | echo "* Symfony requirements check *\n"; 12 | echo "* *\n"; 13 | echo "********************************\n\n"; 14 | 15 | echo $iniPath ? sprintf("* Configuration file used by PHP: %s\n\n", $iniPath) : "* WARNING: No configuration file (php.ini) used by PHP!\n\n"; 16 | 17 | echo "** ATTENTION **\n"; 18 | echo "* The PHP CLI can use a different php.ini file\n"; 19 | echo "* than the one used with your web server.\n"; 20 | if ('\\' == DIRECTORY_SEPARATOR) { 21 | echo "* (especially on the Windows platform)\n"; 22 | } 23 | echo "* To be on the safe side, please also launch the requirements check\n"; 24 | echo "* from your web server using the web/config.php script.\n"; 25 | 26 | echo_title('Mandatory requirements'); 27 | 28 | $checkPassed = true; 29 | foreach ($symfonyRequirements->getRequirements() as $req) { 30 | /** @var $req Requirement */ 31 | echo_requirement($req); 32 | if (!$req->isFulfilled()) { 33 | $checkPassed = false; 34 | } 35 | } 36 | 37 | echo_title('Optional recommendations'); 38 | 39 | foreach ($symfonyRequirements->getRecommendations() as $req) { 40 | echo_requirement($req); 41 | } 42 | 43 | exit($checkPassed ? 0 : 1); 44 | 45 | /** 46 | * Prints a Requirement instance 47 | */ 48 | function echo_requirement(Requirement $requirement) 49 | { 50 | $result = $requirement->isFulfilled() ? 'OK' : ($requirement->isOptional() ? 'WARNING' : 'ERROR'); 51 | echo ' ' . str_pad($result, 9); 52 | echo $requirement->getTestMessage() . "\n"; 53 | 54 | if (!$requirement->isFulfilled()) { 55 | echo sprintf(" %s\n\n", $requirement->getHelpText()); 56 | } 57 | } 58 | 59 | function echo_title($title) 60 | { 61 | echo "\n** $title **\n\n"; 62 | } 63 | -------------------------------------------------------------------------------- /app/config/assets.json: -------------------------------------------------------------------------------- 1 | { 2 | "css": { 3 | "dev": [ 4 | "vendor/bootstrap/docs/assets/css/bootstrap.css", 5 | "vendor/bootstrap/docs/assets/css/bootstrap-responsive.css", 6 | "css/main.css" 7 | ], 8 | "prod": "_static/css/style.min.css" 9 | }, 10 | "js": { 11 | "dev": [ 12 | "vendor/jquery/jquery.min.js", 13 | "vendor/bootstrap/docs/assets/js/bootstrap.js", 14 | "js/script.js" 15 | ], 16 | "prod": "_static/js/script.min.js" 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /app/config/config.php: -------------------------------------------------------------------------------- 1 | getParameter('kernel.root_dir').'/config/assets.json'), true); 4 | 5 | $container->setParameter('app.assets', $assets); 6 | -------------------------------------------------------------------------------- /app/config/config.yml: -------------------------------------------------------------------------------- 1 | imports: 2 | - { resource: parameters.yml } 3 | - { resource: security.yml } 4 | - { resource: config.php } 5 | 6 | framework: 7 | #esi: ~ 8 | #translator: { fallback: "%locale%" } 9 | secret: "%secret%" 10 | router: 11 | resource: "%kernel.root_dir%/config/routing.yml" 12 | strict_requirements: ~ 13 | form: ~ 14 | csrf_protection: ~ 15 | validation: { enable_annotations: true } 16 | templating: 17 | engines: ['twig'] 18 | #assets_version: SomeVersionScheme 19 | default_locale: "%locale%" 20 | trusted_hosts: ~ 21 | trusted_proxies: ~ 22 | session: 23 | # handler_id set to null will use default session handler from php.ini 24 | handler_id: ~ 25 | fragments: ~ 26 | http_method_override: true 27 | 28 | # Twig Configuration 29 | twig: 30 | debug: "%kernel.debug%" 31 | strict_variables: "%kernel.debug%" 32 | globals: 33 | app_assets: %app.assets% 34 | 35 | # Doctrine Configuration 36 | doctrine: 37 | dbal: 38 | driver: "%database_driver%" 39 | host: "%database_host%" 40 | port: "%database_port%" 41 | dbname: "%database_name%" 42 | user: "%database_user%" 43 | password: "%database_password%" 44 | charset: UTF8 45 | # if using pdo_sqlite as your database driver, add the path in parameters.yml 46 | # e.g. database_path: "%kernel.root_dir%/data/data.db3" 47 | # path: "%database_path%" 48 | 49 | orm: 50 | auto_generate_proxy_classes: "%kernel.debug%" 51 | auto_mapping: true 52 | 53 | # Swiftmailer Configuration 54 | swiftmailer: 55 | transport: "%mailer_transport%" 56 | host: "%mailer_host%" 57 | username: "%mailer_user%" 58 | password: "%mailer_password%" 59 | spool: { type: memory } 60 | -------------------------------------------------------------------------------- /app/config/config_dev.yml: -------------------------------------------------------------------------------- 1 | imports: 2 | - { resource: config.yml } 3 | 4 | framework: 5 | router: 6 | resource: "%kernel.root_dir%/config/routing_dev.yml" 7 | strict_requirements: true 8 | profiler: { only_exceptions: false } 9 | 10 | web_profiler: 11 | toolbar: true 12 | intercept_redirects: false 13 | 14 | monolog: 15 | handlers: 16 | main: 17 | type: stream 18 | path: "%kernel.logs_dir%/%kernel.environment%.log" 19 | level: debug 20 | console: 21 | type: console 22 | bubble: false 23 | # uncomment to get logging in your browser 24 | # you may have to allow bigger header sizes in your Web server configuration 25 | #firephp: 26 | # type: firephp 27 | # level: info 28 | #chromephp: 29 | # type: chromephp 30 | # level: info 31 | 32 | #swiftmailer: 33 | # delivery_address: me@example.com 34 | -------------------------------------------------------------------------------- /app/config/config_prod.yml: -------------------------------------------------------------------------------- 1 | imports: 2 | - { resource: config.yml } 3 | 4 | #framework: 5 | # validation: 6 | # cache: apc 7 | 8 | #doctrine: 9 | # orm: 10 | # metadata_cache_driver: apc 11 | # result_cache_driver: apc 12 | # query_cache_driver: apc 13 | 14 | monolog: 15 | handlers: 16 | main: 17 | type: fingers_crossed 18 | action_level: error 19 | handler: nested 20 | nested: 21 | type: stream 22 | path: "%kernel.logs_dir%/%kernel.environment%.log" 23 | level: debug 24 | console: 25 | type: console 26 | -------------------------------------------------------------------------------- /app/config/config_test.yml: -------------------------------------------------------------------------------- 1 | imports: 2 | - { resource: config_dev.yml } 3 | 4 | framework: 5 | test: ~ 6 | session: 7 | storage_id: session.storage.mock_file 8 | profiler: 9 | collect: false 10 | 11 | web_profiler: 12 | toolbar: false 13 | intercept_redirects: false 14 | 15 | swiftmailer: 16 | disable_delivery: true 17 | -------------------------------------------------------------------------------- /app/config/parameters.yml.dist: -------------------------------------------------------------------------------- 1 | parameters: 2 | database_driver: pdo_mysql 3 | database_host: 127.0.0.1 4 | database_port: ~ 5 | database_name: symfony 6 | database_user: root 7 | database_password: ~ 8 | 9 | mailer_transport: smtp 10 | mailer_host: 127.0.0.1 11 | mailer_user: ~ 12 | mailer_password: ~ 13 | 14 | locale: en 15 | secret: ThisTokenIsNotSoSecretChangeIt 16 | -------------------------------------------------------------------------------- /app/config/routing.yml: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kbond/symfony-grunt-edition/635e10180173c6b6703ac1cf717b619131b57511/app/config/routing.yml -------------------------------------------------------------------------------- /app/config/routing_dev.yml: -------------------------------------------------------------------------------- 1 | _wdt: 2 | resource: "@WebProfilerBundle/Resources/config/routing/wdt.xml" 3 | prefix: /_wdt 4 | 5 | _profiler: 6 | resource: "@WebProfilerBundle/Resources/config/routing/profiler.xml" 7 | prefix: /_profiler 8 | 9 | _configurator: 10 | resource: "@SensioDistributionBundle/Resources/config/routing/webconfigurator.xml" 11 | prefix: /_configurator 12 | 13 | _main: 14 | resource: routing.yml 15 | 16 | # AcmeDemoBundle routes (to be removed) 17 | _acme_demo: 18 | resource: "@AcmeDemoBundle/Resources/config/routing.yml" 19 | -------------------------------------------------------------------------------- /app/config/security.yml: -------------------------------------------------------------------------------- 1 | security: 2 | encoders: 3 | Symfony\Component\Security\Core\User\User: plaintext 4 | 5 | role_hierarchy: 6 | ROLE_ADMIN: ROLE_USER 7 | ROLE_SUPER_ADMIN: [ROLE_USER, ROLE_ADMIN, ROLE_ALLOWED_TO_SWITCH] 8 | 9 | providers: 10 | in_memory: 11 | memory: 12 | users: 13 | user: { password: userpass, roles: [ 'ROLE_USER' ] } 14 | admin: { password: adminpass, roles: [ 'ROLE_ADMIN' ] } 15 | 16 | firewalls: 17 | dev: 18 | pattern: ^/(_(profiler|wdt)|css|images|js)/ 19 | security: false 20 | 21 | login: 22 | pattern: ^/demo/secured/login$ 23 | security: false 24 | 25 | secured_area: 26 | pattern: ^/demo/secured/ 27 | form_login: 28 | check_path: _security_check 29 | login_path: _demo_login 30 | logout: 31 | path: _demo_logout 32 | target: _demo 33 | #anonymous: ~ 34 | #http_basic: 35 | # realm: "Secured Demo Area" 36 | 37 | access_control: 38 | #- { path: ^/login, roles: IS_AUTHENTICATED_ANONYMOUSLY, requires_channel: https } 39 | -------------------------------------------------------------------------------- /app/console: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env php 2 | getParameterOption(array('--env', '-e'), getenv('SYMFONY_ENV') ?: 'dev'); 19 | $debug = getenv('SYMFONY_DEBUG') !== '0' && !$input->hasParameterOption(array('--no-debug', '')) && $env !== 'prod'; 20 | 21 | if ($debug) { 22 | Debug::enable(); 23 | } 24 | 25 | $kernel = new AppKernel($env, $debug); 26 | $application = new Application($kernel); 27 | $application->run($input); 28 | -------------------------------------------------------------------------------- /app/logs/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kbond/symfony-grunt-edition/635e10180173c6b6703ac1cf717b619131b57511/app/logs/.gitkeep -------------------------------------------------------------------------------- /app/phpunit.xml.dist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 15 | 16 | 17 | 18 | ../src/*/*Bundle/Tests 19 | ../src/*/Bundle/*Bundle/Tests 20 | 21 | 22 | 23 | 28 | 29 | 30 | 31 | ../src 32 | 33 | ../src/*/*Bundle/Resources 34 | ../src/*/*Bundle/Tests 35 | ../src/*/Bundle/*Bundle/Resources 36 | ../src/*/Bundle/*Bundle/Tests 37 | 38 | 39 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /bower.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "symfony-grunt", 3 | "dependencies": { 4 | "jquery": "1.10.2", 5 | "bootstrap": "2.3.2" 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "kbond/symfony-grunt-edition", 3 | "license": "MIT", 4 | "type": "project", 5 | "description": "The \"Symfony Grunt Edition\" distribution", 6 | "autoload": { 7 | "psr-0": { "": "src/" } 8 | }, 9 | "require": { 10 | "php": ">=5.3.3", 11 | "symfony/symfony": "~2.4", 12 | "doctrine/orm": "~2.2,>=2.2.3", 13 | "doctrine/doctrine-bundle": "~1.2", 14 | "twig/extensions": "~1.0", 15 | "symfony/swiftmailer-bundle": "~2.3", 16 | "symfony/monolog-bundle": "~2.4", 17 | "sensio/distribution-bundle": "~2.3", 18 | "sensio/framework-extra-bundle": "~3.0", 19 | "sensio/generator-bundle": "~2.3", 20 | "incenteev/composer-parameter-handler": "~2.0" 21 | }, 22 | "scripts": { 23 | "post-install-cmd": [ 24 | "Incenteev\\ParameterHandler\\ScriptHandler::buildParameters", 25 | "Sensio\\Bundle\\DistributionBundle\\Composer\\ScriptHandler::clearCache", 26 | "Sensio\\Bundle\\DistributionBundle\\Composer\\ScriptHandler::installAssets", 27 | "Sensio\\Bundle\\DistributionBundle\\Composer\\ScriptHandler::installRequirementsFile" 28 | ], 29 | "post-update-cmd": [ 30 | "Incenteev\\ParameterHandler\\ScriptHandler::buildParameters", 31 | "Sensio\\Bundle\\DistributionBundle\\Composer\\ScriptHandler::clearCache", 32 | "Sensio\\Bundle\\DistributionBundle\\Composer\\ScriptHandler::installAssets", 33 | "Sensio\\Bundle\\DistributionBundle\\Composer\\ScriptHandler::installRequirementsFile" 34 | ] 35 | }, 36 | "config": { 37 | "bin-dir": "bin" 38 | }, 39 | "extra": { 40 | "symfony-app-dir": "app", 41 | "symfony-web-dir": "web", 42 | "incenteev-parameters": { 43 | "file": "app/config/parameters.yml" 44 | } 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /gruntfile.js: -------------------------------------------------------------------------------- 1 | module.exports = function (grunt) { 2 | // read in assets from configuration 3 | var assets = grunt.file.readJSON('app/config/assets.json'); 4 | 5 | // prefix assets with 'web/' 6 | var loadAssets = function(config) { 7 | var ret = {}; 8 | var dest = 'web/' + config.prod; 9 | var files = []; 10 | 11 | config.dev.forEach(function(val) { 12 | files.push('web/' + val); 13 | }); 14 | 15 | ret[dest] = files; 16 | 17 | return ret; 18 | }; 19 | 20 | grunt.initConfig({ 21 | pkg: grunt.file.readJSON('package.json'), 22 | 23 | modernizr: { 24 | devFile: "remote", 25 | outputFile: "web/_static/js/modernizr.js", 26 | files: ["web/js/*", "web/css/*"] 27 | }, 28 | 29 | jshint: { 30 | options: { 31 | reporter: require('jshint-stylish') 32 | }, 33 | all: [ 34 | 'Gruntfile.js', 35 | 'web/js/*' 36 | ] 37 | }, 38 | 39 | uglify: { 40 | options: { 41 | report: 'min', 42 | banner: '/*! <%= pkg.name %> <%= grunt.template.today("yyyy-mm-dd") %> */\n' 43 | }, 44 | build: { 45 | files: loadAssets(assets.js) 46 | } 47 | }, 48 | 49 | cssmin: { 50 | options: { 51 | report: 'min', 52 | root: 'web', 53 | target: 'web', 54 | banner: '/*! <%= pkg.name %> <%= grunt.template.today("yyyy-mm-dd") %> */\n' 55 | }, 56 | build: { 57 | files: loadAssets(assets.css) 58 | } 59 | }, 60 | 61 | clean: ['web/_static/*'] 62 | }); 63 | 64 | grunt.loadNpmTasks("grunt-modernizr"); 65 | grunt.loadNpmTasks('grunt-contrib-jshint'); 66 | grunt.loadNpmTasks('grunt-contrib-uglify'); 67 | grunt.loadNpmTasks('grunt-contrib-cssmin'); 68 | grunt.loadNpmTasks('grunt-contrib-clean'); 69 | 70 | grunt.registerTask('default', ['clean', 'jshint', 'uglify', 'cssmin', 'modernizr']); 71 | }; 72 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "symfony-grunt", 3 | "devDependencies": { 4 | "grunt": "~0.4.2", 5 | "grunt-contrib-jshint": "~0.6.3", 6 | "jshint-stylish": "~0.1.4", 7 | "grunt-contrib-uglify": "~0.2.2", 8 | "grunt-contrib-cssmin": "~0.7.0", 9 | "grunt-modernizr": "~0.4.1", 10 | "grunt-contrib-clean": "~0.5.0" 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/.htaccess: -------------------------------------------------------------------------------- 1 | deny from all -------------------------------------------------------------------------------- /src/Acme/DemoBundle/AcmeDemoBundle.php: -------------------------------------------------------------------------------- 1 | {{ block('title') }} 7 | {% endblock %} 8 | -------------------------------------------------------------------------------- /src/Acme/DemoBundle/Resources/views/layout.html.twig: -------------------------------------------------------------------------------- 1 | {% extends "::base.html.twig" %} 2 | 3 | {% block body %} 4 | {% block content %}{% endblock %} 5 | {% endblock %} 6 | -------------------------------------------------------------------------------- /web/.htaccess: -------------------------------------------------------------------------------- 1 | # Use the front controller as index file. It serves as a fallback solution when 2 | # every other rewrite/redirect fails (e.g. in an aliased environment without 3 | # mod_rewrite). Additionally, this reduces the matching process for the 4 | # start page (path "/") because otherwise Apache will apply the rewriting rules 5 | # to each configured DirectoryIndex file (e.g. index.php, index.html, index.pl). 6 | DirectoryIndex app.php 7 | 8 | 9 | RewriteEngine On 10 | 11 | # Determine the RewriteBase automatically and set it as environment variable. 12 | # If you are using Apache aliases to do mass virtual hosting or installed the 13 | # project in a subdirectory, the base path will be prepended to allow proper 14 | # resolution of the app.php file and to redirect to the correct URI. It will 15 | # work in environments without path prefix as well, providing a safe, one-size 16 | # fits all solution. But as you do not need it in this case, you can comment 17 | # the following 2 lines to eliminate the overhead. 18 | RewriteCond %{REQUEST_URI}::$1 ^(/.+)/(.*)::\2$ 19 | RewriteRule ^(.*) - [E=BASE:%1] 20 | 21 | # Redirect to URI without front controller to prevent duplicate content 22 | # (with and without `/app.php`). Only do this redirect on the initial 23 | # rewrite by Apache and not on subsequent cycles. Otherwise we would get an 24 | # endless redirect loop (request -> rewrite to front controller -> 25 | # redirect -> request -> ...). 26 | # So in case you get a "too many redirects" error or you always get redirected 27 | # to the start page because your Apache does not expose the REDIRECT_STATUS 28 | # environment variable, you have 2 choices: 29 | # - disable this feature by commenting the following 2 lines or 30 | # - use Apache >= 2.3.9 and replace all L flags by END flags and remove the 31 | # following RewriteCond (best solution) 32 | RewriteCond %{ENV:REDIRECT_STATUS} ^$ 33 | RewriteRule ^app\.php(/(.*)|$) %{ENV:BASE}/$2 [R=301,L] 34 | 35 | # If the requested filename exists, simply serve it. 36 | # We only want to let Apache serve files and not directories. 37 | RewriteCond %{REQUEST_FILENAME} -f 38 | RewriteRule .? - [L] 39 | 40 | # Rewrite all other queries to the front controller. 41 | RewriteRule .? %{ENV:BASE}/app.php [L] 42 | 43 | 44 | 45 | 46 | # When mod_rewrite is not available, we instruct a temporary redirect of 47 | # the start page to the front controller explicitly so that the website 48 | # and the generated links can still be used. 49 | RedirectMatch 302 ^/$ /app.php/ 50 | # RedirectTemp cannot be used instead 51 | 52 | 53 | -------------------------------------------------------------------------------- /web/app.php: -------------------------------------------------------------------------------- 1 | handle($request); 17 | $response->send(); 18 | $kernel->terminate($request, $response); 19 | -------------------------------------------------------------------------------- /web/app_dev.php: -------------------------------------------------------------------------------- 1 | handle($request); 28 | $response->send(); 29 | $kernel->terminate($request, $response); 30 | -------------------------------------------------------------------------------- /web/apple-touch-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kbond/symfony-grunt-edition/635e10180173c6b6703ac1cf717b619131b57511/web/apple-touch-icon.png -------------------------------------------------------------------------------- /web/config.php: -------------------------------------------------------------------------------- 1 | getFailedRequirements(); 20 | $minorProblems = $symfonyRequirements->getFailedRecommendations(); 21 | 22 | ?> 23 | 24 | 25 | 26 | 27 | 28 | Symfony Configuration 29 | 30 | 31 | 32 | 33 | 34 |
35 |
36 | 39 | 40 | 60 |
61 | 62 |
63 |
64 |
65 |

Welcome!

66 |

Welcome to your new Symfony project.

67 |

68 | This script will guide you through the basic configuration of your project. 69 | You can also do the same by editing the ‘app/config/parameters.yml’ file directly. 70 |

71 | 72 | 73 |

Major problems

74 |

Major problems have been detected and must be fixed before continuing:

75 |
    76 | 77 |
  1. getHelpHtml() ?>
  2. 78 | 79 |
80 | 81 | 82 | 83 |

Recommendations

84 |

85 | Additionally, toTo enhance your Symfony experience, 86 | it’s recommended that you fix the following: 87 |

88 |
    89 | 90 |
  1. getHelpHtml() ?>
  2. 91 | 92 |
93 | 94 | 95 | hasPhpIniConfigIssue()): ?> 96 |

* 97 | getPhpIniConfigPath()): ?> 98 | Changes to the php.ini file must be done in "getPhpIniConfigPath() ?>". 99 | 100 | To change settings, create a "php.ini". 101 | 102 |

103 | 104 | 105 | 106 |

Your configuration looks good to run Symfony.

107 | 108 | 109 | 118 |
119 |
120 |
121 |
Symfony Standard Edition
122 |
123 | 124 | 125 | -------------------------------------------------------------------------------- /web/css/main.css: -------------------------------------------------------------------------------- 1 | h1 { 2 | font-style: italic; 3 | } 4 | -------------------------------------------------------------------------------- /web/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kbond/symfony-grunt-edition/635e10180173c6b6703ac1cf717b619131b57511/web/favicon.ico -------------------------------------------------------------------------------- /web/js/script.js: -------------------------------------------------------------------------------- 1 | $(function() { 2 | $('h1').css('color', '#900'); 3 | }); 4 | -------------------------------------------------------------------------------- /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 | --------------------------------------------------------------------------------