diff --git a/.gitignore b/.gitignore index 8c2fd1f608..3350e520bb 100644 --- a/.gitignore +++ b/.gitignore @@ -17,22 +17,34 @@ # More details about excluding specific file on your local environment can be found # in the official GitHub article: https://help.github.com/articles/ignoring-files/ +/.web-server-pid +/app/config/parameters.yml +/build/ +/phpunit.xml +/var/* +!/var/cache +/var/cache/* +!var/cache/.gitkeep +!/var/logs +/var/logs/* +!var/logs/.gitkeep +!/var/sessions +/var/sessions/* +!var/sessions/.gitkeep +!var/SymfonyRequirements.php /vendor/ +/web/bundles/ + .php~ -/bin/behat -/bin/phpunit -/app/check.php -/app/SymfonyRequirements.php -/app/cache/ -/app/logs/ + +# Legacy related ignores, that are generated by composer (settings not handled out of the box) /ezpublish_legacy -/app/config/parameters.yml -/app/bootstrap.php.cache -/doc/docker/entrypoint/*/*.sql /web/index_treemenu.php /web/index_rest.php /web/index_cluster.php -/web/bundles/ + +/doc/docker/entrypoint/*/*.sql + /web/css/ /web/js/ web/fonts/ @@ -41,6 +53,7 @@ web/fonts/ /web/share /web/var /web/.htaccess + composer.phar composer.lock .buildpath diff --git a/.platform.app.yaml b/.platform.app.yaml index eb10a6a7b1..b6b945b587 100644 --- a/.platform.app.yaml +++ b/.platform.app.yaml @@ -36,9 +36,11 @@ disk: 2048 # The mounts that will be performed when the package is deployed. mounts: - "/app/cache": "shared:files/cache" - "/app/logs": "shared:files/logs" + "/var/cache": "shared:files/cache" + "/var/logs": "shared:files/logs" "/web/var": "shared:files/files" + # Might want to not mount this one, it will slow down sessions, if you need cluster use memcached/redis! + "/var/sessions": "shared:files/sessions" # The hooks that will be performed when the package is deployed. hooks: @@ -61,10 +63,10 @@ hooks: export SYMFONY_ENV=prod fi if [ ! -f web/var/.platform.installed ]; then - php -d memory_limit=-1 app/console ezplatform:install --env=$SYMFONY_ENV $INSTALL_EZ_INSTALL_TYPE + php -d memory_limit=-1 bin/console ezplatform:install --env=$SYMFONY_ENV $INSTALL_EZ_INSTALL_TYPE touch web/var/.platform.installed fi - app/console --env=$SYMFONY_ENV cache:clear + bin/console --env=$SYMFONY_ENV cache:clear # The configuration of scheduled execution. # see http://symfony.com/doc/current/components/console/introduction.html diff --git a/.travis.yml b/.travis.yml index 2602a3ddf7..e1b75e66b6 100644 --- a/.travis.yml +++ b/.travis.yml @@ -16,11 +16,14 @@ env: - SYMFONY_DEBUG=1 # list of behat arguments to test matrix: - - TEST_CMD="bin/behat -vv --profile=rest --suite=fullJson --tags=~@broken" COMPOSE_FILE="doc/docker/base-dev.yml:doc/docker/varnish.yml:doc/docker/selenium.yml" WEB_HOST="varnish" + # TMP disable usage of varnish until we figure out segmentation faulty issue on 2.0 + #- TEST_CMD="bin/behat -vv --profile=rest --suite=fullJson --tags=~@broken" COMPOSE_FILE="doc/docker/base-dev.yml:doc/docker/varnish.yml:doc/docker/selenium.yml" WEB_HOST="varnish" + - TEST_CMD="bin/behat -vv --profile=rest --suite=fullJson --tags=~@broken" COMPOSE_FILE="doc/docker/base-dev.yml:doc/docker/selenium.yml" - TEST_CMD="bin/behat -vv --profile=rest --suite=fullXml --tags=~@broken" - TEST_CMD="bin/behat -vv --profile=core --tags=~@broken" - TEST_CMD="bin/phpunit -v vendor/ezsystems/ezpublish-kernel/eZ/Bundle/EzPublishRestBundle/Tests/Functional" SYMFONY_CMD="ez:behat:create-language 'pol-PL' 'Polish (polski)'" - - TEST_CMD="bin/behat -vv --profile=platformui --tags='@common'" COMPOSE_FILE="doc/docker/base-dev.yml:doc/docker/redis.yml:doc/docker/selenium.yml" + - TEST_CMD="bin/behat -v --profile=repository-forms --tags=~@broken" COMPOSE_FILE="doc/docker/base-dev.yml:doc/docker/redis.yml:doc/docker/selenium.yml" + - TEST_CMD="bin/behat -v --profile=behat --tags=~@broken" # test only master (+ Pull requests) branches: @@ -34,16 +37,16 @@ before_install: ./bin/.travis/trusty/update_docker.sh before_script: # Internal auth token dedicated to testing with travis+composer on ezsystems repos, not for reuse! - echo "{\"github-oauth\":{\"github.com\":\"d0285ed5c8644f30547572ead2ed897431c1fc09\"}}" > auth.json - # In case of dev mode we'll need to install composer packages first - - docker-compose -f doc/docker/install.yml up --abort-on-container-exit - # Run (start containers and execute install command) - - docker-compose up -d + # Setup eZ Platform inside docker container + - /bin/bash ./bin/.travis/trusty/setup_ezplatform.sh "${COMPOSE_FILE}" + # Execute Symfony command if injected into test matrix + - if [ "${SYMFONY_CMD}" != "" ] ; then docker-compose exec --user www-data app sh -c "bin/console ${SYMFONY_CMD}" ; fi #- docker ps #- docker-compose logs # Execute test command, need to use sh to get right exit code (docker/compose/issues/3379) # Behat will use behat.yml which is a copy of behat.yml.dist with hostnames update by doc/docker/selenium.yml -script: docker-compose exec --user www-data app sh -c "php /scripts/wait_for_db.php; php $TEST_CMD" +script: docker-compose exec --user www-data app sh -c "php $TEST_CMD" after_failure: # Will show us the last bit of the log of container's main processes diff --git a/Dockerfile b/Dockerfile index 9bff30112e..2e083599ad 100644 --- a/Dockerfile +++ b/Dockerfile @@ -17,7 +17,8 @@ RUN composer dump-autoload --optimize # Next, remove everything we don't want to be copied to next build stage # Clear cache again so env variables are taken into account on startup -RUN rm -Rf app/logs/* app/cache/*/* +RUN rm -Rf var/logs/* var/cache/*/* + # Looks like we need to keep web/bundles ( like web/bundles/ezstudioui/js/views/ezs-landingpageview.js ) or else # urls like http://localhost:8080/_ezcombo?/bundles/ezstudioui/js/views/ezs-landingpageview.js&/tpl/handlebars/studiolandingpageconfigview-ez-template.js&/bundles/ezstudioui/js/views/ezs-landingpageconfigview.js&/tpl/handlebars/studiolayoutselectorview-ez-template.js&/bundles/ezstudioui/js/views/ezs-layoutselectorview.js&/tpl/handlebars/studiolandingpageconfigpopupformview-ez-template.js&/bundles/ezstudioui/js/views/forms/ezs-landingpageconfigpopupformview.js&/tpl/handlebars/landingpagecreatorview-ez-template.js&/bundles/ezsystemsformbuilder/js/models/fb-formfield-model.js&/bundles/ezsystemsformbuilder/js/lists/fb-formfields-modellist.js&/bundles/ezsystemsformbuilder/js/models/fb-formpage-model.js&/bundles/ezsystemsformbuilder/js/lists/fb-formpages-modellist.js&/bundles/ezsystemsformbuilder/js/models/fb-form-model.js&/tpl/handlebars/fbbasetabview-ez-template.js&/bundles/ezsystemsformbuilder/js/tabs/fb-base-tabview.js&/tpl/handlebars/fbpanelview-ez-template.js&/bundles/ezsystemsformbuilder/js/panels/fb-panelview.js # will not work when loading http://localhost:8080/ez @@ -34,6 +35,6 @@ ENV SYMFONY_ENV=prod COPY --from=builder /var/www /var/www # Fix permissions for www-data -RUN chown -R www-data:www-data app/cache app/logs \ - && find app/cache app/logs -type d -print0 | xargs -0 chmod -R 775 \ - && find app/cache app/logs -type f -print0 | xargs -0 chmod -R 664 +RUN chown -R www-data:www-data var web/var \ + && find var web/var -type d -print0 | xargs -0 chmod -R 775 \ + && find var web/var -type f -print0 | xargs -0 chmod -R 664 diff --git a/app/.htaccess b/app/.htaccess new file mode 100644 index 0000000000..fb1de45bdb --- /dev/null +++ b/app/.htaccess @@ -0,0 +1,7 @@ + + Require all denied + + + Order deny,allow + Deny from all + diff --git a/app/AppKernel.php b/app/AppKernel.php index 007ec741c9..d9706cbf80 100644 --- a/app/AppKernel.php +++ b/app/AppKernel.php @@ -5,16 +5,10 @@ class AppKernel extends Kernel { - /** - * Returns an array of bundles to registers. - * - * @return array an array of bundle instances - * - * @api - */ public function registerBundles() { - $bundles = array( + $bundles = [ + // Symfony new Symfony\Bundle\FrameworkBundle\FrameworkBundle(), new Symfony\Bundle\SecurityBundle\SecurityBundle(), new Symfony\Bundle\TwigBundle\TwigBundle(), @@ -23,58 +17,76 @@ public function registerBundles() new Symfony\Bundle\AsseticBundle\AsseticBundle(), new Doctrine\Bundle\DoctrineBundle\DoctrineBundle(), new Sensio\Bundle\FrameworkExtraBundle\SensioFrameworkExtraBundle(), - new Tedivm\StashBundle\TedivmStashBundle(), + // Dependencies new Hautelook\TemplatedUriBundle\HautelookTemplatedUriBundle(), new Liip\ImagineBundle\LiipImagineBundle(), new FOS\HttpCacheBundle\FOSHttpCacheBundle(), + new Nelmio\CorsBundle\NelmioCorsBundle(), + new Oneup\FlysystemBundle\OneupFlysystemBundle(), + new JMS\TranslationBundle\JMSTranslationBundle(), + new Knp\Bundle\MenuBundle\KnpMenuBundle(), + new Bazinga\Bundle\JsTranslationBundle\BazingaJsTranslationBundle(), + new FOS\JsRoutingBundle\FOSJsRoutingBundle(), + new WhiteOctober\PagerfantaBundle\WhiteOctoberPagerfantaBundle(), + // eZ Systems new EzSystems\PlatformHttpCacheBundle\EzSystemsPlatformHttpCacheBundle(), new eZ\Bundle\EzPublishCoreBundle\EzPublishCoreBundle(), new eZ\Bundle\EzPublishLegacySearchEngineBundle\EzPublishLegacySearchEngineBundle(), new eZ\Bundle\EzPublishIOBundle\EzPublishIOBundle(), - new EzSystems\MultiFileUploadBundle\EzSystemsMultiFileUploadBundle(), new eZ\Bundle\EzPublishRestBundle\EzPublishRestBundle(), - new EzSystems\PlatformUIAssetsBundle\EzSystemsPlatformUIAssetsBundle(), - new EzSystems\PlatformUIBundle\EzSystemsPlatformUIBundle(), new EzSystems\EzSupportToolsBundle\EzSystemsEzSupportToolsBundle(), - new Nelmio\CorsBundle\NelmioCorsBundle(), - new WhiteOctober\PagerfantaBundle\WhiteOctoberPagerfantaBundle(), - new Oneup\FlysystemBundle\OneupFlysystemBundle(), new EzSystems\PlatformInstallerBundle\EzSystemsPlatformInstallerBundle(), new EzSystems\RepositoryFormsBundle\EzSystemsRepositoryFormsBundle(), new EzSystems\EzPlatformSolrSearchEngineBundle\EzSystemsEzPlatformSolrSearchEngineBundle(), - new EzSystems\EzContentOnTheFlyBundle\EzSystemsEzContentOnTheFlyBundle(), new EzSystems\EzPlatformDesignEngineBundle\EzPlatformDesignEngineBundle(), - new Bazinga\Bundle\JsTranslationBundle\BazingaJsTranslationBundle(), - new JMS\TranslationBundle\JMSTranslationBundle(), + new EzSystems\EzPlatformAdminUiBundle\EzPlatformAdminUiBundle(), + new EzSystems\EzPlatformAdminUiModulesBundle\EzPlatformAdminUiModulesBundle(), + new EzSystems\EzPlatformAdminUiAssetsBundle\EzPlatformAdminUiAssetsBundle(), + // Application new AppBundle\AppBundle(), - ); + ]; switch ($this->getEnvironment()) { case 'test': case 'behat': $bundles[] = new EzSystems\BehatBundle\EzSystemsBehatBundle(); $bundles[] = new EzSystems\PlatformBehatBundle\EzPlatformBehatBundle(); - // No break, test also needs dev bundles + // No break, test also needs dev bundles case 'dev': $bundles[] = new eZ\Bundle\EzPublishDebugBundle\EzPublishDebugBundle(); $bundles[] = new Symfony\Bundle\DebugBundle\DebugBundle(); $bundles[] = new Symfony\Bundle\WebProfilerBundle\WebProfilerBundle(); + $bundles[] = new Symfony\Bundle\WebServerBundle\WebServerBundle(); $bundles[] = new Sensio\Bundle\DistributionBundle\SensioDistributionBundle(); $bundles[] = new Sensio\Bundle\GeneratorBundle\SensioGeneratorBundle(); - $bundles[] = new Egulias\ListenersDebugCommandBundle\EguliasListenersDebugCommandBundle(); } return $bundles; } - /** - * Loads the container configuration. - * - * @param LoaderInterface $loader A LoaderInterface instance - * @throws \RuntimeException when config file is not readable - * - * @api - */ + public function getRootDir() + { + return __DIR__; + } + + public function getCacheDir() + { + if (!empty($_SERVER['SYMFONY_TMP_DIR'])) { + return dirname($_SERVER['SYMFONY_TMP_DIR']) . '/var/cache/' . $this->getEnvironment(); + } + + return dirname(__DIR__) . '/var/cache/' . $this->getEnvironment(); + } + + public function getLogDir() + { + if (!empty($_SERVER['SYMFONY_TMP_DIR'])) { + return dirname($_SERVER['SYMFONY_TMP_DIR']) . '/var/logs'; + } + + return dirname(__DIR__) . '/var/logs'; + } + public function registerContainerConfiguration(LoaderInterface $loader) { $loader->load($this->getRootDir() . '/config/config_' . $this->getEnvironment() . '.yml'); diff --git a/app/cache/.keep b/app/Resources/views/.gitkeep similarity index 100% rename from app/cache/.keep rename to app/Resources/views/.gitkeep diff --git a/app/autoload.php b/app/autoload.php deleted file mode 100644 index 79137cbb30..0000000000 --- a/app/autoload.php +++ /dev/null @@ -1,20 +0,0 @@ -setParameter('secret', $value); -} - -// Mailer settings -if ($value = getenv('MAILER_TRANSPORT')) { - $container->setParameter('mailer_transport', $value); -} - -if ($value = getenv('MAILER_HOST')) { - $container->setParameter('mailer_host', $value); -} - -if ($value = getenv('MAILER_USER')) { - $container->setParameter('mailer_user', $value); -} - -if ($value = getenv('MAILER_PASSWORD')) { - $container->setParameter('mailer_password', $value); -} - -// Database settings -if ($value = getenv('DATABASE_DRIVER')) { - $container->setParameter('database_driver', $value); -} - -if ($value = getenv('DATABASE_HOST')) { - $container->setParameter('database_host', $value); -} - -if ($value = getenv('DATABASE_PORT')) { - $container->setParameter('database_port', $value); -} - -if ($value = getenv('DATABASE_NAME')) { - $container->setParameter('database_name', $value); -} - -if ($value = getenv('DATABASE_USER')) { - $container->setParameter('database_user', $value); -} - -if ($value = getenv('DATABASE_PASSWORD')) { - $container->setParameter('database_password', $value); -} - -// Search Engine settings -if ($value = getenv('SEARCH_ENGINE')) { - $container->setParameter('search_engine', $value); -} - -if ($value = getenv('SOLR_DSN')) { - $container->setParameter('solr_dsn', $value); -} - -// Logging settings -if ($value = getenv('LOG_TYPE')) { - $container->setParameter('log_type', $value); -} - -if ($value = getenv('LOG_PATH')) { - $container->setParameter('log_path', $value); -} - // Cache settings -// Config validation by Stash prohbitis us from pre defining pools using drivers not supported by all systems -// So we expose a env variable to load and use other pools when needed, additional pools can be added in cache_pool/ folder. -if ($pool = getenv('CUSTOM_CACHE_POOL')) { - $container->setParameter('cache_pool', $pool); - - if ($host = getenv('CACHE_HOST')) { - $container->setParameter('cache_host', $host); - } - - // Optional port settings in case not default - if ($host = getenv('CACHE_MEMCACHED_PORT')) { - $container->setParameter('cache_memcached_port', $host); - } elseif ($host = getenv('CACHE_REDIS_PORT')) { - $container->setParameter('cache_redis_port', $host); - } - +// If CACHE_POOL env variable is set, check if there is a yml file that needs to be loaded for it +if (($pool = getenv('CACHE_POOL')) && file_exists(__DIR__ . "/../cache_pool/${pool}.yml")) { $loader = new Loader\YamlFileLoader($container, new FileLocator(__DIR__ . '/../cache_pool')); $loader->load($pool . '.yml'); } -// HttpCache setting (for configuring http cache purging) +// Params that needs to be set at compile time and thus can't use Symfony's env() if ($purgeType = getenv('HTTPCACHE_PURGE_TYPE')) { $container->setParameter('purge_type', $purgeType); } -if ($purgeServer = getenv('HTTPCACHE_PURGE_SERVER')) { - // BC : In earlier versions, purge_type was set automatically if purge_server was set - if ($purgeType === false) { - $container->setParameter('purge_type', 'http'); - } - $container->setParameter('purge_server', $purgeServer); +if ($value = getenv('MAILER_TRANSPORT')) { + $container->setParameter('mailer_transport', $value); } -if ($value = getenv('HTTPCACHE_DEFAULT_TTL')) { - $container->setParameter('httpcache_default_ttl', $value); +if ($value = getenv('LOG_TYPE')) { + $container->setParameter('log_type', $value); } // EzSystemsRecommendationsBundle settings +// @todo Move to use env() and params if ($value = getenv('RECOMMENDATIONS_CUSTOMER_ID')) { $container->setParameter('ez_recommendation.default.yoochoose.customer_id', $value); } diff --git a/app/config/ezplatform.yml b/app/config/ezplatform.yml index eeaefd3366..aecd4ce5b1 100644 --- a/app/config/ezplatform.yml +++ b/app/config/ezplatform.yml @@ -13,9 +13,14 @@ ezpublish: # Siteaccess configuration, with one siteaccess per default siteaccess: - list: [site] + list: [site, admin] groups: site_group: [site] + + # WARNING: Do not remove or rename this group. + # It's used to distinguish common siteaccesses from admin ones. + # In case of multisite with multiple admin panels, remember to add any additional admin siteaccess to this group. + admin_group: [admin] default_siteaccess: site match: URIElement: 1 @@ -23,8 +28,8 @@ ezpublish: # System settings, grouped by siteaccess and/or siteaccess group system: site_group: - # Pool to use for cache, needs to be different per repository (database). - cache_pool_name: '%cache_pool%' + # Cache pool service, needs to be different per repository (database) on multi repository install. + cache_service_name: '%cache_pool%' # These reflect the current installers, complete installation before you change them. For changing var_dir # it is recommended to install clean, then change setting before you start adding binary content, otherwise you'll # need to manually modify your database data to reflect this to avoid exceptions. @@ -40,3 +45,18 @@ ezpublish: # HttpCache purge server(s) setting, eg Varnish, for when ezpublish.http_cache.purge_type is set to 'http'. http_cache: purge_servers: ['%purge_server%'] + # Temporary hard coding session name during v2 development + session: + name: eZSESSID + + # WARNING: Do not remove or rename this group. + admin_group: + cache_service_name: '%cache_pool%' + var_dir: var/site + languages: [eng-GB] + content: + default_ttl: '%httpcache_default_ttl%' + http_cache: + purge_servers: ['%purge_server%'] + session: + name: eZSESSID diff --git a/app/config/ezplatform_test.yml b/app/config/ezplatform_test.yml new file mode 100644 index 0000000000..967ac2e915 --- /dev/null +++ b/app/config/ezplatform_test.yml @@ -0,0 +1,2 @@ +imports: + - { resource: ezplatform.yml } diff --git a/app/config/parameters.yml.dist b/app/config/parameters.yml.dist index 0ff4cba476..08fc5a6253 100644 --- a/app/config/parameters.yml.dist +++ b/app/config/parameters.yml.dist @@ -1,13 +1,13 @@ # This file is a "template" of what your parameters.yml file should look like parameters: # A secret key that's used to generate certain security-related tokens - secret: ThisEzPlatformTokenIsNotSoSecretChangeIt + env(SYMFONY_SECRET): ThisEzPlatformTokenIsNotSoSecretChangeIt # Settings for database backend used by Doctrine DBAL - # In turn used for Content Repository Persistence, and default database powered search engine - database_driver: pdo_mysql - database_host: localhost - database_port: ~ - database_name: ezplatform - database_user: root - database_password: + # In turn used for default storage engine & default search engine (if legacy is configured as search engine) + env(DATABASE_DRIVER): pdo_mysql + env(DATABASE_HOST): localhost + env(DATABASE_PORT): ~ + env(DATABASE_NAME): ezplatform + env(DATABASE_USER): root + env(DATABASE_PASSWORD): diff --git a/app/config/routing.yml b/app/config/routing.yml index 1dce3661eb..fddb4a66bc 100644 --- a/app/config/routing.yml +++ b/app/config/routing.yml @@ -8,32 +8,20 @@ login_check: logout: path: /logout -_ezpublishRoutes: +kernel.internal: resource: '@EzPublishCoreBundle/Resources/config/routing/internal.yml' -_ezpublishRestRoutes: +kernel.rest: resource: '@EzPublishRestBundle/Resources/config/routing.yml' - prefix: '%ezpublish_rest.path_prefix%' + prefix: /api/ezp/v2 -_ezpublishRestOptionsRoutes: - resource: '@EzPublishRestBundle/Resources/config/routing.yml' - prefix: '%ezpublish_rest.path_prefix%' - type: rest_options - -_liip_imagine: - resource: '@LiipImagineBundle/Resources/config/routing.xml' - -_ezpublishPlatformUIRoutes: - resource: '@eZPlatformUIBundle/Resources/config/routing.yml' +ezplatform.admin_ui: + resource: '@EzPlatformAdminUiBundle/Resources/config/routing.yml' + defaults: + siteaccess_group_whitelist: '%admin_group_name%' _ezplatformRepositoryFormsRoutes: resource: '@EzSystemsRepositoryFormsBundle/Resources/config/routing.yml' -_contentOnTheFly: - resource: '@ContentOnTheFlyBundle/Resources/config/routing.yml' - prefix: '%ezpublish_rest.path_prefix%' - -_multiFileUpload: - resource: '@EzSystemsMultiFileUploadBundle/Resources/config/routing.yml' - prefix: '%ezpublish_rest.path_prefix%' - +fos.js_routing: + resource: '@FOSJsRoutingBundle/Resources/config/routing/routing.xml' diff --git a/app/config/security.yml b/app/config/security.yml index 8f194241e4..429af06723 100644 --- a/app/config/security.yml +++ b/app/config/security.yml @@ -14,15 +14,6 @@ security: pattern: ^/(_(profiler|wdt)|css|images|js)/ security: false - ## WARNING - ## Until https://jira.ez.no/browse/EZP-22192 is implemented, - ## enabling basic auth in REST will prevent PlatformUI from working -# ezpublish_rest: -# pattern: ^/api/ezp/v2 -# stateless: true -# ezpublish_http_basic: -# realm: eZ Publish REST API - ezpublish_front: pattern: ^/ anonymous: ~ @@ -31,5 +22,12 @@ security: require_previous_session: false logout: ~ - default: + main: anonymous: ~ + # activate different ways to authenticate + + # https://symfony.com/doc/current/security.html#a-configuring-how-your-users-will-authenticate + #http_basic: ~ + + # https://symfony.com/doc/current/security/form_login_setup.html + #form_login: ~ diff --git a/app/config/services.yml b/app/config/services.yml new file mode 100644 index 0000000000..63dc7a1580 --- /dev/null +++ b/app/config/services.yml @@ -0,0 +1,15 @@ +# Learn more about services, parameters and containers at +# https://symfony.com/doc/current/service_container.html +parameters: + #parameter_name: value + +services: + # default configuration for services in *this* file + _defaults: + # automatically injects dependencies in your services + autowire: true + # automatically registers your services as commands, event subscribers, etc. + autoconfigure: true + # this means you cannot fetch services directly from the container via $container->get() + # if you need to do this, you can override this setting on individual services + public: false diff --git a/app/phpunit.xml.dist b/app/phpunit.xml.dist deleted file mode 100644 index 5549ae627c..0000000000 --- a/app/phpunit.xml.dist +++ /dev/null @@ -1,38 +0,0 @@ - - - - - - - - - - ../src/*/*Bundle/Tests - ../src/*/Bundle/*Bundle/Tests - ../src/*Bundle/Tests - - - - - - - - ../src - - ../src/*/*Bundle/Resources - ../src/*/*Bundle/Tests - ../src/*/Bundle/*Bundle/Resources - ../src/*/Bundle/*Bundle/Tests - - - - diff --git a/behat.yml.dist b/behat.yml.dist index a8a65961a3..4f237beaac 100644 --- a/behat.yml.dist +++ b/behat.yml.dist @@ -1,4 +1,3 @@ -# This file contains the default configuration for behat testing using EzSystems/BehatBundle default: calls: error_reporting: -1 # Report all PHP errors @@ -19,24 +18,19 @@ default: Behat\Symfony2Extension: kernel: - bootstrap: app/autoload.php + bootstrap: vendor/autoload.php path: app/AppKernel.php class: AppKernel env: behat debug: false - jarnaiz\JUnitFormatter\JUnitFormatterExtension: - filename: report.xml - outputDir: %paths.base%/app/logs/junit - EzSystems\PlatformBehatBundle\ServiceContainer\EzBehatExtension: ~ - # default profile: no suites suites: ~ imports: - vendor/ezsystems/ezpublish-kernel/eZ/Bundle/EzPublishCoreBundle/behat_suites.yml - vendor/ezsystems/ezpublish-kernel/eZ/Bundle/EzPublishRestBundle/behat_suites.yml - - vendor/ezsystems/behatbundle/EzSystems/BehatBundle/behat_suites.yml - - vendor/ezsystems/platform-ui-bundle/behat_suites.yml - vendor/ezsystems/repository-forms/behat_suites.yml + - vendor/ezsystems/ezplatform-admin-ui/behat_suites.yml + - vendor/ezsystems/behatbundle/EzSystems/BehatBundle/behat_suites.yml diff --git a/bin/.travis/parameters.yml b/bin/.travis/parameters.yml index 67ecd0bb76..b047a671b1 100644 --- a/bin/.travis/parameters.yml +++ b/bin/.travis/parameters.yml @@ -1,5 +1,5 @@ # Only settings different then parameters.yml.dist, buildParameters will inject those we don't define from there! parameters: - database_name: behattestdb - database_user: ezp - database_password: ezp + env(DATABASE_NAME): behattestdb + env(DATABASE_USER): ezp + env(DATABASE_PASSWORD): ezp diff --git a/bin/.travis/trusty/setup_ezplatform.sh b/bin/.travis/trusty/setup_ezplatform.sh new file mode 100755 index 0000000000..1ed53517d7 --- /dev/null +++ b/bin/.travis/trusty/setup_ezplatform.sh @@ -0,0 +1,82 @@ +#!/bin/bash + +# This script provides setup steps needed to build eZ Platform docker containers ready to execute +# functional and acceptance (behat) tests. +# +# Example usage: +# $ ./bin/.travis/trusty/setup_ezplatform.sh "${COMPOSE_FILE}" "${INSTALL_TYPE}" ["${DEPENDENCY_PACKAGE_DIR}"] +# +# Arguments: +# - ${COMPOSE_FILE} compose file(s) paths +# - ${INSTALL_TYPE} optional, eZ Platform install type ("clean") will take from .env if not set +# - ${DEPENDENCY_PACKAGE_DIR} optional, directory containing existing eZ Platform dependency package + +# Determine eZ Platform Build dir as relative to current script path +EZPLATFORM_BUILD_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )/../../.." && pwd )" + +# Source .env first to make sure we don't override any variables +. ${EZPLATFORM_BUILD_DIR}/.env + +DEPENDENCY_PACKAGE_DIR=$3 + +if [[ -z "${1}" ]]; then + COMPOSE_FILE=$COMPOSE_FILE +else + COMPOSE_FILE=$1 +fi + +if [[ -z "${2}" ]]; then + INSTALL_TYPE=$INSTALL_EZ_INSTALL_TYPE +else + INSTALL_TYPE=$2 +fi + +if [[ -n "${DEPENDENCY_PACKAGE_DIR}" ]]; then + # Get details about dependency package + DEPENDENCY_PACKAGE_NAME=`php -r "echo json_decode(file_get_contents('${DEPENDENCY_PACKAGE_DIR}/composer.json'))->name;"` + + if [[ -z "${DEPENDENCY_PACKAGE_NAME}" ]]; then + echo 'Missing composer package name of tested dependency' >&2 + exit 2 + fi +fi + +echo '> Preparing eZ Platform container using the following setup:' +echo "- EZPLATFORM_BUILD_DIR=${EZPLATFORM_BUILD_DIR}" +echo "- COMPOSE_FILE=${COMPOSE_FILE}" +if [[ -n "${DEPENDENCY_PACKAGE_NAME}" ]]; then + echo "- DEPENDENCY_PACKAGE_NAME=${DEPENDENCY_PACKAGE_NAME}" +fi + +echo '> Remove XDebug PHP extension' +phpenv config-rm xdebug.ini + +echo "> Start docker containers specified by ${COMPOSE_FILE}" +docker-compose up -d +docker-compose exec app sh -c 'chown -R www-data:www-data /var/www' + +echo '> Run composer install inside docker app container' +docker-compose exec --user www-data app sh -c 'COMPOSER_HOME=$HOME/.composer composer install --no-suggest --no-progress --no-interaction --prefer-dist --optimize-autoloader' + +# Handle dependency if needed +if [[ -n "${DEPENDENCY_PACKAGE_NAME}" ]]; then + # check if dependency exists for current meta-package version + if [[ ! -d "./vendor/${DEPENDENCY_PACKAGE_NAME}" ]]; then + echo "Testing dependency failed: package ${DEPENDENCY_PACKAGE_NAME} does not exist" >&2 + exit 3 + fi + + echo "> Overwrite ./vendor/${DEPENDENCY_PACKAGE_NAME} with ${DEPENDENCY_PACKAGE_DIR}" + if ! (sudo rm -rf "./vendor/${DEPENDENCY_PACKAGE_NAME}" && sudo mv ${DEPENDENCY_PACKAGE_DIR} "./vendor/${DEPENDENCY_PACKAGE_NAME}"); then + echo 'Overwrite failed' >&2 + exit 4 + fi + + echo '> Clear Symfony cache inside docker app container' + docker-compose exec --user www-data app sh -c 'php ./bin/console cache:clear --no-warmup && php ./bin/console cache:warmup' +fi + +echo '> Install data' +docker-compose exec --user www-data app sh -c "php /scripts/wait_for_db.php; php bin/console ezplatform:install ${INSTALL_TYPE}" + +echo '> Done, ready to run tests' diff --git a/bin/.travis/trusty/setup_from_external_repo.sh b/bin/.travis/trusty/setup_from_external_repo.sh index 86d0df97e1..280f95236f 100755 --- a/bin/.travis/trusty/setup_from_external_repo.sh +++ b/bin/.travis/trusty/setup_from_external_repo.sh @@ -1,5 +1,7 @@ #!/bin/bash +# @deprecated since 2.0, use ./bin/.travis/trusty/setup_ezplatform.sh +# # This script is meant to be reused from other repos that needs to run behat tests. # # It assumes you have already checked pout ezplatform (to get access to this script) and @@ -21,6 +23,8 @@ # # script: docker-compose run -u www-data --rm behatphpcli bin/behat --profile=rest --suite=fullJson --tags=~@broken +echo 'The script setup_from_external_repo is deprecated. Use ./bin/.travis/trusty/setup_ezplatform.sh instead.' >&2 + REPO_DIR=$1 COMPOSER_REQUIRE=${@:2} @@ -60,10 +64,10 @@ if [ "$RUN_INSTALL" = "1" ] ; then echo "> Run composer install" composer install --no-progress --no-interaction --prefer-dist --optimize-autoloader mkdir -p web/var - rm -Rf app/logs/* app/cache/*/* - sudo chown -R www-data:www-data app/cache app/logs web/var - find app/cache app/logs web/var -type d | xargs chmod -R 775 - find app/cache app/logs web/var -type f | xargs chmod -R 664 + rm -Rf var/logs/* var/cache/*/* + sudo chown -R www-data:www-data var/cache var/logs web/var + find var/cache var/logs web/var -type d | xargs chmod -R 775 + find var/cache var/logs web/var -type f | xargs chmod -R 664 # Do NOT use this for your prod setup, this is done like this for behat sudo chown -R www-data:www-data app/config src #docker-compose -f doc/docker/install.yml up --abort-on-container-exit @@ -73,6 +77,6 @@ INSTALL_EZ_INSTALL_TYPE=${INSTALL_EZ_INSTALL_TYPE:-clean} echo "> Start containers and install data" docker-compose up -d -docker-compose exec --user www-data app sh -c "php /scripts/wait_for_db.php; php app/console ezplatform:install $INSTALL_EZ_INSTALL_TYPE" +docker-compose exec --user www-data app sh -c "php /scripts/wait_for_db.php; php bin/console ezplatform:install $INSTALL_EZ_INSTALL_TYPE" echo "> Done, ready to run behatphpcli container" diff --git a/app/console b/bin/console similarity index 58% rename from app/console rename to bin/console index 58b61953f0..5af600e5c1 100755 --- a/app/console +++ b/bin/console @@ -1,8 +1,13 @@ #!/usr/bin/env php getParameterOption(array('--env', '-e'), getenv('SYMFONY_ENV') ?: 'dev'); -$debug = getenv('SYMFONY_DEBUG') !== '0' && !$input->hasParameterOption(array('--no-debug', '')) && $env !== 'prod'; +$env = $input->getParameterOption(['--env', '-e'], getenv('SYMFONY_ENV') ?: 'dev'); +$debug = getenv('SYMFONY_DEBUG') !== '0' && !$input->hasParameterOption(['--no-debug', '']) && $env !== 'prod'; + if ($debug) { Debug::enable(); } diff --git a/bin/symfony_requirements b/bin/symfony_requirements new file mode 100755 index 0000000000..a7bf65a1b8 --- /dev/null +++ b/bin/symfony_requirements @@ -0,0 +1,146 @@ +#!/usr/bin/env php +getPhpIniConfigPath(); + +echo_title('Symfony Requirements Checker'); + +echo '> PHP is using the following php.ini file:'.PHP_EOL; +if ($iniPath) { + echo_style('green', ' '.$iniPath); +} else { + echo_style('yellow', ' WARNING: No configuration file (php.ini) used by PHP!'); +} + +echo PHP_EOL.PHP_EOL; + +echo '> Checking Symfony requirements:'.PHP_EOL.' '; + +$messages = array(); +foreach ($symfonyRequirements->getRequirements() as $req) { + if ($helpText = get_error_message($req, $lineSize)) { + echo_style('red', 'E'); + $messages['error'][] = $helpText; + } else { + echo_style('green', '.'); + } +} + +$checkPassed = empty($messages['error']); + +foreach ($symfonyRequirements->getRecommendations() as $req) { + if ($helpText = get_error_message($req, $lineSize)) { + echo_style('yellow', 'W'); + $messages['warning'][] = $helpText; + } else { + echo_style('green', '.'); + } +} + +if ($checkPassed) { + echo_block('success', 'OK', 'Your system is ready to run Symfony projects'); +} else { + echo_block('error', 'ERROR', 'Your system is not ready to run Symfony projects'); + + echo_title('Fix the following mandatory requirements', 'red'); + + foreach ($messages['error'] as $helpText) { + echo ' * '.$helpText.PHP_EOL; + } +} + +if (!empty($messages['warning'])) { + echo_title('Optional recommendations to improve your setup', 'yellow'); + + foreach ($messages['warning'] as $helpText) { + echo ' * '.$helpText.PHP_EOL; + } +} + +echo PHP_EOL; +echo_style('title', 'Note'); +echo ' The command console could use a different php.ini file'.PHP_EOL; +echo_style('title', '~~~~'); +echo ' than the one used with your web server. To be on the'.PHP_EOL; +echo ' safe side, please check the requirements from your web'.PHP_EOL; +echo ' server using the '; +echo_style('yellow', 'web/config.php'); +echo ' script.'.PHP_EOL; +echo PHP_EOL; + +exit($checkPassed ? 0 : 1); + +function get_error_message(Requirement $requirement, $lineSize) +{ + if ($requirement->isFulfilled()) { + return; + } + + $errorMessage = wordwrap($requirement->getTestMessage(), $lineSize - 3, PHP_EOL.' ').PHP_EOL; + $errorMessage .= ' > '.wordwrap($requirement->getHelpText(), $lineSize - 5, PHP_EOL.' > ').PHP_EOL; + + return $errorMessage; +} + +function echo_title($title, $style = null) +{ + $style = $style ?: 'title'; + + echo PHP_EOL; + echo_style($style, $title.PHP_EOL); + echo_style($style, str_repeat('~', strlen($title)).PHP_EOL); + echo PHP_EOL; +} + +function echo_style($style, $message) +{ + // ANSI color codes + $styles = array( + 'reset' => "\033[0m", + 'red' => "\033[31m", + 'green' => "\033[32m", + 'yellow' => "\033[33m", + 'error' => "\033[37;41m", + 'success' => "\033[37;42m", + 'title' => "\033[34m", + ); + $supports = has_color_support(); + + echo($supports ? $styles[$style] : '').$message.($supports ? $styles['reset'] : ''); +} + +function echo_block($style, $title, $message) +{ + $message = ' '.trim($message).' '; + $width = strlen($message); + + echo PHP_EOL.PHP_EOL; + + echo_style($style, str_repeat(' ', $width)); + echo PHP_EOL; + echo_style($style, str_pad(' ['.$title.']', $width, ' ', STR_PAD_RIGHT)); + echo PHP_EOL; + echo_style($style, $message); + echo PHP_EOL; + echo_style($style, str_repeat(' ', $width)); + echo PHP_EOL; +} + +function has_color_support() +{ + static $support; + + if (null === $support) { + if (DIRECTORY_SEPARATOR == '\\') { + $support = false !== getenv('ANSICON') || 'ON' === getenv('ConEmuANSI'); + } else { + $support = function_exists('posix_isatty') && @posix_isatty(STDOUT); + } + } + + return $support; +} diff --git a/composer.json b/composer.json index a9879201cf..127b4844ee 100644 --- a/composer.json +++ b/composer.json @@ -24,55 +24,53 @@ "files": [ "vendor/symfony/symfony/src/Symfony/Component/VarDumper/Resources/functions/dump.php" ] }, "require": { - "php": "~5.6|~7.0", - "symfony/symfony": "~2.8", - "twig/extensions": "~1.4", + "php": "^7.1", + "symfony/symfony": "3.4.0", + "twig/twig": "^1.0||^2.0", + "twig/extensions": "^1.5.0", "symfony/assetic-bundle": "~2.8", "symfony/swiftmailer-bundle": "~2.5", - "symfony/monolog-bundle": "~2.12|~3.0", - "sensio/distribution-bundle": "^3.0.36|^4.0.6|^5.0", - "sensio/generator-bundle": "^2.3|^3.0", + "symfony/monolog-bundle": "^3.1.0", + "doctrine/doctrine-bundle": "^1.6", + "doctrine/orm": "^2.5", + "sensio/distribution-bundle": "^5.0.19", "incenteev/composer-parameter-handler": "~2.1", - "tedivm/stash-bundle": "~0.6", - "ezsystems/ezpublish-kernel": "^6.13@dev", - "ezsystems/repository-forms": "^1.10@dev", + "ezsystems/ezpublish-kernel": "^7.0@dev", + "ezsystems/repository-forms": "^2.0@dev", "ezsystems/ezplatform-solr-search-engine": "^1.5@dev", - "ezsystems/platform-ui-bundle": "^1.13@dev", - "ezsystems/ez-support-tools": "~0.1.3@dev", + "ezsystems/ez-support-tools": "^0.2@dev", "ezsystems/ezplatform-http-cache": "^0.4@dev", - "ezplatform-i18n/ezplatform-i18n-ach_ug": "^1.4@dev", - "ezsystems/ezplatform-multi-file-upload": "^0.1", + "ezsystems/ezplatform-admin-ui": "^1.0@dev", + "ezsystems/ezplatform-admin-ui-modules": "^1.0@dev", + "ezsystems/ezplatform-admin-ui-assets": "^0.4", "ezsystems/ezplatform-design-engine": "^1.1", - "egulias/listeners-debug-command-bundle": "~1.9", - "white-october/pagerfanta-bundle": "1.0.*", - "hautelook/templated-uri-bundle": "~1.0 | ~2.0", - "doctrine/doctrine-bundle": "~1.5", - "sensio/framework-extra-bundle": "~3.0", - "ezsystems/content-on-the-fly-prototype": "~0.1.11", + "knplabs/knp-menu-bundle": "^2.1", + "sensio/framework-extra-bundle": "^3.0.2", "willdurand/js-translation-bundle": "^2.6.4", - "roave/security-advisories": "dev-master" + "oneup/flysystem-bundle": "^2.0", + "friendsofsymfony/jsrouting-bundle": "^1.4", + "white-october/pagerfanta-bundle": "^1.1", + "roave/security-advisories": "dev-master", + "leafo/scssphp": "^0.7" }, "require-dev": { - "ezsystems/ezplatform-i18n": "^1.4@dev", "behat/behat": "~3.2", "behat/symfony2-extension": "~2.0", "behat/mink-extension": "~2.0", "behat/mink-goutte-driver": "~1.0", "behat/mink-selenium2-driver": "~1.0", - "jarnaiz/behat-junit-formatter": "^1.3", - "ezsystems/behatbundle": "^6.3" - }, - "suggest": { - "ezsystems/legacy-bridge": "Provides the full legacy backoffice and legacy features" + "ezsystems/behatbundle": "^6.5", + "phpunit/phpunit": "^6.4", + "sensio/generator-bundle": "~3.1", + "symfony/phpunit-bridge": "~3.2" }, "scripts": { "symfony-scripts": [ "Incenteev\\ParameterHandler\\ScriptHandler::buildParameters", - "Sensio\\Bundle\\DistributionBundle\\Composer\\ScriptHandler::buildBootstrap", "eZ\\Bundle\\EzPublishCoreBundle\\Composer\\ScriptHandler::clearCache", "Sensio\\Bundle\\DistributionBundle\\Composer\\ScriptHandler::installAssets", - "eZ\\Bundle\\EzPublishCoreBundle\\Composer\\ScriptHandler::dumpAssets", - "Sensio\\Bundle\\DistributionBundle\\Composer\\ScriptHandler::installRequirementsFile" + "Sensio\\Bundle\\DistributionBundle\\Composer\\ScriptHandler::installRequirementsFile", + "@php bin/console assetic:dump" ], "post-install-cmd": [ "@symfony-scripts" @@ -85,20 +83,22 @@ ] }, "config": { - "process-timeout": 3000, - "bin-dir": "bin" + "bin-dir": "bin", + "sort-packages": true }, "extra": { "symfony-app-dir": "app", + "symfony-bin-dir": "bin", + "symfony-var-dir": "var", "symfony-web-dir": "web", - "___symfony-assets-install": "One of 'symlink', 'relative' (symlinks) or 'hard'", + "symfony-tests-dir": "tests", "symfony-assets-install": "relative", "incenteev-parameters": { "keep-outdated": true, "file": "app/config/parameters.yml" }, "branch-alias": { - "dev-master": "1.13.x-dev" + "dev-master": "2.0.x-dev" } } } diff --git a/doc/apache2/vhost.template b/doc/apache2/vhost.template index 276eb2306c..49c473b809 100644 --- a/doc/apache2/vhost.template +++ b/doc/apache2/vhost.template @@ -72,11 +72,6 @@ # For FastCGI mode or when using PHP-FPM, to get basic auth working. RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}] - # Needed for ci testing, you can optionally remove this. - RewriteCond %{ENV:SYMFONY_ENV} "behat" - RewriteCond %{REQUEST_URI} ^/php5-fcgi(.*) - RewriteRule . - [L] - # Cluster/streamed files rewrite rules. Enable on cluster with DFS as a binary data handler #RewriteRule ^/var/([^/]+/)?storage/images(-versioned)?/.* /app.php [L] diff --git a/doc/docker/README.md b/doc/docker/README.md index 4664c6514c..530c3c6776 100644 --- a/doc/docker/README.md +++ b/doc/docker/README.md @@ -77,7 +77,7 @@ docker-compose build dataset-vardir dataset-dbdump docker-compose up -d --force-recreate ``` -After some 5-10 seconds you should be able to browse the site on `localhost:8080` and the backend on `localhost:8080/ez`. +After some 5-10 seconds you should be able to browse the site on `localhost:8080` and the backend on `localhost:8080/admin`. ### Development "mount" use @@ -100,7 +100,7 @@ docker-compose up -d --force-recreate ``` -After some 5-10 seconds you should be able to browse the site on `localhost:8080` and the backend on `localhost:8080/ez`. +After some 5-10 seconds you should be able to browse the site on `localhost:8080` and the backend on `localhost:8080/admin`. ### Behat and Selenium use diff --git a/doc/docker/install.yml b/doc/docker/install.yml index 7033570fb0..419ad3f848 100644 --- a/doc/docker/install.yml +++ b/doc/docker/install.yml @@ -34,12 +34,12 @@ services: composer install --no-progress --no-interaction --prefer-dist --no-suggest --optimize-autoloader; mkdir -p web/var; php /scripts/wait_for_db.php; - php app/console ezplatform:install ${INSTALL_EZ_INSTALL_TYPE}; - if [ \"$SYMFONY_CMD\" != '' ]; then echo '> Executing' \"$SYMFONY_CMD\"; php app/console $SYMFONY_CMD; fi; - rm -Rf app/logs/* app/cache/*/*; - chown -R www-data:www-data app/cache app/logs web/var; - find app/cache app/logs web/var -type d -print0 | xargs -0 chmod -R 775; - find app/cache app/logs web/var -type f -print0 | xargs -0 chmod -R 664; + php bin/console ezplatform:install ${INSTALL_EZ_INSTALL_TYPE}; + if [ \"$SYMFONY_CMD\" != '' ]; then echo '> Executing' \"$SYMFONY_CMD\"; php bin/console $SYMFONY_CMD; fi; + rm -Rf var/logs/* var/cache/*/*; + chown -R www-data:www-data var/cache var/logs web/var; + find var/cache var/logs web/var -type d -print0 | xargs -0 chmod -R 775; + find var/cache var/logs web/var -type f -print0 | xargs -0 chmod -R 664; chown -R www-data:www-data app/config src; echo 'Dumping database into doc/docker/entrypoint/mysql/2_dump.sql for use by mysql on startup.'; mysqldump -u $$DATABASE_USER --password=$$DATABASE_PASSWORD -h $$DATABASE_HOST --add-drop-table --extended-insert --protocol=tcp $$DATABASE_NAME > doc/docker/entrypoint/mysql/2_dump.sql" diff --git a/doc/docker/redis.yml b/doc/docker/redis.yml index 0daa26df94..1a0c59c0df 100644 --- a/doc/docker/redis.yml +++ b/doc/docker/redis.yml @@ -10,8 +10,8 @@ services: depends_on: - redis environment: - - CUSTOM_CACHE_POOL=singleredis - - CACHE_HOST=redis + - CACHE_POOL=cache.redis + - CACHE_DSN=redis:6379 redis: image: ${REDIS_IMAGE} diff --git a/doc/varnish/varnish.md b/doc/varnish/varnish.md index 628c47965e..264df7a7ed 100644 --- a/doc/varnish/varnish.md +++ b/doc/varnish/varnish.md @@ -10,8 +10,6 @@ Recommended VCL base files For Varnish to work properly with eZ, you'll need to use the following VCL as starting point: * [eZ Platform 1.7+ with Varnish 4.x/5.x with xkey VMOD](vcl/varnish4_xkey.vcl) -* [eZ 5.4+ / 2014.09+ with Varnish 4/5 using builtin BAN](vcl/varnish4_ban.vcl) _(Deprecated in favour of xkey version)_ -* [eZ 5.4+ / 2014.09+ with Varnish 3 using builtin BAN](vcl/varnish3_ban.vcl) _(Deprecated in favour of xkey version)_ > **Note:** Http cache management is done with the help of [FOSHttpCacheBundle](http://foshttpcachebundle.readthedocs.org/). diff --git a/doc/varnish/vcl/varnish3_ban.vcl b/doc/varnish/vcl/varnish3_ban.vcl deleted file mode 100644 index 0517ded56a..0000000000 --- a/doc/varnish/vcl/varnish3_ban.vcl +++ /dev/null @@ -1,209 +0,0 @@ -// Varnish 3 style - eZ 5.4+ / 2014.09+ -// Complete VCL example -// DEPRECATED: For faster, and over time more stable setup look to ezplatform-http-cache and Varnish xkey use. - -// For customizing your backend and acl rules see parameters.yml -include "parameters.vcl"; - -// Called at the beginning of a request, after the complete request has been received -sub vcl_recv { - - // Set the backend - set req.backend = ezplatform; - - // Advertise Symfony for ESI support - set req.http.Surrogate-Capability = "abc=ESI/1.0"; - - // Add a unique header containing the client address (only for master request) - // Please note that /_fragment URI can change in Symfony configuration - if (!req.url ~ "^/_fragment") { - if (req.http.x-forwarded-for) { - set req.http.X-Forwarded-For = req.http.X-Forwarded-For + ", " + client.ip; - } else { - set req.http.X-Forwarded-For = client.ip; - } - } - - // Trigger cache purge if needed - call ez_purge; - - // Don't cache requests other than GET and HEAD. - if (req.request != "GET" && req.request != "HEAD") { - return (pass); - } - - // Normalize the Accept-Encoding headers - if (req.http.Accept-Encoding) { - if (req.http.Accept-Encoding ~ "gzip") { - set req.http.Accept-Encoding = "gzip"; - } elsif (req.http.Accept-Encoding ~ "deflate") { - set req.http.Accept-Encoding = "deflate"; - } else { - unset req.http.Accept-Encoding; - } - } - - // Don't cache Authenticate & Authorization - // You may remove this when using REST API with basic auth. - if (req.http.Authenticate || req.http.Authorization) { - if (client.ip ~ debuggers) { - set req.http.X-Debug = "Not Cached according to configuration (Authorization)"; - } - return(pass); - } - - // Do a standard lookup on assets - // Note that file extension list below is not extensive, so consider completing it to fit your needs. - if (req.url ~ "\.(css|js|gif|jpe?g|bmp|png|tiff?|ico|img|tga|wmf|svg|swf|ico|mp3|mp4|m4a|ogg|mov|avi|wmv|zip|gz|pdf|ttf|eot|wof)$") { - return (lookup); - } - - // Retrieve client user hash and add it to the forwarded request. - call ez_user_hash; - - // If it passes all these tests, do a lookup anyway. - return (lookup); -} - -// Called when the requested object has been retrieved from the backend -sub vcl_fetch { - - if (req.restarts == 0 - && req.http.accept ~ "application/vnd.fos.user-context-hash" - && beresp.status >= 500 - ) { - error 503 "Hash error"; - } - - // Optimize to only parse the Response contents from Symfony - if (beresp.http.Surrogate-Control ~ "ESI/1.0") { - unset beresp.http.Surrogate-Control; - set beresp.do_esi = true; - } - - // Respect the Cache-Control=private header from the backend - if (beresp.http.Cache-Control ~ "no-cache|no-store|private") { - set beresp.ttl = 120s; - return (hit_for_pass); - } - - return (deliver); -} - -// Handle purge -// You may add FOSHttpCacheBundle tagging rules -// See http://foshttpcache.readthedocs.org/en/latest/varnish-configuration.html#id4 -sub ez_purge { - - if (req.request == "BAN") { - if (!client.ip ~ invalidators) { - error 405 "Method not allowed"; - } - - if (req.http.X-Location-Id) { - ban( "obj.http.X-Location-Id ~ " + req.http.X-Location-Id); - if (client.ip ~ debuggers) { - set req.http.X-Debug = "Ban done for content connected to LocationId " + req.http.X-Location-Id; - } - error 200 "Banned"; - } - } -} - -// Sub-routine to get client user hash, for context-aware HTTP cache. -sub ez_user_hash { - - // Prevent tampering attacks on the hash mechanism - if (req.restarts == 0 - && (req.http.accept ~ "application/vnd.fos.user-context-hash" - || req.http.x-user-hash - ) - ) { - error 400; - } - - if (req.restarts == 0 && (req.request == "GET" || req.request == "HEAD")) { - // Get User (Context) hash, for varying cache by what user has access to. - // https://doc.ez.no/display/EZP/Context+aware+HTTP+cache - - // Anonymous user w/o session => Use hardcoded anonymous hash to avoid backend lookup for hash - if (req.http.Cookie !~ "eZSESSID" && !req.http.authorization) { - // You may update this hash with the actual one for anonymous user - // to get a better cache hit ratio across anonymous users. - // Note: You should then update it every time anonymous user rights change. - set req.http.X-User-Hash = "38015b703d82206ebc01d17a39c727e5"; - } - // Pre-authenticate request to get shared cache, even when authenticated - else { - set req.http.x-fos-original-url = req.url; - set req.http.x-fos-original-accept = req.http.accept; - set req.http.x-fos-original-cookie = req.http.cookie; - // Clean up cookie for the hash request to only keep session cookie, as hash cache will vary on cookie. - set req.http.cookie = ";" + req.http.cookie; - set req.http.cookie = regsuball(req.http.cookie, "; +", ";"); - set req.http.cookie = regsuball(req.http.cookie, ";(eZSESSID[^=]*)=", "; \1="); - set req.http.cookie = regsuball(req.http.cookie, ";[^ ][^;]*", ""); - set req.http.cookie = regsuball(req.http.cookie, "^[; ]+|[; ]+$", ""); - - set req.http.accept = "application/vnd.fos.user-context-hash"; - set req.url = "/_fos_user_context_hash"; - - // Force the lookup, the backend must tell how to cache/vary response containing the user hash - - return (lookup); - } - } - - // Rebuild the original request which now has the hash. - if (req.restarts > 0 - && req.http.accept == "application/vnd.fos.user-context-hash" - ) { - set req.url = req.http.x-fos-original-url; - set req.http.accept = req.http.x-fos-original-accept; - set req.http.cookie = req.http.x-fos-original-cookie; - - unset req.http.x-fos-original-url; - unset req.http.x-fos-original-accept; - unset req.http.x-fos-original-cookie; - - // Force the lookup, the backend must tell not to cache or vary on the - // user hash to properly separate cached data. - - return (lookup); - } -} - -sub vcl_deliver { - // On receiving the hash response, copy the hash header to the original - // request and restart. - if (req.restarts == 0 - && resp.http.content-type ~ "application/vnd.fos.user-context-hash" - && resp.status == 200 - ) { - set req.http.x-user-hash = resp.http.x-user-hash; - - return (restart); - } - - // If we get here, this is a real response that gets sent to the client. - - // Remove the vary on context user hash, this is nothing public. Keep all - // other vary headers. - set resp.http.Vary = regsub(resp.http.Vary, "(?i),? *x-user-hash *", ""); - set resp.http.Vary = regsub(resp.http.Vary, "^, *", ""); - if (resp.http.Vary == "") { - unset resp.http.Vary; - } - - // Sanity check to prevent ever exposing the hash to a client. - unset resp.http.x-user-hash; - - if (client.ip ~ debuggers) { - if (obj.hits > 0) { - set resp.http.X-Cache = "HIT"; - set resp.http.X-Cache-Hits = obj.hits; - } else { - set resp.http.X-Cache = "MISS"; - } - } -} diff --git a/doc/varnish/vcl/varnish4_ban.vcl b/doc/varnish/vcl/varnish4_ban.vcl deleted file mode 100644 index cebae6cccb..0000000000 --- a/doc/varnish/vcl/varnish4_ban.vcl +++ /dev/null @@ -1,205 +0,0 @@ -// Varnish 4 style - eZ 5.4+ / 2014.09+ -// Complete VCL example -// DEPRECATED: For faster, and over time more stable setup look to ezplatform-http-cache and Varnish xkey use. - -vcl 4.0; - -// For customizing your backend and acl rules see parameters.yml -include "parameters.vcl"; - -// Called at the beginning of a request, after the complete request has been received -sub vcl_recv { - - // Set the backend - set req.backend_hint = ezplatform; - - // Advertise Symfony for ESI support - set req.http.Surrogate-Capability = "abc=ESI/1.0"; - - // Add a unique header containing the client address (only for master request) - // Please note that /_fragment URI can change in Symfony configuration - if (!req.url ~ "^/_fragment") { - if (req.http.x-forwarded-for) { - set req.http.X-Forwarded-For = req.http.X-Forwarded-For + ", " + client.ip; - } else { - set req.http.X-Forwarded-For = client.ip; - } - } - - // Trigger cache purge if needed - call ez_purge; - - // Don't cache requests other than GET and HEAD. - if (req.method != "GET" && req.method != "HEAD") { - return (pass); - } - - // Normalize the Accept-Encoding headers - if (req.http.Accept-Encoding) { - if (req.http.Accept-Encoding ~ "gzip") { - set req.http.Accept-Encoding = "gzip"; - } elsif (req.http.Accept-Encoding ~ "deflate") { - set req.http.Accept-Encoding = "deflate"; - } else { - unset req.http.Accept-Encoding; - } - } - - // Don't cache Authenticate & Authorization - // You may remove this when using REST API with basic auth. - if (req.http.Authenticate || req.http.Authorization) { - if (client.ip ~ debuggers) { - set req.http.X-Debug = "Not Cached according to configuration (Authorization)"; - } - return (hash); - } - - // Do a standard lookup on assets - // Note that file extension list below is not extensive, so consider completing it to fit your needs. - if (req.url ~ "\.(css|js|gif|jpe?g|bmp|png|tiff?|ico|img|tga|wmf|svg|swf|ico|mp3|mp4|m4a|ogg|mov|avi|wmv|zip|gz|pdf|ttf|eot|wof)$") { - return (hash); - } - - // Retrieve client user hash and add it to the forwarded request. - call ez_user_hash; - - // If it passes all these tests, do a lookup anyway. - return (hash); -} - -// Called when the requested object has been retrieved from the backend -sub vcl_backend_response { - - if (bereq.http.accept ~ "application/vnd.fos.user-context-hash" - && beresp.status >= 500 - ) { - return (abandon); - } - - // Optimize to only parse the Response contents from Symfony - if (beresp.http.Surrogate-Control ~ "ESI/1.0") { - unset beresp.http.Surrogate-Control; - set beresp.do_esi = true; - } - - // Allow stale content, in case the backend goes down or cache is not fresh any more - // make Varnish keep all objects for 1 hours beyond their TTL - set beresp.grace = 1h; -} - -// Handle purge -// You may add FOSHttpCacheBundle tagging rules -// See http://foshttpcache.readthedocs.org/en/latest/varnish-configuration.html#id4 -sub ez_purge { - - if (req.method == "BAN") { - if (!client.ip ~ invalidators) { - return (synth(405, "Method not allowed")); - } - - if (req.http.X-Location-Id) { - ban("obj.http.X-Location-Id ~ " + req.http.X-Location-Id); - if (client.ip ~ debuggers) { - set req.http.X-Debug = "Ban done for content connected to LocationId " + req.http.X-Location-Id; - } - return (synth(200, "Banned")); - } - } -} - -// Sub-routine to get client user hash, for context-aware HTTP cache. -sub ez_user_hash { - - // Prevent tampering attacks on the hash mechanism - if (req.restarts == 0 - && (req.http.accept ~ "application/vnd.fos.user-context-hash" - || req.http.x-user-hash - ) - ) { - return (synth(400)); - } - - if (req.restarts == 0 && (req.method == "GET" || req.method == "HEAD")) { - // Get User (Context) hash, for varying cache by what user has access to. - // https://doc.ez.no/display/EZP/Context+aware+HTTP+cache - - // Anonymous user w/o session => Use hardcoded anonymous hash to avoid backend lookup for hash - if (req.http.Cookie !~ "eZSESSID" && !req.http.authorization) { - // You may update this hash with the actual one for anonymous user - // to get a better cache hit ratio across anonymous users. - // Note: You should then update it every time anonymous user rights change. - set req.http.X-User-Hash = "38015b703d82206ebc01d17a39c727e5"; - } - // Pre-authenticate request to get shared cache, even when authenticated - else { - set req.http.x-fos-original-url = req.url; - set req.http.x-fos-original-accept = req.http.accept; - set req.http.x-fos-original-cookie = req.http.cookie; - // Clean up cookie for the hash request to only keep session cookie, as hash cache will vary on cookie. - set req.http.cookie = ";" + req.http.cookie; - set req.http.cookie = regsuball(req.http.cookie, "; +", ";"); - set req.http.cookie = regsuball(req.http.cookie, ";(eZSESSID[^=]*)=", "; \1="); - set req.http.cookie = regsuball(req.http.cookie, ";[^ ][^;]*", ""); - set req.http.cookie = regsuball(req.http.cookie, "^[; ]+|[; ]+$", ""); - - set req.http.accept = "application/vnd.fos.user-context-hash"; - set req.url = "/_fos_user_context_hash"; - - // Force the lookup, the backend must tell how to cache/vary response containing the user hash - - return (hash); - } - } - - // Rebuild the original request which now has the hash. - if (req.restarts > 0 - && req.http.accept == "application/vnd.fos.user-context-hash" - ) { - set req.url = req.http.x-fos-original-url; - set req.http.accept = req.http.x-fos-original-accept; - set req.http.cookie = req.http.x-fos-original-cookie; - - unset req.http.x-fos-original-url; - unset req.http.x-fos-original-accept; - unset req.http.x-fos-original-cookie; - - // Force the lookup, the backend must tell not to cache or vary on the - // user hash to properly separate cached data. - - return (hash); - } -} - -sub vcl_deliver { - // On receiving the hash response, copy the hash header to the original - // request and restart. - if (req.restarts == 0 - && resp.http.content-type ~ "application/vnd.fos.user-context-hash" - ) { - set req.http.x-user-hash = resp.http.x-user-hash; - - return (restart); - } - - // If we get here, this is a real response that gets sent to the client. - - // Remove the vary on context user hash, this is nothing public. Keep all - // other vary headers. - set resp.http.Vary = regsub(resp.http.Vary, "(?i),? *x-user-hash *", ""); - set resp.http.Vary = regsub(resp.http.Vary, "^, *", ""); - if (resp.http.Vary == "") { - unset resp.http.Vary; - } - - // Sanity check to prevent ever exposing the hash to a client. - unset resp.http.x-user-hash; - - if (client.ip ~ debuggers) { - if (obj.hits > 0) { - set resp.http.X-Cache = "HIT"; - set resp.http.X-Cache-Hits = obj.hits; - } else { - set resp.http.X-Cache = "MISS"; - } - } -} diff --git a/doc/varnish/vcl/varnish4_xkey.vcl b/doc/varnish/vcl/varnish4_xkey.vcl index 981e2a8b00..ff19f6936a 100644 --- a/doc/varnish/vcl/varnish4_xkey.vcl +++ b/doc/varnish/vcl/varnish4_xkey.vcl @@ -26,10 +26,6 @@ sub vcl_recv { // Add a Surrogate-Capability header to announce ESI support. set req.http.Surrogate-Capability = "abc=ESI/1.0"; - // Varnish, in its default configuration, sends the X-Forwarded-For header but does not filter out Forwarded header - // To be removed in Symfony 3.3 - unset req.http.Forwarded; - // Ensure that the Symfony Router generates URLs correctly with Varnish if (req.http.X-Forwarded-Proto == "https" ) { set req.http.X-Forwarded-Port = "443"; diff --git a/phpunit.xml.dist b/phpunit.xml.dist new file mode 100644 index 0000000000..5a12e6762f --- /dev/null +++ b/phpunit.xml.dist @@ -0,0 +1,31 @@ + + + + + + + + + + + + tests + + + + + + src + + src/*Bundle/Resources + src/*/*Bundle/Resources + src/*/Bundle/*Bundle/Resources + + + + diff --git a/src/.htaccess b/src/.htaccess new file mode 100644 index 0000000000..fb1de45bdb --- /dev/null +++ b/src/.htaccess @@ -0,0 +1,7 @@ + + Require all denied + + + Order deny,allow + Deny from all + diff --git a/app/logs/.keep b/var/cache/.gitkeep similarity index 100% rename from app/logs/.keep rename to var/cache/.gitkeep diff --git a/var/logs/.gitkeep b/var/logs/.gitkeep new file mode 100644 index 0000000000..e69de29bb2 diff --git a/var/sessions/.gitkeep b/var/sessions/.gitkeep new file mode 100644 index 0000000000..e69de29bb2 diff --git a/web/app.php b/web/app.php index b8a2e86830..c2bbb3dd0c 100644 --- a/web/app.php +++ b/web/app.php @@ -5,6 +5,7 @@ // Ensure UTF-8 is used in string operations setlocale(LC_CTYPE, 'C.UTF-8'); +require __DIR__ . '/../vendor/autoload.php'; // Environment is taken from "SYMFONY_ENV" variable, if not set, defaults to "prod" $environment = getenv('SYMFONY_ENV'); @@ -18,27 +19,12 @@ $useDebugging = $environment === 'dev'; } -// Depending on SYMFONY_CLASSLOADER_FILE use custom class loader, otherwise use bootstrap cache, or autoload in debug -if ($loaderFile = getenv('SYMFONY_CLASSLOADER_FILE')) { - require_once $loaderFile; -} else { - require_once __DIR__ . '/../app/autoload.php'; - if (!$useDebugging) { - require_once __DIR__ . '/../app/bootstrap.php.cache'; - } -} - if ($useDebugging) { Debug::enable(); } $kernel = new AppKernel($environment, $useDebugging); -// we don't want to use the classes cache if we are in a debug session -if (!$useDebugging) { - $kernel->loadClassCache(); -} - // Depending on the SYMFONY_HTTP_CACHE environment variable, tells whether the internal HTTP Cache mechanism is to be used. // If not set, or "", it is auto activated if _not_ in "dev" environment. if (($useHttpCache = getenv('SYMFONY_HTTP_CACHE')) === false || $useHttpCache === '') { @@ -47,23 +33,19 @@ // Load HTTP Cache ... if ($useHttpCache) { - // The standard HttpCache implementation can be overridden by setting the SYMFONY_HTTP_CACHE_CLASS environment variable. - // NOTE: Make sure to setup composer config so it is *autoloadable*, or use "SYMFONY_CLASSLOADER_FILE" for this. - if ($httpCacheClass = getenv('SYMFONY_HTTP_CACHE_CLASS')) { - $kernel = new $httpCacheClass($kernel); - } else { - $kernel = new AppCache($kernel); - } -} + $kernel = new AppCache($kernel); -$request = Request::createFromGlobals(); + // When using the HttpCache, you need to call the method in your front controller instead of relying on the configuration parameter + Request::enableHttpMethodParameterOverride(); -// If you are behind one or more trusted reverse proxies, you might want to set them in SYMFONY_TRUSTED_PROXIES environment -// variable in order to get correct client IP -if ($trustedProxies = getenv('SYMFONY_TRUSTED_PROXIES')) { - Request::setTrustedProxies(explode(',', $trustedProxies)); + // If you are behind one or more trusted reverse proxies, you might want to set them in SYMFONY_TRUSTED_PROXIES environment + // variable in order to get correct client IP. NOTE: As per Symfony doc you will need to customize these lines for your proxy! + if ($trustedProxies = getenv('SYMFONY_TRUSTED_PROXIES')) { + Request::setTrustedProxies(explode(',', $trustedProxies), Request::HEADER_X_FORWARDED_ALL); + } } +$request = Request::createFromGlobals(); $response = $kernel->handle($request); $response->send(); $kernel->terminate($request, $response); diff --git a/web/app_dev.php b/web/app_dev.php index 836db57f9c..80b5241ca4 100644 --- a/web/app_dev.php +++ b/web/app_dev.php @@ -2,11 +2,16 @@ // This file is mainly here for use with symfony server commands. // Recommended rewrite rules for apache and nginx does not use this. +// If you don't want to setup permissions the proper way (in dev), just uncomment the following PHP line +// read https://symfony.com/doc/current/setup.html#checking-symfony-application-configuration-and-setup +// for more information +//umask(0000); + // This check prevents access to debug front controllers that are deployed by accident to production servers. -// Feel free to remove this, extend it, or make something more sophisticated at your own risk. +// Feel free to remove this, extend it, or make something more sophisticated. if (isset($_SERVER['HTTP_CLIENT_IP']) || isset($_SERVER['HTTP_X_FORWARDED_FOR']) - || !(in_array(@$_SERVER['REMOTE_ADDR'], ['127.0.0.1', 'fe80::1', '::1']) || PHP_SAPI === 'cli-server') + || !(in_array(@$_SERVER['REMOTE_ADDR'], ['127.0.0.1', '::1'], true) || PHP_SAPI === 'cli-server') ) { header('HTTP/1.0 403 Forbidden'); exit('You are not allowed to access this file. Check ' . basename(__FILE__) . ' for more information.');