├── .gitignore ├── .platform.app.yaml ├── .platform ├── routes.yaml └── services.yaml ├── .sensiolabs.yml ├── .styleci.yml ├── .travis.yml ├── CONTRIBUTING.md ├── LICENSE ├── README.md ├── app ├── .htaccess ├── AppCache.php ├── AppKernel.php ├── Resources │ ├── CmfBlogBundle │ │ └── views │ │ │ └── default_layout.html.twig │ ├── LuneticsLocaleBundle │ │ └── views │ │ │ └── Switcher │ │ │ └── switcher_links.html.twig │ ├── TwigBundle │ │ └── views │ │ │ └── Exception │ │ │ └── error.html.twig │ ├── translations │ │ ├── CmfSonataPhpcrAdminIntegrationBundle.de.xliff │ │ ├── CmfSonataPhpcrAdminIntegrationBundle.en.xliff │ │ ├── CmfSonataPhpcrAdminIntegrationBundle.fr.xliff │ │ ├── CmfSonataPhpcrAdminIntegrationBundle.sk.xliff │ │ ├── messages.de.yml │ │ ├── messages.en.yml │ │ ├── messages.fr.yml │ │ └── messages.sk.yml │ └── views │ │ ├── admin │ │ ├── custom_layout.html.twig │ │ ├── form_admin_fields.html.twig │ │ ├── switcher_links.html.twig │ │ └── user_block.html.twig │ │ ├── base.html.twig │ │ ├── block │ │ └── demo_action_block.html.twig │ │ ├── demo │ │ ├── controller.html.twig │ │ └── template_explicit.html.twig │ │ ├── homepage │ │ └── index.html.twig │ │ ├── image │ │ └── upload.html.twig │ │ ├── includes │ │ ├── footer_menu.html.twig │ │ ├── main_menu.html.twig │ │ └── switcher_links.html.twig │ │ ├── security │ │ └── login.html.twig │ │ └── static_content │ │ ├── hello.html.twig │ │ └── index.html.twig ├── autoload.php └── config │ ├── config.yml │ ├── config_dev.yml │ ├── config_prod.yml │ ├── config_test.yml │ ├── parameters.yml.dist │ ├── phpcr_doctrine_dbal.yml.dist │ ├── phpcr_jackrabbit.yml.dist │ ├── routing.yml │ ├── routing_dev.yml │ ├── security.yml │ └── services.yml ├── bin ├── console ├── reloadFixtures.sh └── symfony_requirements ├── composer.json ├── composer.lock ├── phpunit.xml.dist ├── src ├── .htaccess └── AppBundle │ ├── AppBundle.php │ ├── Controller │ ├── ContentController.php │ ├── DefaultController.php │ └── SecurityController.php │ ├── DataFixtures │ └── PHPCR │ │ ├── LoadMenuData.php │ │ ├── LoadNewsData.php │ │ ├── LoadRoutingData.php │ │ └── LoadStaticPageData.php │ ├── DependencyInjection │ └── Compiler │ │ └── DocumentClassPass.php │ ├── Document │ ├── DemoClassContent.php │ ├── DemoNewsContent.php │ ├── DemoSeoContent.php │ ├── DemoSeoExtractor.php │ ├── DemoTemplateContent.php │ └── Image.php │ ├── EventListener │ └── SandboxExceptionListener.php │ ├── Resources │ ├── config │ │ ├── cmf_routing_auto.yml │ │ └── serializer │ │ │ ├── Document.DemoSeoContent.yml │ │ │ └── cmf │ │ │ └── Model.StaticContent.yml │ ├── data │ │ └── page.yml │ └── rdf-mappings │ │ ├── AppBundle.Document.DemoSeoContent.xml │ │ └── AppBundle.Document.DemoSeoExtractor.xml │ ├── Security │ └── ResourceVoter.php │ └── Twig │ └── MenuExtension.php ├── tests ├── Functional │ ├── AdminDashboardTest.php │ ├── AdminTest.php │ ├── HomepageTest.php │ ├── StaticPageTest.php │ └── WebTestCase.php ├── travis_doctrine_dbal.sh └── travis_jackrabbit.sh ├── travis.php.ini ├── vagrant ├── README.md ├── Vagrantfile └── cookbook │ ├── recipes │ └── default.rb │ └── templates │ └── default │ ├── jackrabbit.erb │ └── vhost.conf.erb ├── var ├── SymfonyRequirements.php └── logs │ └── .gitkeep └── web ├── .htaccess ├── app.php ├── app_dev.php ├── assets ├── css │ ├── sonata_admin.css │ └── style.css ├── images │ ├── pager-next.png │ └── symfony-cmf-logo.svg ├── js │ └── rawdata.js └── vendor │ ├── bootstrap.min.css │ ├── bootstrap.min.js │ ├── fonts │ ├── glyphicons-halflings-regular.eot │ ├── glyphicons-halflings-regular.svg │ ├── glyphicons-halflings-regular.ttf │ ├── glyphicons-halflings-regular.woff │ └── glyphicons-halflings-regular.woff2 │ └── jquery.min.js ├── config.php ├── favicon.ico ├── logo_symfony_cmf.png ├── reload-fixtures.php └── robots.txt /.gitignore: -------------------------------------------------------------------------------- 1 | /app/config/parameters.yml 2 | /build/ 3 | /phpunit.xml 4 | /var/* 5 | !/var/cache 6 | /var/cache/* 7 | !var/cache/.gitkeep 8 | !/var/logs 9 | /var/logs/* 10 | !var/logs/.gitkeep 11 | !/var/sessions 12 | /var/sessions/* 13 | !var/sessions/.gitkeep 14 | !var/SymfonyRequirements.php 15 | /vendor/ 16 | /web/bundles/ 17 | 18 | /app/config/phpcr.yml 19 | /jackrabbit/ 20 | /jackrabbit-standalone-*.jar 21 | /vagrant/.vagrant 22 | -------------------------------------------------------------------------------- /.platform.app.yaml: -------------------------------------------------------------------------------- 1 | # This file describes an application. You can have multiple applications 2 | # in the same project. 3 | 4 | # The name of this app. Must be unique within a project. 5 | name: php 6 | 7 | # The toolstack used to build the application. 8 | type: php:7.0 9 | build: 10 | flavor: symfony 11 | 12 | # The relationships of the application with services or other applications. 13 | # The left-hand side is the name of the relationship as it will be exposed 14 | # to the application in the PLATFORM_RELATIONSHIPS variable. The right-hand 15 | # side is in the form `:`. 16 | #relationships: 17 | # database: "mysql:mysql" 18 | 19 | # The configuration of app when it is exposed to the web. 20 | web: 21 | # The public directory of the app, relative to its root. 22 | document_root: "/web" 23 | # The front-controller script to send non-static requests to. 24 | passthru: "/app.php" 25 | whitelist: 26 | # slides 27 | - ^/slides/.*\.html$ 28 | 29 | # CSS, JavaScript and Other assets. 30 | - \.css$ 31 | - \.js$ 32 | - ^/assets/ 33 | - ^/bundles/ 34 | 35 | # image/* types. 36 | - \.gif$ 37 | - \.jpe?g$ 38 | - \.png$ 39 | - \.ico 40 | - \.svg$ 41 | 42 | # robots.txt. 43 | - /robots\.txt$ 44 | 45 | cron: 46 | symfony: 47 | spec: '* */2 * * *' 48 | cmd: ./bin/reloadFixtures.sh $PWD true 49 | 50 | # The size of the persistent disk of the application (in MB). 51 | disk: 2048 52 | 53 | # The mounts that will be performed when the package is deployed. 54 | mounts: 55 | "/var/cache": "shared:files/cache" 56 | "/var/logs": "shared:files/logs" 57 | 58 | # The hooks that will be performed when the package is deployed. 59 | hooks: 60 | build: | 61 | rm web/app_dev.php 62 | # place sqlite file into /tmp so that we can write to it during deploy 63 | sed -i 's@%kernel.root_dir%/../var/app.sqlite@/tmp/app.sqlite@' app/config/parameters.yml 64 | bin/console --env=prod assets:install -n --no-debug 65 | bin/console --env=prod assetic:dump -n --no-debug 66 | deploy: ./bin/reloadFixtures.sh $PWD true 67 | 68 | runtime: 69 | extensions: 70 | - name: blackfire 71 | configuration: 72 | server_id: "ce95eba9-2d90-48b7-ad75-fcad42e1bcab" 73 | server_token: "ca7e32ac2d466ecfdf30b8ac43bdfef1304fc3feeb66e8906c1192b435e206f0" 74 | -------------------------------------------------------------------------------- /.platform/routes.yaml: -------------------------------------------------------------------------------- 1 | "http://{default}/": 2 | type: upstream 3 | upstream: "php:php" 4 | -------------------------------------------------------------------------------- /.platform/services.yaml: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/symfony-cmf/cmf-sandbox/5cb26f59d1c104ac9350bd81daf4d3d74994cdf0/.platform/services.yaml -------------------------------------------------------------------------------- /.sensiolabs.yml: -------------------------------------------------------------------------------- 1 | # Sensiolabs Insight configuration 2 | # 3 | # Please remove this file if you start a real project. It's not intended for production use. 4 | # 5 | 6 | global_exclude_dirs: 7 | - vendor 8 | - web 9 | - app/tests 10 | - vagrant 11 | - bin 12 | 13 | pre_composer_script: | 14 | #!/bin/bash 15 | 16 | cp app/config/parameters.yml.dist app/config/parameters.yml 17 | cp app/config/phpcr_doctrine_dbal.yml.dist app/config/phpcr.yml 18 | 19 | exclude_patterns: 20 | - app/autoload.php 21 | - app/check.php 22 | - app/SymfonyRequirements.php 23 | 24 | rules: 25 | symfony.web_config_should_not_be_present: 26 | enabled: false 27 | -------------------------------------------------------------------------------- /.styleci.yml: -------------------------------------------------------------------------------- 1 | preset: symfony 2 | 3 | enabled: 4 | - ordered_use 5 | - short_array_syntax 6 | 7 | disabled: 8 | - phpdoc_to_comment 9 | - phpdoc_var_without_name 10 | - single_line_class_definition 11 | 12 | finder: 13 | exclude: [var] 14 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: php 2 | 3 | php: 4 | - 7.1 5 | 6 | sudo: false 7 | 8 | cache: 9 | directories: 10 | - $HOME/.composer/cache/files 11 | 12 | matrix: 13 | fast_finish: true 14 | include: 15 | - php: 7.1 16 | env: TRANSPORT=jackrabbit COMPOSER_INSTALL=1 17 | - php: 7.1 18 | env: TRANSPORT=doctrine_dbal COMPOSER_INSTALL=1 19 | 20 | env: 21 | global: 22 | - SYMFONY_PHPUNIT_DIR=.phpunit SYMFONY_PHPUNIT_REMOVE="symfony/yaml" SYMFONY_PHPUNIT_VERSION=5.7 23 | - SYMFONY_DEPRECATIONS_HELPER=weak 24 | matrix: 25 | - TRANSPORT=jackrabbit 26 | - TRANSPORT=doctrine_dbal 27 | 28 | before_install: 29 | - if ! [ -z "$STABILITY" ]; then composer config minimum-stability ${STABILITY}; composer config prefer-stable true; fi; 30 | - if [ "$TRAVIS_PHP_VERSION" == "7.0" ]; then echo "zend.enable_gc = 0" >> ~/.phpenv/versions/$(phpenv version-name)/etc/conf.d/travis.ini; fi 31 | - phpenv config-rm xdebug.ini || true 32 | - composer self-update 33 | 34 | install: 35 | - phpenv config-add travis.php.ini 36 | - php -ini | grep memory_limit 37 | - if [ "$COMPOSER_INSTALL" != "1" ]; then composer update --no-scripts --prefer-dist; else composer install --no-scripts --prefer-dist; fi 38 | 39 | before_script: 40 | - cp app/config/phpcr_${TRANSPORT}.yml.dist app/config/phpcr.yml 41 | - composer run-script post-update-cmd 42 | - ./tests/travis_${TRANSPORT}.sh 43 | - bin/console doctrine:phpcr:workspace:create sandbox_test -e=test 44 | - bin/console doctrine:phpcr:repository:init -e=test 45 | 46 | script: php vendor/bin/simple-phpunit --debug 47 | 48 | notifications: 49 | irc: "irc.freenode.org#symfony-cmf" 50 | email: "symfony-cmf-devs@googlegroups.com" 51 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | Contributing 2 | ------------ 3 | 4 | Symfony2 CMF is an open source, community-driven project. We follow the same 5 | guidelines as core Symfony2. If you'd like to contribute, please read the 6 | [Contributing Code][1] part of the documentation. If you're submitting a pull 7 | request, please follow the guidelines in the [Submitting a Patch][2] section 8 | and use the [Pull Request Template][3]. 9 | 10 | [1]: http://symfony.com/doc/current/contributing/code/index.html 11 | [2]: http://symfony.com/doc/current/contributing/code/patches.html#check-list 12 | [3]: http://symfony.com/doc/current/contributing/code/patches.html#make-a-pull-request 13 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | cmf-sandbox 2 | 3 | The MIT License 4 | 5 | Copyright (c) 2011-2013 Symfony2 CMF 6 | 7 | Permission is hereby granted, free of charge, to any person obtaining a copy 8 | of this software and associated documentation files (the "Software"), to deal 9 | in the Software without restriction, including without limitation the rights 10 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 | copies of the Software, and to permit persons to whom the Software is 12 | furnished to do so, subject to the following conditions: 13 | 14 | The above copyright notice and this permission notice shall be included in 15 | all copies or substantial portions of the Software. 16 | 17 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 23 | THE SOFTWARE. 24 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # This repository is no longer maintained 2 | 3 | Due to lack of interest, we had to decide to discontinue this repository. 4 | The CMF project focusses on the [Routing component](https://github.com/symfony-cmf/routing) and [RoutingBundle](https://github.com/symfony-cmf/routing-bundle), which are still in active use by other projects. 5 | 6 | This repository will no longer be upgraded and marked as abandoned, but will be kept available for legacy projects or if somebody wants to experiment with the CMF. 7 | 8 | You can contact us in the #symfony_cmf channel of the [Symfony devs slack](https://symfony.com/slack). 9 | 10 | # Symfony Content Management Framework Sandbox 11 | 12 | [![Build Status](https://travis-ci.org/symfony-cmf/cmf-sandbox.svg?branch=master)](https://travis-ci.org/symfony-cmf/cmf-sandbox) 13 | [![StyleCI](https://styleci.io/repos/1316499/shield)](https://styleci.io/repos/1316499) 14 | [![Dependency Status](https://www.versioneye.com/php/symfony-cmf:sandbox/badge.svg)](https://www.versioneye.com/php/symfony-cmf:sandbox) 15 | 16 | This sandbox is a testing ground for the cmf bundles being developed. 17 | 18 | It is based on the [Symfony Standard edition](https://github.com/symfony/symfony-standard) and adds all 19 | cmf related bundles on top of the standard edition bundles. 20 | 21 | Link to the [live demo](http://sandbox.cmf.symfony.com/) 22 | 23 | ## Getting started 24 | 25 | You can run the sandbox on your system, or in a virtualbox VM using Vagrant. For the latter, see 26 | "Getting started using Vagrant" 27 | 28 | ### You will need: 29 | 30 | * PHP 5.3.9+ (with intl extension) 31 | * PHPUnit 3.6+ (optional) 32 | * Composer 33 | 34 | ## Initial setup and configuration 35 | 36 | git clone git://github.com/symfony-cmf/cmf-sandbox.git 37 | cd cmf-sandbox 38 | curl -s http://getcomposer.org/installer | php -- 39 | php composer.phar install 40 | 41 | At the end of the installation you will be interactively asked several configuration 42 | questions. Note that by default you will end up with a configuration using 43 | SQLite and Doctrine DBAL for storage. If you want to adjust the configuration 44 | to use Jackrabbit please look at the following section. 45 | 46 | ### Install and run Apache JackRabbit 47 | 48 | Follow the guide in the [Jackalope Wiki](https://github.com/jackalope/jackalope/wiki/Running-a-jackrabbit-server). 49 | You can also use a different PHPCR implementation but this is the most solid 50 | implementation. 51 | 52 | Once you have that, copy the default jackalope-jackrabbit configuration file, 53 | adjust it as needed and install the dependencies with composer: 54 | 55 | cp app/config/phpcr_jackrabbit.yml.dist app/config/phpcr.yml 56 | 57 | The last command will fetch the main project and all its dependencies (CMF 58 | Bundles, Symfony, Doctrine\PHPCR, Jackalope ... ). You might want to have a look 59 | at the ``app/config/parameters.yml`` and adjust as needed. 60 | 61 | ### Install the Doctrine DBAL provider (optional) 62 | 63 | Instead of `phpcr_jackrabbit.yml.dist`, use the `phpcr_doctrine_dbal*.yml.dist` 64 | files and create the database accordingly. If you have the PHP sqlite extension 65 | available, this is the simplest to quickly try out the CMF. Copy the file 66 | and then install the dependencies: 67 | 68 | cp app/config/phpcr_doctrine_dbal.yml.dist app/config/phpcr.yml 69 | 70 | The Doctrine DBAL implementation is installed by default already along side the Jackrabbit implementation. 71 | 72 | To disable the meta data and node cache for debugging comment the ``caches`` settings in the `phpcr.yml`. 73 | 74 | Then, create the database and tables and set up the default workspace using: 75 | 76 | php bin/console doctrine:database:create 77 | php bin/console doctrine:phpcr:init:dbal --force 78 | 79 | ## Prepare the PHPCR repository 80 | 81 | First you need to create a workspace that will hold the data for the sandbox. 82 | The default parameters.yml defines the workspace to be 'default'. You can 83 | change this of course. If you do, f.e. to 'sandbox, also run the following command: 84 | 85 | php bin/console doctrine:phpcr:workspace:create sandbox 86 | 87 | Once your workspace is set up, you need to [register the node types](https://github.com/doctrine/phpcr-odm/wiki/Custom-node-type-phpcr%3Amanaged) 88 | for PHPCR-ODM: 89 | 90 | php bin/console doctrine:phpcr:repository:init 91 | 92 | ## Import the fixtures 93 | 94 | The admin backend is still in an early stage. Until it improves, the easiest is 95 | to programmatically create data. The best way to do that is with the doctrine 96 | data fixtures. The DoctrinePHPCRBundle included in the symfony-cmf repository 97 | provides a command to load fixtures: 98 | 99 | php bin/console -v doctrine:phpcr:fixtures:load 100 | 101 | Run this to load the fixtures from the Sandbox AppBundle. 102 | 103 | ## Setup filesystem permissions 104 | 105 | As with any Symfony2 installation, you need to set up some filesystem permissions. 106 | A good guide is in the [Symfony2 installation guide](http://symfony.com/doc/current/book/installation.html#configuration-and-setup). 107 | If you use the default setup, an sqlite database will be created at `app/app.sqlite`. 108 | You need to set up permissions for this file and the app/ folder with the method 109 | you chose from the installation guide. 110 | 111 | If you just want to move on and try out the sandbox for now, you can 112 | run: 113 | 114 | sudo chmod -R 777 app/ 115 | 116 | ## Access by web browser 117 | 118 | Create an apache virtual host entry along the lines of: 119 | 120 | 121 | Servername cmf.lo 122 | DocumentRoot /path/to/symfony-cmf/cmf-sandbox/web 123 | 124 | AllowOverride All 125 | 126 | 127 | 128 | And add an entry to your hosts file for cmf.lo 129 | 130 | If you are running Symfony2 for the first time, run http://cmf.lo/config.php to ensure your system settings have been 131 | setup inline with the expected behaviour of the Symfony2 framework. 132 | 133 | Note however that "Configure your Symfony Application online" is not supported in the sandbox. 134 | 135 | Then point your browser to http://cmf.lo/app_dev.php 136 | 137 | ## Production environment 138 | 139 | In order to run the sandbox in production mode at http://cmf.lo/ 140 | you need to generate the doctrine proxies and dump the assetic assets: 141 | 142 | php bin/console cache:warmup --env=prod --no-debug 143 | php bin/console assetic:dump --env=prod --no-debug 144 | 145 | # Getting started using Vagrant 146 | 147 | please checkout the [README.md](vagrant) in the vagrant/ folder of the project 148 | 149 | # Other hints 150 | 151 | ## Console 152 | 153 | The PHPCR ODM Bundle provides a couple of useful commands in the doctrine:phpcr namespace. 154 | Type bin/console to see them all. 155 | 156 | ## Admin interface 157 | 158 | There is a proof-of-concept admin interface using the SonataPhpcrAdminBundle at 159 | http://cmf.lo/app_dev.php/admin/dashboard 160 | 161 | Basically you have paginated lists for two types of documents. You create new documents, edit and delete them. 162 | Some filtering is available in the list. This bundle is an implementation of 163 | [Sonata Admin Bundle](https://github.com/sonata-project/SonataAdminBundle) 164 | 165 | At the moment there is no notion of parents and sons in the admin bundle. 166 | 167 | ## Run the test suite 168 | 169 | Functional tests are written with PHPUnit. Note that Bundles and Components are tested independently: 170 | 171 | php bin/console doctrine:phpcr:workspace:create sandbox_test 172 | phpunit -c app 173 | 174 | 175 | ## Remove demo configuration 176 | 177 | If you start a project from the sandbox, remove ```.sensiolabs.yml``` as its not a good example for production use. 178 | -------------------------------------------------------------------------------- /app/.htaccess: -------------------------------------------------------------------------------- 1 | deny from all 2 | -------------------------------------------------------------------------------- /app/AppCache.php: -------------------------------------------------------------------------------- 1 | getEnvironment(), ['dev', 'test'])) { 74 | $bundles[] = new Symfony\Bundle\WebProfilerBundle\WebProfilerBundle(); 75 | $bundles[] = new Symfony\Bundle\DebugBundle\DebugBundle(); 76 | $bundles[] = new Sensio\Bundle\GeneratorBundle\SensioGeneratorBundle(); 77 | $bundles[] = new Sensio\Bundle\DistributionBundle\SensioDistributionBundle(); 78 | $bundles[] = new \Symfony\Bundle\WebServerBundle\WebServerBundle(); 79 | 80 | // additional bundle for tests 81 | if ('test' === $this->getEnvironment()) { 82 | $bundles[] = new Liip\FunctionalTestBundle\LiipFunctionalTestBundle(); 83 | } 84 | } 85 | 86 | return $bundles; 87 | } 88 | 89 | public function getRootDir() 90 | { 91 | return __DIR__; 92 | } 93 | 94 | public function getCacheDir() 95 | { 96 | return dirname(__DIR__).'/var/cache/'.$this->getEnvironment(); 97 | } 98 | 99 | public function getLogDir() 100 | { 101 | return dirname(__DIR__).'/var/logs'; 102 | } 103 | 104 | public function registerContainerConfiguration(LoaderInterface $loader) 105 | { 106 | $loader->load(__DIR__.'/config/config_'.$this->getEnvironment().'.yml'); 107 | } 108 | } 109 | -------------------------------------------------------------------------------- /app/Resources/CmfBlogBundle/views/default_layout.html.twig: -------------------------------------------------------------------------------- 1 | {% extends "base.html.twig" %} 2 | 3 | {% block content %} 4 | {% endblock %} 5 | -------------------------------------------------------------------------------- /app/Resources/LuneticsLocaleBundle/views/Switcher/switcher_links.html.twig: -------------------------------------------------------------------------------- 1 | {% for locale in locales %} 2 | 3 | {{ locale.locale_current_language }} 4 | 5 | {% endfor %} 6 | -------------------------------------------------------------------------------- /app/Resources/TwigBundle/views/Exception/error.html.twig: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | An Error Occurred: {{ status_text }} 6 | 7 | 8 |

Oops! An Error Occurred

9 |

The server returned a "{{ status_code }} {{ status_text }}".

10 |

11 | The admin tool currently allows full access to the entire content tree. 12 | As a result its possible to break the entire routing configuration. In 13 | many cases when you see an error on this site, its caused by someone 14 | having done exactly that. You can reload the entire content to the 15 | original state by calling 16 | reload-fixtures.php 17 |

18 | 19 | 20 | -------------------------------------------------------------------------------- /app/Resources/translations/CmfSonataPhpcrAdminIntegrationBundle.de.xliff: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | breadcrumb.link_demo_seo_content_list 7 | Statischer Inhalt 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /app/Resources/translations/CmfSonataPhpcrAdminIntegrationBundle.en.xliff: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | breadcrumb.link_demo_seo_content_list 7 | Static contents 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /app/Resources/translations/CmfSonataPhpcrAdminIntegrationBundle.fr.xliff: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | breadcrumb.link_demo_seo_content_list 7 | Contenus statiques 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /app/Resources/translations/CmfSonataPhpcrAdminIntegrationBundle.sk.xliff: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | breadcrumb.link_demo_seo_content_list 7 | Statické stránky 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /app/Resources/translations/messages.de.yml: -------------------------------------------------------------------------------- 1 | cmf: 2 | action_block: 3 | title: Demo Aktions-Block 4 | body: Dieser Inhalt wurde durch eine Symfony2 Controller Action gerendert. Er kann nicht inline editiert werden. 5 | raw_data: | 6 | Dieses Fenster zeigt, wie Inhalt mit einem Accept Header im xml bzw json Format abgefragt werden kann. 7 | Damit dies geht, muss das Format erlabut sein in fos_rest.format_listener.rules und braucht es Konfiguration 8 | für den jms serializer für das Dokument in config.yml. 9 | raw_data_hint: Rohdaten dieser Seite anzeigen. 10 | -------------------------------------------------------------------------------- /app/Resources/translations/messages.en.yml: -------------------------------------------------------------------------------- 1 | cmf: 2 | action_block: 3 | title: Demo Action Block 4 | body: This block content is rendered by a custom Symfony2 action. It has no inline-editing. 5 | raw_data: | 6 | This window shows the output when requesting content with an accept-header asking for xml / json. 7 | This is enabled by configuring a rule in fos_rest.format_listener.rules and a jms serializer mapping 8 | for the content document in config.yml. 9 | raw_data_hint: Show raw data of this page. 10 | -------------------------------------------------------------------------------- /app/Resources/translations/messages.fr.yml: -------------------------------------------------------------------------------- 1 | cmf: 2 | action_block: 3 | title: Demo block d'action 4 | body: Ce contenu est rendu par une action d'un controlleur Symfony2. Il n'a pas le inline editing. 5 | raw_data: | 6 | Cette fenêtre montre le résultat obtenu quand on envoye un header Accept demandant du xml / json. 7 | Pour controler les formats permit, on utilise les règles dans fos_rest.format_listener.rules et 8 | on a besoin d'un mapping pour le document en question avec le jms serializer dans config.yml. 9 | raw_data_hint: Data brut de ce page. 10 | -------------------------------------------------------------------------------- /app/Resources/translations/messages.sk.yml: -------------------------------------------------------------------------------- 1 | cmf: 2 | action_block: 3 | title: Demo blok akcie 4 | body: Tento obsah bloku je vyrenderovaný vlastnou Symfony2 akciou. Nemá možnosť inline editácie. 5 | -------------------------------------------------------------------------------- /app/Resources/views/admin/custom_layout.html.twig: -------------------------------------------------------------------------------- 1 | {% extends 'SonataAdminBundle::standard_layout.html.twig' %} 2 | 3 | {% block stylesheets %} 4 | {{ parent() }} 5 | 6 | 7 | 8 | {% endblock %} 9 | -------------------------------------------------------------------------------- /app/Resources/views/admin/form_admin_fields.html.twig: -------------------------------------------------------------------------------- 1 | {% extends "SonataDoctrinePHPCRAdminBundle:Form:form_admin_fields.html.twig" %} 2 | 3 | {% block burgov_key_value_widget %} 4 | {{- block('sonata_type_native_collection_widget') -}} 5 | {% endblock %} 6 | -------------------------------------------------------------------------------- /app/Resources/views/admin/switcher_links.html.twig: -------------------------------------------------------------------------------- 1 | Read in 2 | {% for locale in locales %} 3 | 4 | {% endfor %} 5 | -------------------------------------------------------------------------------- /app/Resources/views/admin/user_block.html.twig: -------------------------------------------------------------------------------- 1 | {% extends 'SonataAdminBundle:Core:user_block.html.twig' %} 2 | 3 | {% block user_block %} 4 | 8 | 9 |
10 | {{ locale_switcher(null, null, 'admin/switcher_links.html.twig') }} 11 |
12 | {% endblock %} 13 | -------------------------------------------------------------------------------- /app/Resources/views/base.html.twig: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | {{ sonata_seo_metadatas() }} 8 | {{ sonata_seo_link_canonical() }} 9 | {{ sonata_seo_lang_alternates() }} 10 | {{ sonata_seo_title() }} 11 | 12 | {% block includes %} 13 | 14 | 15 | {% endblock %} 16 | 17 | {% block top_scripts %} 18 | {% endblock %} 19 | 20 | 21 | 76 | 77 | {% block banner %} 78 | 87 | {% endblock %} 88 | 89 |
90 |
91 |
92 |
93 |
Navigation
94 | 95 | {{ knp_menu_render('main', { template: 'includes/main_menu.html.twig' }) }} 96 |
97 |
98 | 99 |
100 | {% block content %}{% endblock %} 101 |
102 |
103 |
104 | 105 | 120 | 121 | 131 | 132 | {% block bottom_scripts %} 133 | 134 | 135 | 136 | {% endblock %} 137 | 138 | 139 | -------------------------------------------------------------------------------- /app/Resources/views/block/demo_action_block.html.twig: -------------------------------------------------------------------------------- 1 | {% extends 'CmfBlockBundle:Block:block_base.html.twig' %} 2 | 3 | {% block block %} 4 |
5 |

{% trans %}cmf.action_block.title{% endtrans %}

6 |

{% trans %}cmf.action_block.body{% endtrans %}

7 |
8 | {% endblock %} 9 | -------------------------------------------------------------------------------- /app/Resources/views/demo/controller.html.twig: -------------------------------------------------------------------------------- 1 | {% extends "base.html.twig" %} 2 | 3 | {% block content %} 4 |
5 |

{{ info|raw }}

6 | 7 | Read about this feature in the CMF documentation. 8 |
9 | 10 |

{{ cmfMainContent.title }}

11 |
{{ cmfMainContent.body|raw }}
12 | {% endblock %} 13 | -------------------------------------------------------------------------------- /app/Resources/views/demo/template_explicit.html.twig: -------------------------------------------------------------------------------- 1 | {# special template without the sidebar #} 2 | {% extends "base.html.twig" %} 3 | 4 | {% block content %} 5 |
6 |

This page is rendered using the demo/template_explicit.html.twig template. This template is directly configured in the route by using the _template setting.

7 | 8 | Read about this feature in the CMF documentation. 9 |
10 | 11 |

{{ cmfMainContent.title }}

12 | {{ cmfMainContent.body|raw }} 13 | 14 | {{ parent() }} 15 | {% endblock %} 16 | -------------------------------------------------------------------------------- /app/Resources/views/homepage/index.html.twig: -------------------------------------------------------------------------------- 1 | {% extends "base.html.twig" %} 2 | 3 | {% block banner %} 4 | 17 | {% endblock %} 18 | 19 | {% block content %} 20 |
21 |

The homepage uses a custom template. This template is directly configured at the route by using the _template setting.

22 | 23 | Read about this feature in the CMF documentation. 24 |
25 | 26 |

{{ cmfMainContent.title }}

27 | 28 | {{ cmfMainContent.body|raw }} 29 | 30 | {{ sonata_block_render({ 'name': 'additionalInfoBlock' }, { 31 | 'divisible_by': 3, 32 | 'divisible_class': 'row', 33 | 'child_class': 'col-md-4' 34 | }) }} 35 | 36 |
37 |
38 |

Some additional links:

39 | 44 |
45 | 46 |
47 | {{ sonata_block_render({ 'name': 'rssBlock' }) }} 48 |
49 |
50 | {% endblock %} 51 | -------------------------------------------------------------------------------- /app/Resources/views/image/upload.html.twig: -------------------------------------------------------------------------------- 1 | http://dribbble.com/system/users/2404/screenshots/349714/qta-logo.png?1323721724 2 | -------------------------------------------------------------------------------- /app/Resources/views/includes/footer_menu.html.twig: -------------------------------------------------------------------------------- 1 | {% extends "knp_menu.html.twig" %} 2 | 3 | {% block list %} 4 | {% set listAttributes = item.childrenAttributes|merge({ class: 'footer-nav' }) %} 5 | {{ parent() }} 6 | {% endblock %} 7 | -------------------------------------------------------------------------------- /app/Resources/views/includes/main_menu.html.twig: -------------------------------------------------------------------------------- 1 | {% extends "knp_menu.html.twig" %} 2 | 3 | {% block list %} 4 | {% set listAttributes = item.childrenAttributes|merge({ class: 'list-group' }) %} 5 | {{ parent() }} 6 | {% endblock %} 7 | 8 | {% block item %} 9 | {% set classes = item.attribute('class') is not empty ? [item.attribute('class')] : [] %} 10 | {% do item.setAttribute('class', classes|merge(['list-group-item'])|join(' ')) %} 11 | {{ parent() }} 12 | {% endblock %} 13 | -------------------------------------------------------------------------------- /app/Resources/views/includes/switcher_links.html.twig: -------------------------------------------------------------------------------- 1 | {% for locale in locales %} 2 | 3 | {{ locale.locale_target_language|capitalize }} 4 | 5 | {% endfor %} 6 | -------------------------------------------------------------------------------- /app/Resources/views/security/login.html.twig: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Admin area login 8 | 9 | 10 | 11 | 23 | 24 | 25 | 63 | 64 | 65 | -------------------------------------------------------------------------------- /app/Resources/views/static_content/hello.html.twig: -------------------------------------------------------------------------------- 1 | {% extends "base.html.twig" %} 2 | 3 | {% block raw_data %}{# can't get raw data for this #}{% endblock %} 4 | 5 | {% block content %} 6 |

This page is a normal Symfony page: A template rendered by a controller that was resolved using a route defined in app/config/routing.yml.

7 | 8 |

Hello World!

9 |

Sonet affert an has. Nam id odio nisl eruditi. Te quo falli propriae delectus, ut animal meliore est, agam decore in sea. Prima debet fierent id sed. Usu debet paulo argumentum ex, solum homero in sed, modus laboramus et usu. Brute legendos contentiones ex pri. Ut suscipit honestatis sed, per id facer euismod probatus. Ne persius posidonium eum, has elaboraret philosophia eu. No eam wisi choro labores. Sit id oratio aperiam electram, quodsi deterruisset no eum, vel modo quaeque ei.

10 | {% endblock %} 11 | -------------------------------------------------------------------------------- /app/Resources/views/static_content/index.html.twig: -------------------------------------------------------------------------------- 1 | {% extends "base.html.twig" %} 2 | 3 | {% block content %} 4 |
5 |

This page is generated by the CmfContentBundle using the static_content/index.html.twig template.

6 | 7 | Read about this feature in the CMF documentation. 8 |
9 | 10 |

{{ cmfMainContent.title }}

11 | {{ cmfMainContent.body|raw }} 12 | 13 | {{ sonata_block_render({ 'name': 'additionalInfoBlock' }) }} 14 | {% endblock %} 15 | -------------------------------------------------------------------------------- /app/autoload.php: -------------------------------------------------------------------------------- 1 | ' 202 | items: 203 | - cmf_sonata_phpcr_admin_integration.content.admin 204 | - cmf_sonata_phpcr_admin_integration.block.simple_admin 205 | - cmf_sonata_phpcr_admin_integration.block.container_admin 206 | - cmf_sonata_phpcr_admin_integration.block.reference_admin 207 | - cmf_sonata_phpcr_admin_integration.block.action_admin 208 | routing: 209 | label: URLs 210 | icon: '' 211 | items: 212 | - cmf_sonata_phpcr_admin_integration.routing.route_admin 213 | - cmf_sonata_phpcr_admin_integration.routing.redirect_route_admin 214 | menu: 215 | label: Menu 216 | icon: '' 217 | items: 218 | - cmf_sonata_phpcr_admin_integration.menu.menu_admin 219 | - cmf_sonata_phpcr_admin_integration.menu.node_admin 220 | 221 | sonata_doctrine_phpcr_admin: 222 | templates: 223 | form: 224 | - admin/form_admin_fields.html.twig 225 | document_tree: 226 | routing_defaults: [locale] 227 | 228 | sonata_translation: 229 | locales: '%locales%' 230 | default_locale: '%locale%' 231 | phpcr: true 232 | 233 | sonata_seo: 234 | page: 235 | title: CMF Sandbox 236 | metas: 237 | name: 238 | keywords: 'CMF, Symfony, Routing, Content, PHPCR' 239 | 240 | ivory_ck_editor: 241 | configs: 242 | cmf_sonata_phpcr_admin_integration: { toolbar: standard } 243 | 244 | sensio_framework_extra: 245 | router: { annotations: true } 246 | request: { converters: true } 247 | 248 | lunetics_locale: 249 | strict_mode: true 250 | guessing_order: 251 | - router 252 | - cookie 253 | - browser 254 | allowed_locales: '%locales%' 255 | 256 | doctrine_cache: 257 | providers: 258 | phpcr_meta: 259 | type: file_system 260 | phpcr_nodes: 261 | type: file_system 262 | 263 | jms_serializer: 264 | metadata: 265 | auto_detection: true 266 | directories: 267 | CmfContentBundle: 268 | namespace_prefix: 'Symfony\Cmf\Bundle\ContentBundle' 269 | path: '@AppBundle/Resources/config/serializer/cmf' 270 | 271 | fos_rest: 272 | view: 273 | force_redirects: 274 | html: true 275 | formats: 276 | json: true 277 | xml: true 278 | templating_formats: 279 | html: true 280 | allowed_methods_listener: true 281 | access_denied_listener: 282 | json: true 283 | format_listener: 284 | rules: 285 | - { path: ^/, priorities: [ html, json, xml, css ], fallback_format: html, prefer_extension: false } 286 | -------------------------------------------------------------------------------- /app/config/config_dev.yml: -------------------------------------------------------------------------------- 1 | imports: 2 | - { resource: config.yml } 3 | 4 | framework: 5 | router: { resource: '%kernel.root_dir%/config/routing_dev.yml' } 6 | profiler: { only_exceptions: false } 7 | 8 | web_profiler: 9 | toolbar: true 10 | intercept_redirects: false 11 | 12 | monolog: 13 | handlers: 14 | main: 15 | type: stream 16 | path: '%kernel.logs_dir%/%kernel.environment%.log' 17 | level: debug 18 | firephp: 19 | type: firephp 20 | level: info 21 | 22 | assetic: 23 | use_controller: true 24 | 25 | #swiftmailer: 26 | # delivery_address: me@example.com 27 | -------------------------------------------------------------------------------- /app/config/config_prod.yml: -------------------------------------------------------------------------------- 1 | imports: 2 | - { resource: config.yml } 3 | 4 | #doctrine: 5 | # orm: 6 | # metadata_cache_driver: apc 7 | # result_cache_driver: apc 8 | # query_cache_driver: apc 9 | 10 | monolog: 11 | handlers: 12 | main: 13 | type: fingers_crossed 14 | action_level: error 15 | handler: nested 16 | nested: 17 | type: stream 18 | path: '%kernel.logs_dir%/%kernel.environment%.log' 19 | level: debug 20 | -------------------------------------------------------------------------------- /app/config/config_test.yml: -------------------------------------------------------------------------------- 1 | imports: 2 | - { resource: config_dev.yml } 3 | 4 | parameters: 5 | phpcr_workspace: sandbox_test 6 | 7 | framework: 8 | test: ~ 9 | session: 10 | storage_id: session.storage.filesystem 11 | 12 | security: 13 | firewalls: 14 | main: 15 | http_basic: ~ 16 | 17 | web_profiler: 18 | toolbar: false 19 | intercept_redirects: false 20 | 21 | swiftmailer: 22 | disable_delivery: true 23 | -------------------------------------------------------------------------------- /app/config/parameters.yml.dist: -------------------------------------------------------------------------------- 1 | parameters: 2 | locale: en 3 | locales: [en, fr, de] 4 | 5 | secret: ThisTokenIsNotSoSecretChangeIt 6 | 7 | # a little hack to avoid errors on missing node/coffeescript. 8 | # remove -disabled if you want coffee. 9 | coffee.extension: '\.coffee-disabled$' 10 | coffee.bin: '' 11 | coffee.node: '' 12 | 13 | database_driver: pdo_sqlite 14 | database_host: 15 | database_port: 16 | database_name: 17 | database_user: 18 | database_password: 19 | database_path: '%kernel.root_dir%/../var/app.sqlite' 20 | 21 | mailer_transport: smtp 22 | mailer_host: localhost 23 | mailer_user: ~ 24 | mailer_password: ~ 25 | -------------------------------------------------------------------------------- /app/config/phpcr_doctrine_dbal.yml.dist: -------------------------------------------------------------------------------- 1 | parameters: 2 | phpcr_backend: 3 | logging: true 4 | profiling: true 5 | type: doctrinedbal 6 | connection: default 7 | caches: 8 | meta: doctrine_cache.providers.phpcr_meta 9 | nodes: doctrine_cache.providers.phpcr_nodes 10 | parameters: 11 | jackalope.check_login_on_server: false 12 | phpcr_workspace: default 13 | phpcr_user: admin 14 | phpcr_pass: admin 15 | -------------------------------------------------------------------------------- /app/config/phpcr_jackrabbit.yml.dist: -------------------------------------------------------------------------------- 1 | parameters: 2 | phpcr_backend: 3 | logging: true 4 | profiling: true 5 | type: jackrabbit 6 | url: http://localhost:8080/server/ 7 | parameters: 8 | jackalope.check_login_on_server: false 9 | phpcr_workspace: default 10 | phpcr_user: admin 11 | phpcr_pass: admin 12 | -------------------------------------------------------------------------------- /app/config/routing.yml: -------------------------------------------------------------------------------- 1 | # Internal routing configuration to handle ESI 2 | #_internal: 3 | # resource: '@FrameworkBundle/Resources/config/routing/internal.xml' 4 | # prefix: /_internal 5 | 6 | _app: 7 | resource: '@AppBundle/Controller' 8 | type: annotation 9 | 10 | home_redirect: 11 | path: / 12 | defaults: 13 | _controller: lunetics_locale.switcher_controller:switchAction 14 | route: '/cms/routes/%locale%' 15 | statusCode: 301 16 | useReferrer: false 17 | 18 | admin_wo_locale: 19 | path: /admin 20 | defaults: 21 | _controller: FrameworkBundle:Redirect:redirect 22 | route: sonata_admin_dashboard 23 | permanent: true # this for 301 24 | 25 | admin_dashboard_wo_locale: 26 | path: /admin/dashboard 27 | defaults: 28 | _controller: FrameworkBundle:Redirect:redirect 29 | route: sonata_admin_dashboard 30 | permanent: true # this for 301 31 | 32 | admin_dashboard: 33 | path: /{_locale}/admin/ 34 | defaults: 35 | _controller: FrameworkBundle:Redirect:redirect 36 | route: sonata_admin_dashboard 37 | permanent: true # this for 301 38 | 39 | admin: 40 | resource: '@SonataAdminBundle/Resources/config/routing/sonata_admin.xml' 41 | prefix: /{_locale}/admin 42 | 43 | sonata_admin: 44 | resource: . 45 | type: sonata_admin 46 | prefix: /{_locale}/admin 47 | 48 | block_cache: 49 | resource: '@CmfBlockBundle/Resources/config/routing/cache.xml' 50 | prefix: / 51 | 52 | cmf_resource: 53 | resource: '@CmfResourceRestBundle/Resources/config/routing.yml' 54 | prefix: /admin 55 | 56 | sonata_phpcr_admin_tree: 57 | resource: '@SonataDoctrinePHPCRAdminBundle/Resources/config/routing/tree.xml' 58 | prefix: /admin 59 | -------------------------------------------------------------------------------- /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 | _main: 10 | resource: routing.yml 11 | -------------------------------------------------------------------------------- /app/config/security.yml: -------------------------------------------------------------------------------- 1 | security: 2 | # *NEVER* store passwords as plaintext in production, this is purely for 3 | # demo purposes. 4 | encoders: 5 | Symfony\Component\Security\Core\User\User: plaintext 6 | 7 | role_hierarchy: 8 | ROLE_ADMIN: [ROLE_USER, ROLE_SONATA_ADMIN, ROLE_CAN_VIEW_NON_PUBLISHED] 9 | ROLE_SUPER_ADMIN: [ROLE_ADMIN, ROLE_ALLOWED_TO_SWITCH] 10 | 11 | providers: 12 | in_memory: 13 | memory: 14 | # Only for demo purposes. Of course, use a more 15 | # secure password on production. 16 | users: 17 | anna_admin: { password: kitten, roles: ROLE_ADMIN } 18 | admin: { password: admin, roles: ROLE_ADMIN } 19 | 20 | firewalls: 21 | dev: 22 | pattern: ^/(_(profiler|wdt)|css|images|js)/ 23 | security: false 24 | 25 | main: 26 | anonymous: ~ 27 | form_login: 28 | login_path: login 29 | check_path: login 30 | logout: ~ 31 | 32 | access_control: 33 | - { path: ^(/(de|fr|en))?/admin, roles: ROLE_ADMIN } 34 | - { path: ^/login, roles: IS_AUTHENTICATED_ANONYMOUSLY } 35 | -------------------------------------------------------------------------------- /app/config/services.yml: -------------------------------------------------------------------------------- 1 | services: 2 | app.content_controller: 3 | class: AppBundle\Controller\ContentController 4 | parent: cmf_content.controller 5 | 6 | app.exception_listener: 7 | class: AppBundle\EventListener\SandboxExceptionListener 8 | calls: 9 | - [setContainer, ['@service_container']] 10 | tags: 11 | - { name: kernel.event_subscriber } 12 | 13 | app.twig.menu_extension: 14 | class: AppBundle\Twig\MenuExtension 15 | arguments: ['@knp_menu.helper', '@knp_menu.matcher'] 16 | tags: 17 | - { name: twig.extension } 18 | 19 | app.resource_voter: 20 | class: AppBundle\Security\ResourceVoter 21 | tags: 22 | - { name: security.voter } 23 | -------------------------------------------------------------------------------- /bin/console: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env php 2 | getParameterOption(array('--env', '-e'), getenv('SYMFONY_ENV') ?: 'dev'); 21 | $debug = getenv('SYMFONY_DEBUG') !== '0' && !$input->hasParameterOption(array('--no-debug', '')) && $env !== 'prod'; 22 | 23 | if ($debug) { 24 | Debug::enable(); 25 | } 26 | 27 | $kernel = new AppKernel($env, $debug); 28 | $application = new Application($kernel); 29 | $application->run($input); 30 | -------------------------------------------------------------------------------- /bin/reloadFixtures.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | DIR=$1 4 | PROD=$2||false 5 | run () { 6 | comment="+++ "$1" +++" 7 | command=$2 8 | echo ${comment} 9 | echo "Command: "${command} 10 | ${command} > /tmp/output 2> /tmp/error 11 | OUT=$? 12 | if [ ${OUT} -eq 0 ];then 13 | echo "+++ DONE +++" 14 | cat /tmp/output 15 | echo 16 | else 17 | echo "+++ Errors +++" 18 | cat /tmp/output 19 | cat /tmp/error 20 | exit ${OUT} 21 | fi 22 | } 23 | 24 | CACHE_DIR=${DIR}var/cache/prod 25 | if [ "${PROD}" ]; then 26 | run "Remove cache directory:" "rm -rf /var/cache/prod" 27 | else 28 | run "Remove cache directory:" "rm -rf ${DIR}var/cache/prod" 29 | fi 30 | run "Drop and init dbal:" "php ${DIR}bin/console --env=prod doctrine:phpcr:init:dbal --drop --force -n -vvv" 31 | run "Init repositories:" "php ${DIR}bin/console --env=prod doctrine:phpcr:repository:init -n -vvv" 32 | run "Load date fixtures:" "php ${DIR}bin/console --env=prod doctrine:phpcr:fixtures:load -n -vvv" 33 | run "Warm up cache:" "php ${DIR}bin/console --env=prod cache:warmup -n --no-debug -vvv" -------------------------------------------------------------------------------- /bin/symfony_requirements: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env php 2 | getPhpIniConfigPath(); 9 | 10 | echo_title('Symfony Requirements Checker'); 11 | 12 | echo '> PHP is using the following php.ini file:'.PHP_EOL; 13 | if ($iniPath) { 14 | echo_style('green', ' '.$iniPath); 15 | } else { 16 | echo_style('yellow', ' WARNING: No configuration file (php.ini) used by PHP!'); 17 | } 18 | 19 | echo PHP_EOL.PHP_EOL; 20 | 21 | echo '> Checking Symfony requirements:'.PHP_EOL.' '; 22 | 23 | $messages = array(); 24 | foreach ($symfonyRequirements->getRequirements() as $req) { 25 | if ($helpText = get_error_message($req, $lineSize)) { 26 | echo_style('red', 'E'); 27 | $messages['error'][] = $helpText; 28 | } else { 29 | echo_style('green', '.'); 30 | } 31 | } 32 | 33 | $checkPassed = empty($messages['error']); 34 | 35 | foreach ($symfonyRequirements->getRecommendations() as $req) { 36 | if ($helpText = get_error_message($req, $lineSize)) { 37 | echo_style('yellow', 'W'); 38 | $messages['warning'][] = $helpText; 39 | } else { 40 | echo_style('green', '.'); 41 | } 42 | } 43 | 44 | if ($checkPassed) { 45 | echo_block('success', 'OK', 'Your system is ready to run Symfony projects'); 46 | } else { 47 | echo_block('error', 'ERROR', 'Your system is not ready to run Symfony projects'); 48 | 49 | echo_title('Fix the following mandatory requirements', 'red'); 50 | 51 | foreach ($messages['error'] as $helpText) { 52 | echo ' * '.$helpText.PHP_EOL; 53 | } 54 | } 55 | 56 | if (!empty($messages['warning'])) { 57 | echo_title('Optional recommendations to improve your setup', 'yellow'); 58 | 59 | foreach ($messages['warning'] as $helpText) { 60 | echo ' * '.$helpText.PHP_EOL; 61 | } 62 | } 63 | 64 | echo PHP_EOL; 65 | echo_style('title', 'Note'); 66 | echo ' The command console could use a different php.ini file'.PHP_EOL; 67 | echo_style('title', '~~~~'); 68 | echo ' than the one used with your web server. To be on the'.PHP_EOL; 69 | echo ' safe side, please check the requirements from your web'.PHP_EOL; 70 | echo ' server using the '; 71 | echo_style('yellow', 'web/config.php'); 72 | echo ' script.'.PHP_EOL; 73 | echo PHP_EOL; 74 | 75 | exit($checkPassed ? 0 : 1); 76 | 77 | function get_error_message(Requirement $requirement, $lineSize) 78 | { 79 | if ($requirement->isFulfilled()) { 80 | return; 81 | } 82 | 83 | $errorMessage = wordwrap($requirement->getTestMessage(), $lineSize - 3, PHP_EOL.' ').PHP_EOL; 84 | $errorMessage .= ' > '.wordwrap($requirement->getHelpText(), $lineSize - 5, PHP_EOL.' > ').PHP_EOL; 85 | 86 | return $errorMessage; 87 | } 88 | 89 | function echo_title($title, $style = null) 90 | { 91 | $style = $style ?: 'title'; 92 | 93 | echo PHP_EOL; 94 | echo_style($style, $title.PHP_EOL); 95 | echo_style($style, str_repeat('~', strlen($title)).PHP_EOL); 96 | echo PHP_EOL; 97 | } 98 | 99 | function echo_style($style, $message) 100 | { 101 | // ANSI color codes 102 | $styles = array( 103 | 'reset' => "\033[0m", 104 | 'red' => "\033[31m", 105 | 'green' => "\033[32m", 106 | 'yellow' => "\033[33m", 107 | 'error' => "\033[37;41m", 108 | 'success' => "\033[37;42m", 109 | 'title' => "\033[34m", 110 | ); 111 | $supports = has_color_support(); 112 | 113 | echo($supports ? $styles[$style] : '').$message.($supports ? $styles['reset'] : ''); 114 | } 115 | 116 | function echo_block($style, $title, $message) 117 | { 118 | $message = ' '.trim($message).' '; 119 | $width = strlen($message); 120 | 121 | echo PHP_EOL.PHP_EOL; 122 | 123 | echo_style($style, str_repeat(' ', $width)); 124 | echo PHP_EOL; 125 | echo_style($style, str_pad(' ['.$title.']', $width, ' ', STR_PAD_RIGHT)); 126 | echo PHP_EOL; 127 | echo_style($style, $message); 128 | echo PHP_EOL; 129 | echo_style($style, str_repeat(' ', $width)); 130 | echo PHP_EOL; 131 | } 132 | 133 | function has_color_support() 134 | { 135 | static $support; 136 | 137 | if (null === $support) { 138 | if (DIRECTORY_SEPARATOR == '\\') { 139 | $support = false !== getenv('ANSICON') || 'ON' === getenv('ConEmuANSI'); 140 | } else { 141 | $support = function_exists('posix_isatty') && @posix_isatty(STDOUT); 142 | } 143 | } 144 | 145 | return $support; 146 | } 147 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "symfony-cmf/sandbox", 3 | "description": "Demo Sandbox for the Symfony Content Management Framework", 4 | "homepage": "http://cmf.symfony.com", 5 | "license": "MIT", 6 | "authors": [ 7 | { 8 | "name": "Symfony CMF Community", 9 | "homepage": "https://github.com/symfony-cmf/SimpleCmsBundle/contributors" 10 | } 11 | ], 12 | "autoload": { 13 | "psr-4": { "": "src/" }, 14 | "classmap": [ "app/AppKernel.php", "app/AppCache.php" ] 15 | }, 16 | "autoload-dev": { 17 | "psr-4": { "Tests\\": "tests/" } 18 | }, 19 | "require": { 20 | "php": "^7.1", 21 | "symfony/symfony": "^3.3", 22 | "symfony/assetic-bundle": "^2.8", 23 | "symfony/swiftmailer-bundle": "^2.3.10", 24 | "symfony/monolog-bundle": "^3.0.2", 25 | "symfony/polyfill-apcu": "^1.0", 26 | "sensio/distribution-bundle": "^5.0", 27 | "sensio/framework-extra-bundle": "^3.0.2", 28 | "incenteev/composer-parameter-handler": "^2.0", 29 | 30 | "symfony-cmf/symfony-cmf": "^2.0", 31 | "symfony-cmf/seo-bundle": "^2.0", 32 | "symfony-cmf/routing": "^2.0", 33 | "symfony-cmf/routing-auto-bundle": "^2.0", 34 | "symfony-cmf/sonata-phpcr-admin-integration-bundle": "^1.0", 35 | 36 | "jackalope/jackalope-doctrine-dbal": "1.2.*", 37 | "jackalope/jackalope-jackrabbit": "1.2.*", 38 | "doctrine/doctrine-bundle": "^1.6", 39 | "doctrine/data-fixtures": "^1.0", 40 | "doctrine/doctrine-cache-bundle": "^1.2", 41 | "doctrine/phpcr-odm": "^1.4", 42 | 43 | "sonata-project/cache-bundle": "^2.4", 44 | "sonata-project/translation-bundle": "2.1.0", 45 | "sonata-project/doctrine-phpcr-admin-bundle": "^2.0", 46 | 47 | "jms/serializer-bundle": "^1.1", 48 | "friendsofsymfony/rest-bundle": "~1.7", 49 | "eko/feedbundle": "^1.2.7", 50 | "lunetics/locale-bundle": "^2.5", 51 | "burgov/key-value-form-bundle": "^1.4", 52 | "egeloen/ckeditor-bundle": "^4.0" 53 | }, 54 | "require-dev": { 55 | "sensio/generator-bundle": "^3.0", 56 | "liip/functional-test-bundle": "^1.3", 57 | "symfony-cmf/testing": "^2.0", 58 | "symfony/phpunit-bridge": "^3.3" 59 | }, 60 | "scripts": { 61 | "post-install-cmd": [ 62 | "Incenteev\\ParameterHandler\\ScriptHandler::buildParameters", 63 | "Sensio\\Bundle\\DistributionBundle\\Composer\\ScriptHandler::buildBootstrap", 64 | "Sensio\\Bundle\\DistributionBundle\\Composer\\ScriptHandler::clearCache", 65 | "Sensio\\Bundle\\DistributionBundle\\Composer\\ScriptHandler::installAssets", 66 | "Sensio\\Bundle\\DistributionBundle\\Composer\\ScriptHandler::installRequirementsFile" 67 | ], 68 | "post-update-cmd": [ 69 | "Incenteev\\ParameterHandler\\ScriptHandler::buildParameters", 70 | "Sensio\\Bundle\\DistributionBundle\\Composer\\ScriptHandler::buildBootstrap", 71 | "Sensio\\Bundle\\DistributionBundle\\Composer\\ScriptHandler::clearCache", 72 | "Sensio\\Bundle\\DistributionBundle\\Composer\\ScriptHandler::installAssets", 73 | "Sensio\\Bundle\\DistributionBundle\\Composer\\ScriptHandler::installRequirementsFile" 74 | ] 75 | }, 76 | "extra": { 77 | "symfony-app-dir": "app", 78 | "symfony-bin-dir": "bin", 79 | "symfony-var-dir": "var", 80 | "symfony-web-dir": "web", 81 | "symfony-tests-dir": "tests", 82 | "symfony-assets-install": "relative", 83 | "incenteev-parameters": [ 84 | { "file": "app/config/parameters.yml" }, 85 | { 86 | "file": "app/config/phpcr.yml", 87 | "dist-file": "app/config/phpcr_doctrine_dbal.yml.dist" 88 | } 89 | ], 90 | "branch-alias": { 91 | "dev-master": "2.0-dev" 92 | } 93 | }, 94 | "conflict": { 95 | "sonata-project/cache": "<1.1.1" 96 | } 97 | } 98 | -------------------------------------------------------------------------------- /phpunit.xml.dist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 22 | 23 | 24 | 25 | tests 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | src 36 | 37 | src/*/*Bundle/Resources 38 | src/*/*Bundle/Tests 39 | src/*/Bundle/*Bundle/Resources 40 | src/*/Bundle/*Bundle/Tests 41 | 42 | 43 | 44 | 45 | 46 | -------------------------------------------------------------------------------- /src/.htaccess: -------------------------------------------------------------------------------- 1 | deny from all 2 | -------------------------------------------------------------------------------- /src/AppBundle/AppBundle.php: -------------------------------------------------------------------------------- 1 | addCompilerPass(new DocumentClassPass(), PassConfig::TYPE_BEFORE_OPTIMIZATION, 100); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/AppBundle/Controller/ContentController.php: -------------------------------------------------------------------------------- 1 | $contentDocument, 40 | 'info' => 'This page is rendered by '.__METHOD__.'. This controller was configured for this route type.', 41 | ]; 42 | 43 | return $this->renderResponse('demo/controller.html.twig', $params); 44 | } 45 | 46 | /** 47 | * Action that is mapped in the controller_by_class map. 48 | * 49 | * This can inject something else for the template for this type of content. 50 | * 51 | * @param object $contentDocument 52 | * 53 | * @return Response the response 54 | */ 55 | public function classAction($contentDocument) 56 | { 57 | if (!$contentDocument) { 58 | throw new NotFoundHttpException('Content not found'); 59 | } 60 | 61 | $params = [ 62 | 'cmfMainContent' => $contentDocument, 63 | 'info' => 'This page is rendered by '.__METHOD__.'. This controller will be called for content objects that are instances of AppBundle\Document\DemoClassContent.', 64 | ]; 65 | 66 | return $this->renderResponse('demo/controller.html.twig', $params); 67 | } 68 | 69 | /** 70 | * Action that is explicitly referenced in the _controller field of a content. 71 | * 72 | * This can inject something else for the template 73 | * 74 | * @param object $contentDocument 75 | * 76 | * @return Response 77 | */ 78 | public function specialAction($contentDocument) 79 | { 80 | if (!$contentDocument) { 81 | throw new NotFoundHttpException('Content not found'); 82 | } 83 | 84 | $params = [ 85 | 'cmfMainContent' => $contentDocument, 86 | 'info' => 'This page is rendered by '.__METHOD__.'. This controller was explicitely defined for the route by setting the _controller default.', 87 | ]; 88 | 89 | return $this->renderResponse('demo/controller.html.twig', $params); 90 | } 91 | } 92 | -------------------------------------------------------------------------------- /src/AppBundle/Controller/DefaultController.php: -------------------------------------------------------------------------------- 1 | render('block/demo_action_block.html.twig', [ 31 | 'block' => $block, 32 | ]); 33 | } 34 | 35 | /** 36 | * @Route("/hello", name="symfony_route") 37 | */ 38 | public function helloAction() 39 | { 40 | return $this->render('static_content/hello.html.twig'); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /src/AppBundle/Controller/SecurityController.php: -------------------------------------------------------------------------------- 1 | get('security.authentication_utils'); 26 | $error = $authenticationUtils->getLastAuthenticationError(); 27 | $lastUsername = $authenticationUtils->getLastUsername(); 28 | 29 | return $this->render('security/login.html.twig', [ 30 | 'last_username' => $lastUsername, 31 | 'error' => $error, 32 | ]); 33 | } 34 | 35 | /** 36 | * @Route("/logout", name="logout") 37 | */ 38 | public function logoutAction() 39 | { 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /src/AppBundle/DataFixtures/PHPCR/LoadMenuData.php: -------------------------------------------------------------------------------- 1 | getPhpcrSession(); 45 | 46 | $basepath = $this->container->getParameter('cmf_menu.persistence.phpcr.menu_basepath'); 47 | $content_path = $this->container->getParameter('cmf_content.persistence.phpcr.content_basepath'); 48 | 49 | NodeHelper::createPath($session, $basepath); 50 | $root = $manager->find(null, $basepath); 51 | 52 | $labels = ['en' => 'Home', 'de' => 'Start', 'fr' => 'Accueil']; 53 | /** @var $main Menu */ 54 | $main = $this->createMenuNode($manager, $root, 'main', $labels, $manager->find(null, "$content_path/home")); 55 | $main->setChildrenAttributes(['class' => 'menu_main']); 56 | 57 | $this->createMenuNode($manager, $main, 'admin-item', 'Admin', null, null, 'sonata_admin_dashboard'); 58 | 59 | $projects = $this->createMenuNode($manager, $main, 'projects-item', ['en' => 'Projects', 'de' => 'Projekte', 'fr' => 'Projets'], $manager->find(null, "$content_path/projects")); 60 | $this->createMenuNode($manager, $projects, 'cmf-item', 'Symfony CMF', $manager->find(null, "$content_path/cmf")); 61 | 62 | $company = $this->createMenuNode($manager, $main, 'company-item', ['en' => 'Company', 'de' => 'Firma', 'fr' => 'Entreprise'], $manager->find(null, "$content_path/company")); 63 | $this->createMenuNode($manager, $company, 'team-item', ['en' => 'Team', 'de' => 'Team', 'fr' => 'Equipe'], $manager->find(null, "$content_path/team")); 64 | $this->createMenuNode($manager, $company, 'more-item', ['en' => 'More', 'de' => 'Mehr', 'fr' => 'Plus'], $manager->find(null, "$content_path/more")); 65 | 66 | $this->createMenuNode($manager, $main, 'about', 'About us', $manager->find(null, "$content_path/about")); 67 | $this->createMenuNode($manager, $main, 'contact', 'Contact', $manager->find(null, "$content_path/contact")); 68 | 69 | $demo = $this->createMenuNode($manager, $main, 'demo-item', 'Demo', $manager->find(null, "$content_path/demo")); 70 | //TODO: this should be possible without a content as the controller might not need a content. support directly having the route document as "content" in the menu document? 71 | $this->createMenuNode($manager, $demo, 'controller-item', 'Explicit controller', $manager->find(null, "$content_path/demo_controller")); 72 | $this->createMenuNode($manager, $demo, 'template-item', 'Explicit template', $manager->find(null, "$content_path/demo_template")); 73 | $this->createMenuNode($manager, $demo, 'type-item', 'Route type to controller', $manager->find(null, "$content_path/demo_type")); 74 | $this->createMenuNode($manager, $demo, 'class-item', 'Class to controller', $manager->find(null, "$content_path/demo_class")); 75 | $this->createMenuNode($manager, $demo, 'test-item', 'Normal Symfony Route', null, null, 'symfony_route'); 76 | $this->createMenuNode($manager, $demo, 'external-item', 'External Link', null, 'http://cmf.symfony.com/'); 77 | 78 | $publicationDemo = $this->createMenuNode($manager, $main, 'publication-demo-item', 'Publication Demo', $manager->find(null, "$content_path/publication_demo")); 79 | $this->createMenuNode($manager, $publicationDemo, 'not-published', 'Not published', $manager->find(null, "$content_path/not_published")); 80 | $this->createMenuNode($manager, $publicationDemo, 'published-tomorrow', 'Published tomorrow', $manager->find(null, "$content_path/published_tomorrow")); 81 | 82 | $singlelocale = $this->createMenuNode($manager, $main, 'singlelocale-item', ['en' => 'singlelocale'], $manager->find(null, "$content_path/singlelocale")); 83 | $this->createMenuNode($manager, $singlelocale, 'singlelocale-sub-item', ['en' => 'singlelocale child'], $manager->find(null, "$content_path/singlelocale")); 84 | 85 | $seo = $this->createMenuNode($manager, $main, 'seo', 'SEO', $manager->find(null, "$content_path/simple-seo-example")); 86 | $this->createMenuNode($manager, $seo, 'simple-seo-example', ['en' => 'Seo-Simple-Content'], $manager->find(null, "$content_path/simple-seo-example")); 87 | $this->createMenuNode($manager, $seo, 'demo-seo-extractor', ['en' => 'Seo-Extractor'], $manager->find(null, "$content_path/demo-seo-extractor")); 88 | $this->createMenuNode($manager, $seo, 'simple-seo-property', ['en' => 'Seo-Extra-Properties'], $manager->find(null, "$content_path/simple-seo-property")); 89 | 90 | $this->createMenuNode($manager, $main, 'routing-auto-item', ['en' => 'Auto routing example', 'de' => 'Auto routing beispiel', 'fr' => 'Auto routing exemple'], $manager->find(null, "$content_path/news/RoutingAutoBundle generates routes!")); 91 | 92 | $manager->flush(); 93 | } 94 | 95 | /** 96 | * @return MenuNode a Navigation instance with the specified information 97 | */ 98 | protected function createMenuNode(DocumentManager $manager, $parent, $name, $label, $content, $uri = null, $route = null) 99 | { 100 | if (!$parent instanceof MenuNode && !$parent instanceof Menu) { 101 | $menuNode = new Menu(); 102 | } else { 103 | $menuNode = new MenuNode(); 104 | } 105 | 106 | $menuNode->setParentDocument($parent); 107 | $menuNode->setName($name); 108 | 109 | $manager->persist($menuNode); // do persist before binding translation 110 | 111 | if (null !== $content) { 112 | $menuNode->setContent($content); 113 | } elseif (null !== $uri) { 114 | $menuNode->setUri($uri); 115 | } elseif (null !== $route) { 116 | $menuNode->setRoute($route); 117 | } 118 | 119 | if (is_array($label)) { 120 | foreach ($label as $locale => $l) { 121 | $menuNode->setLabel($l); 122 | $manager->bindTranslation($menuNode, $locale); 123 | } 124 | } else { 125 | $menuNode->setLabel($label); 126 | } 127 | 128 | return $menuNode; 129 | } 130 | } 131 | -------------------------------------------------------------------------------- /src/AppBundle/DataFixtures/PHPCR/LoadNewsData.php: -------------------------------------------------------------------------------- 1 | container->getParameter('cmf_content.persistence.phpcr.content_basepath'); 41 | $newsPath = $basePath.'/news'; 42 | NodeHelper::createPath($manager->getPhpcrSession(), $newsPath); 43 | $newsRoot = $manager->find(null, $newsPath); 44 | 45 | $news = new DemoNewsContent(); 46 | $news->setParentDocument($newsRoot); 47 | $news->setTitle('RoutingAutoBundle generates routes!'); 48 | $news->setBody(<<<'EOT' 49 | 'This is a news item which demonstrates the routing auto bundle. The routing 50 | auto bundle automatically creates routes for documents which are persisted. 51 | 52 | See the routing auto configuration file to see how this works. 53 | EOT 54 | ); 55 | 56 | $manager->persist($news); 57 | $manager->flush(); 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /src/AppBundle/DataFixtures/PHPCR/LoadRoutingData.php: -------------------------------------------------------------------------------- 1 | getPhpcrSession(); 52 | 53 | $basepath = $this->container->getParameter('cmf_sonata_phpcr_admin_integration.routing.basepath'); 54 | if ($session->itemExists($basepath)) { 55 | $session->removeItem($basepath); 56 | } 57 | 58 | NodeHelper::createPath($session, $basepath); 59 | $parent = $manager->find(null, $basepath); 60 | 61 | $content_path = $this->container->getParameter('cmf_content.persistence.phpcr.content_basepath'); 62 | $locales = $this->container->getParameter('locales'); 63 | foreach ($locales as $locale) { 64 | $home = new Route(); 65 | $home->setPosition($parent, $locale); 66 | $home->setDefault(RouteObjectInterface::TEMPLATE_NAME, 'homepage/index.html.twig'); 67 | $home->setContent($manager->find(null, "$content_path/home")); 68 | $manager->persist($home); 69 | 70 | $company = new Route(); 71 | $company->setPosition($home, 'company'); 72 | $company->setContent($manager->find(null, "$content_path/company")); 73 | $manager->persist($company); 74 | 75 | $team = new Route(); 76 | $team->setPosition($company, 'team'); 77 | $team->setContent($manager->find(null, "$content_path/team")); 78 | $manager->persist($team); 79 | 80 | $more = new Route(); 81 | $more->setPosition($company, 'more'); 82 | $more->setContent($manager->find(null, "$content_path/more")); 83 | $manager->persist($more); 84 | 85 | $about = new Route(); 86 | $about->setPosition($home, 'about'); 87 | $about->setContent($manager->find(null, "$content_path/about")); 88 | $manager->persist($about); 89 | 90 | $contact = new Route(); 91 | $contact->setPosition($home, 'contact'); 92 | $contact->setContent($manager->find(null, "$content_path/contact")); 93 | $manager->persist($contact); 94 | 95 | $projects = new Route(); 96 | $projects->setPosition($home, 'projects'); 97 | $projects->setContent($manager->find(null, "$content_path/projects")); 98 | $manager->persist($projects); 99 | 100 | $cmf = new Route(); 101 | $cmf->setPosition($projects, 'cmf'); 102 | $cmf->setContent($manager->find(null, "$content_path/cmf")); 103 | $manager->persist($cmf); 104 | 105 | $seo = new Route(); 106 | $seo->setPosition($home, 'simple-seo-example'); 107 | $seo->setContent($manager->find(null, "$content_path/simple-seo-example")); 108 | $manager->persist($seo); 109 | 110 | $seo = new Route(); 111 | $seo->setPosition($home, 'simple-seo-property'); 112 | $seo->setContent($manager->find(null, "$content_path/simple-seo-property")); 113 | $manager->persist($seo); 114 | 115 | $seo = new Route(); 116 | $seo->setPosition($home, 'demo-seo-extractor'); 117 | $seo->setContent($manager->find(null, "$content_path/demo-seo-extractor")); 118 | $manager->persist($seo); 119 | } 120 | 121 | // demo features of routing 122 | 123 | // we can create routes without locales, but will lose the language context of course 124 | 125 | $demo = new Route(); 126 | $demo->setPosition($parent, 'demo'); 127 | $demo->setContent($manager->find(null, "$content_path/demo")); 128 | $demo->setDefault(RouteObjectInterface::TEMPLATE_NAME, 'demo/template_explicit.html.twig'); 129 | $manager->persist($demo); 130 | 131 | // explicit template 132 | $template = new Route(); 133 | $template->setPosition($demo, 'atemplate'); 134 | $template->setContent($manager->find(null, "$content_path/demo_template")); 135 | $template->setDefault(RouteObjectInterface::TEMPLATE_NAME, 'demo/template_explicit.html.twig'); 136 | $manager->persist($template); 137 | 138 | // explicit controller 139 | $controller = new Route(); 140 | $controller->setPosition($demo, 'controller'); 141 | $controller->setContent($manager->find(null, "$content_path/demo_controller")); 142 | $controller->setDefault('_controller', 'app.content_controller:specialAction'); 143 | $manager->persist($controller); 144 | 145 | // type to controller mapping 146 | $type = new Route(); 147 | $type->setPosition($demo, 'type'); 148 | $type->setContent($manager->find(null, "$content_path/demo_type")); 149 | $type->setDefault('type', 'demo_type'); 150 | $manager->persist($type); 151 | 152 | // class to controller mapping 153 | $class = new Route(); 154 | $class->setPosition($demo, 'class'); 155 | $class->setContent($manager->find(null, "$content_path/demo_class")); 156 | $manager->persist($class); 157 | 158 | // redirections 159 | 160 | // redirect to uri 161 | $redirect = new RedirectRoute(); 162 | $redirect->setPosition($parent, 'external'); 163 | $redirect->setUri('http://cmf.symfony.com'); 164 | $manager->persist($redirect); 165 | 166 | // redirect to other doctrine route 167 | $redirectRoute = new RedirectRoute(); 168 | $redirectRoute->setPosition($parent, 'short'); 169 | $redirectRoute->setRouteTarget($cmf); 170 | $manager->persist($redirectRoute); 171 | 172 | // redirect to Symfony route 173 | $redirectS = new RedirectRoute(); 174 | $redirectS->setPosition($parent, 'short1'); 175 | $redirectS->setRouteName('test'); 176 | $manager->persist($redirectS); 177 | 178 | // class to template mapping is used for all the rest 179 | 180 | $default_locale = $this->container->getParameter('locale'); 181 | $singlelocale = new Route(); 182 | $singlelocale->setPosition($manager->find(null, "$basepath/$default_locale"), 'singlelocale'); 183 | $singlelocale->setDefault('_locale', $default_locale); 184 | $singlelocale->setRequirement('_locale', $default_locale); 185 | $singlelocale->setContent($manager->find(null, "$content_path/singlelocale")); 186 | $manager->persist($singlelocale); 187 | 188 | // publication demos 189 | $publicationDemo = new Route(); 190 | $publicationDemo->setPosition($parent, 'publicationdemo'); 191 | $publicationDemo->setContent($manager->find(null, "$content_path/publication_demo")); 192 | $manager->persist($publicationDemo); 193 | 194 | $notPublished = new Route(); 195 | $notPublished->setPosition($publicationDemo, 'notpublished'); 196 | $notPublished->setContent($manager->find(null, "$content_path/not_published")); 197 | $manager->persist($notPublished); 198 | 199 | $publishedTomorrow = new Route(); 200 | $publishedTomorrow->setPosition($publicationDemo, 'publishedtomorrow'); 201 | $publishedTomorrow->setContent($manager->find(null, "$content_path/published_tomorrow")); 202 | $manager->persist($publishedTomorrow); 203 | 204 | $manager->flush(); 205 | } 206 | } 207 | -------------------------------------------------------------------------------- /src/AppBundle/DataFixtures/PHPCR/LoadStaticPageData.php: -------------------------------------------------------------------------------- 1 | getPhpcrSession(); 46 | 47 | $basepath = $this->container->getParameter('cmf_content.persistence.phpcr.content_basepath'); 48 | NodeHelper::createPath($session, $basepath); 49 | 50 | $yaml = new Parser(); 51 | $data = $yaml->parse( 52 | file_get_contents( 53 | __DIR__.'/../../Resources/data/page.yml' 54 | ) 55 | ); 56 | 57 | $parent = $manager->find(null, $basepath); 58 | foreach ($data['static'] as $overview) { 59 | $path = $basepath.'/'.$overview['name']; 60 | $page = $manager->find(null, $path); 61 | if (!$page) { 62 | $class = isset($overview['class']) ? $overview['class'] : 'AppBundle\\Document\\DemoSeoContent'; 63 | /** @var $page DemoSeoContent */ 64 | $page = new $class(); 65 | $page->setName($overview['name']); 66 | $page->setParentDocument($parent); 67 | $manager->persist($page); 68 | } 69 | 70 | if (is_array($overview['title'])) { 71 | foreach ($overview['title'] as $locale => $title) { 72 | $page->setTitle($title); 73 | $page->setBody($overview['body'][$locale]); 74 | 75 | $manager->bindTranslation($page, $locale); 76 | } 77 | } else { 78 | $page->setTitle($overview['title']); 79 | $page->setBody($overview['body']); 80 | } 81 | 82 | if (isset($overview['publishable']) && false === $overview['publishable']) { 83 | $page->setPublishable(false); 84 | } 85 | 86 | if (!empty($overview['publishStartDate'])) { 87 | $page->setPublishStartDate(new \DateTime($overview['publishStartDate'])); 88 | } 89 | 90 | if (!empty($overview['publishEndDate'])) { 91 | $page->setPublishEndDate(new \DateTime($overview['publishEndDate'])); 92 | } 93 | 94 | if (isset($overview['blocks'])) { 95 | foreach ($overview['blocks'] as $name => $block) { 96 | $this->loadBlock($manager, $page, $name, $block); 97 | } 98 | } 99 | } 100 | 101 | //add a loading for a simple seo aware page 102 | $seoDemo = new DemoSeoContent(); 103 | $seoDemo->setName('simple-seo-example'); 104 | $seoDemo->setTitle('Simple seo example'); 105 | $seoDemo->setBody(<<<'EOH' 106 |

107 | When implementing the SeoAwareInterface, 108 | you get a chance to configure SEO data 109 | (title, description, keywords and original url) 110 | of the document using SeoMetadata. 111 | The SonataAdminBundle integration allows admins to update this data. 112 |

113 | 114 | Read about this feature in the CMF documentation. 115 | EOH 116 | ); 117 | $seoDemo->setParentDocument($parent); 118 | 119 | $seoMetadata = new SeoMetadata(); 120 | $seoMetadata->setTitle('Simple seo example'); 121 | $seoMetadata->setOriginalUrl('/home'); 122 | $seoMetadata->setMetaDescription('This is a simple example of an seo aware document in the sandbox.'); 123 | $seoMetadata->setMetaKeywords('Seo'); 124 | $seoDemo->setSeoMetadata($seoMetadata); 125 | 126 | $manager->persist($seoDemo); 127 | $manager->bindTranslation($seoDemo, 'en'); 128 | 129 | //add a loading for a simple seo aware page 130 | $seoDemo = new DemoSeoContent(); 131 | $seoDemo->setName('simple-seo-property'); 132 | $seoDemo->setTitle('Simple seo property'); 133 | $seoDemo->setBody( 134 | '

135 | SeoMetadata have got the possibility to 136 | to add custom properties for custom 137 | meta tags. You just to set a type, key 138 | and value 139 |

' 140 | ); 141 | $seoDemo->setParentDocument($parent); 142 | 143 | $seoMetadata = new SeoMetadata(); 144 | $seoMetadata->setTitle('Simple seo property'); 145 | $seoMetadata->setMetaKeywords('Seo, Properties'); 146 | $seoMetadata->addExtraHttp('content-type', 'text/html'); 147 | $seoMetadata->addExtraName('robots', 'index, follow'); 148 | $seoMetadata->addExtraProperty('og:title', 'extra title'); 149 | $seoDemo->setSeoMetadata($seoMetadata); 150 | $manager->persist($seoDemo); 151 | 152 | $manager->bindTranslation($seoDemo, 'en'); 153 | 154 | $manager->flush(); //to get ref id populated 155 | } 156 | 157 | /** 158 | * Load a block from the fixtures and create / update the node. Recurse if there are children. 159 | * 160 | * @param ObjectManager $manager the document manager 161 | * @param string $parentPath the parent of the block 162 | * @param string $name the name of the block 163 | * @param array $block the block definition 164 | */ 165 | private function loadBlock(ObjectManager $manager, $parent, $name, $block) 166 | { 167 | $className = $block['class']; 168 | $document = $manager->find(null, $this->getIdentifier($manager, $parent).'/'.$name); 169 | $class = $manager->getClassMetadata($className); 170 | if ($document && get_class($document) != $className) { 171 | $manager->remove($document); 172 | $document = null; 173 | } 174 | if (!$document) { 175 | $document = $class->newInstance(); 176 | 177 | // $document needs to be an instance of BaseBlock ... 178 | $document->setParentDocument($parent); 179 | $document->setName($name); 180 | $manager->persist($document); 181 | } 182 | 183 | if ('Symfony\Cmf\Bundle\BlockBundle\Doctrine\Phpcr\ReferenceBlock' == $className) { 184 | $referencedBlock = $manager->find(null, $block['referencedBlock']); 185 | if (null === $referencedBlock) { 186 | throw new \Exception('did not find '.$block['referencedBlock']); 187 | } 188 | $document->setReferencedBlock($referencedBlock); 189 | } elseif ('Symfony\Cmf\Bundle\BlockBundle\Doctrine\Phpcr\ActionBlock' == $className) { 190 | $document->setActionName($block['actionName']); 191 | } 192 | 193 | // set properties 194 | if (isset($block['properties'])) { 195 | foreach ($block['properties'] as $propName => $prop) { 196 | $class->reflFields[$propName]->setValue($document, $prop); 197 | } 198 | } 199 | // create children 200 | if (isset($block['children'])) { 201 | foreach ($block['children'] as $childName => $child) { 202 | $this->loadBlock($manager, $document, $childName, $child); 203 | } 204 | } 205 | } 206 | 207 | private function getIdentifier($manager, $document) 208 | { 209 | $class = $manager->getClassMetadata(get_class($document)); 210 | 211 | return $class->getIdentifierValue($document); 212 | } 213 | } 214 | -------------------------------------------------------------------------------- /src/AppBundle/DependencyInjection/Compiler/DocumentClassPass.php: -------------------------------------------------------------------------------- 1 | 21 | */ 22 | class DocumentClassPass implements CompilerPassInterface 23 | { 24 | const DOCUMENT_CLASS = 'AppBundle\Document\DemoSeoContent'; 25 | 26 | /** 27 | * You can modify the container here before it is dumped to PHP code. 28 | * 29 | * @param ContainerBuilder $container 30 | */ 31 | public function process(ContainerBuilder $container) 32 | { 33 | $adminServiceDefinition = $container->getDefinition('cmf_sonata_phpcr_admin_integration.content.admin'); 34 | $adminServiceDefinition->replaceArgument(1, self::DOCUMENT_CLASS); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/AppBundle/Document/DemoClassContent.php: -------------------------------------------------------------------------------- 1 | name; 68 | } 69 | 70 | public function setName($name) 71 | { 72 | $this->name = $name; 73 | } 74 | 75 | public function getTitle() 76 | { 77 | return $this->title; 78 | } 79 | 80 | public function setTitle($title) 81 | { 82 | $this->title = $title; 83 | } 84 | 85 | /** 86 | * Set repository path of this navigation item for creation. 87 | */ 88 | public function setPath($path) 89 | { 90 | $this->path = $path; 91 | } 92 | 93 | public function getPath() 94 | { 95 | return $this->path; 96 | } 97 | 98 | public function setParentDocument($parent) 99 | { 100 | $this->parentDocument = $parent; 101 | } 102 | 103 | public function getBody() 104 | { 105 | return $this->body; 106 | } 107 | 108 | public function setBody($content) 109 | { 110 | $this->body = $content; 111 | } 112 | 113 | /** 114 | * @return array of route objects that point to this content 115 | */ 116 | public function getRoutes() 117 | { 118 | return $this->routes->toArray(); 119 | } 120 | } 121 | -------------------------------------------------------------------------------- /src/AppBundle/Document/DemoNewsContent.php: -------------------------------------------------------------------------------- 1 | 20 | * 21 | * @PHPCRODM\Document(referenceable=true) 22 | */ 23 | class DemoNewsContent extends DemoClassContent 24 | { 25 | /** 26 | * @PHPCRODM\Field(type="date") 27 | */ 28 | protected $date; 29 | 30 | public function __construct() 31 | { 32 | $this->date = new \DateTime(); 33 | } 34 | 35 | public function setTitle($title) 36 | { 37 | parent::setTitle($title); 38 | $this->setName($title); 39 | } 40 | 41 | public function getDate() 42 | { 43 | return $this->date; 44 | } 45 | 46 | public function setDate($date) 47 | { 48 | $this->date = $date; 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /src/AppBundle/Document/DemoSeoContent.php: -------------------------------------------------------------------------------- 1 | 25 | */ 26 | class DemoSeoContent extends StaticContent implements SeoAwareInterface 27 | { 28 | /** 29 | * @var SeoMetadata 30 | * 31 | * @PHPCRODM\Child 32 | */ 33 | protected $seoMetadata; 34 | 35 | public function __construct() 36 | { 37 | $this->seoMetadata = new SeoMetadata(); 38 | parent::__construct(); 39 | } 40 | 41 | /** 42 | * {@inheritdoc} 43 | */ 44 | public function getSeoMetadata() 45 | { 46 | return $this->seoMetadata; 47 | } 48 | 49 | /** 50 | * {@inheritdoc} 51 | */ 52 | public function setSeoMetadata($seoMetadata) 53 | { 54 | $this->seoMetadata = $seoMetadata; 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /src/AppBundle/Document/DemoSeoExtractor.php: -------------------------------------------------------------------------------- 1 | 26 | */ 27 | class DemoSeoExtractor extends DemoSeoContent implements 28 | TitleReadInterface, 29 | DescriptionReadInterface, 30 | OriginalUrlReadInterface, 31 | KeywordsReadInterface 32 | { 33 | /** 34 | * {@inheritdoc} 35 | */ 36 | public function getSeoTitle() 37 | { 38 | return $this->getTitle(); 39 | } 40 | 41 | /** 42 | * {@inheritdoc} 43 | */ 44 | public function getSeoDescription() 45 | { 46 | return substr($this->getBody(), 0, 200).' ...'; 47 | } 48 | 49 | /** 50 | * {@inheritdoc} 51 | */ 52 | public function getSeoOriginalUrl() 53 | { 54 | return '/home'; 55 | } 56 | 57 | /** 58 | * {@inheritdoc} 59 | */ 60 | public function getSeoKeywords() 61 | { 62 | return $this->getTags(); 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /src/AppBundle/Document/DemoTemplateContent.php: -------------------------------------------------------------------------------- 1 | path = $path; 67 | } 68 | 69 | public function getPath() 70 | { 71 | return $this->path; 72 | } 73 | 74 | public function getContent() 75 | { 76 | return $this->body; 77 | } 78 | 79 | public function setContent($content) 80 | { 81 | $this->body = $content; 82 | } 83 | 84 | /** 85 | * @return array of route objects that point to this content 86 | */ 87 | public function getRoutes() 88 | { 89 | return $this->routes->toArray(); 90 | } 91 | } 92 | -------------------------------------------------------------------------------- /src/AppBundle/Document/Image.php: -------------------------------------------------------------------------------- 1 | path = $path; 60 | } 61 | 62 | public function getPath() 63 | { 64 | return $this->path; 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /src/AppBundle/EventListener/SandboxExceptionListener.php: -------------------------------------------------------------------------------- 1 | getException() instanceof NotFoundHttpException) { 34 | return; 35 | } 36 | 37 | if (!$this->container->has('doctrine_phpcr.odm.default_document_manager')) { 38 | $error = 'Missing the service doctrine_phpcr.odm.default_document_manager.'; 39 | } else { 40 | try { 41 | $om = $this->container->get('doctrine_phpcr.odm.default_document_manager'); 42 | $doc = $om->find(null, $this->container->getParameter('cmf_menu.persistence.phpcr.menu_basepath')); 43 | if ($doc) { 44 | $error = 'Hm. No clue what goes wrong. Maybe this is a real 404?
'.$event->getException()->__toString().'
'; 45 | } else { 46 | $error = 'Did you load the fixtures? See README for how to load them. I found no node at menu_basepath: '.$this->container->getParameter('cmf_menu.persistence.phpcr.menu_basepath'); 47 | } 48 | } catch (RepositoryException $e) { 49 | $error = 'There was an exception loading the document manager: '.$e->getMessage(). 50 | "
\nMake sure you have a phpcr backend properly set up and running.
".
51 |                     $e->__toString().'
'; 52 | } 53 | } 54 | // do not even trust the templating system to work 55 | $response = new Response(" 56 |

Sandbox

57 |

If you see this page, it means your sandbox is not correctly set up. 58 | Please see the README file in the sandbox root folder and if you can't figure out 59 | what is wrong, ask us on freenode irc #symfony-cmf or the mailinglist cmf-users@groups.google.com. 60 |

61 | 62 |

If you are seeing this page as the result of an edit in the admin tool, please report what you were doing 63 | to our ticket system, 64 | so that we can add means to prevent this issue in the future. But to get things working again 65 | for now, please just getRequest()->getSchemeAndHttpHost()."/reload-fixtures.php\">click here 66 | to reload the data fixtures. 67 |

68 | Detected the following problem: $error 69 |

70 | 71 | "); 72 | 73 | $event->setResponse($response); 74 | } 75 | 76 | public static function getSubscribedEvents() 77 | { 78 | return [ 79 | KernelEvents::EXCEPTION => ['onKernelException', 0], 80 | ]; 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /src/AppBundle/Resources/config/cmf_routing_auto.yml: -------------------------------------------------------------------------------- 1 | AppBundle\Document\DemoNewsContent: 2 | definitions: 3 | - { uri_schema: '/news/{date}/{title}' } 4 | token_providers: 5 | date: [content_datetime, { method: getDate, date_format: Y-m-d }] 6 | title: [content_method, {method: getTitle, slugify: true }] 7 | -------------------------------------------------------------------------------- /src/AppBundle/Resources/config/serializer/Document.DemoSeoContent.yml: -------------------------------------------------------------------------------- 1 | AppBundle\Document\DemoSeoContent: 2 | exclusion_policy: ALL 3 | -------------------------------------------------------------------------------- /src/AppBundle/Resources/config/serializer/cmf/Model.StaticContent.yml: -------------------------------------------------------------------------------- 1 | Symfony\Cmf\Bundle\ContentBundle\Model\StaticContent: 2 | exclusion_policy: ALL 3 | -------------------------------------------------------------------------------- /src/AppBundle/Resources/data/page.yml: -------------------------------------------------------------------------------- 1 | static: 2 | - 3 | name: 'home' 4 | title: 5 | en: 'Homepage' 6 | fr: 'Page principale' 7 | de: 'Startseite' 8 | body: 9 | en: | 10 |

Welcome to the Symfony CMF Demo

11 |

If you see this page, it means that the Symfony CMF installation ran successfully!

12 |

How to proceed

13 |

There is a couple of bundles to look into in the vendor/symfony-cmf/ folder. Look at the main README but also at the individual README files of the bundles.

14 | fr: | 15 |

Bienvenue dans la démo de Symfony CMF

16 |

Si vous voyez cette page, c'est que l'installation de Symfony CMF a fonctionné !

17 |

Que faire maintenant ?

18 |

Plusieurs bundles se trouvent dans le répertoire vendor/symfony-cmf/. Lisez le README principal ainsi que les README propres à chaque bundle.

19 | de: | 20 |

Willkommen zur Symfony CMF Demo

21 |

Wenn du diese Seite siehst, bedeutet das dass die Installation des Symfony CMF erfolgreich war!

22 |

Was nun?

23 |

Es gibt einige Bundles im Verzeichnis vendor/symfony-cmf/. Lies die README Datei im Hauptverzeichnis, und dann die README der einzelnen Bundles.

24 | blocks: 25 | additionalInfoBlock: 26 | class: Symfony\Cmf\Bundle\BlockBundle\Doctrine\Phpcr\ContainerBlock 27 | children: 28 | child1: 29 | class: Symfony\Cmf\Bundle\BlockBundle\Doctrine\Phpcr\SimpleBlock 30 | properties: 31 | title: Editable Simpleblock 32 | body: This is a simple block. It is stored on the homepage, but also referenced from the company page. 33 | child2: 34 | class: Symfony\Cmf\Bundle\BlockBundle\Doctrine\Phpcr\SimpleBlock 35 | properties: 36 | title: Admin Credentials 37 | body: To log into the backend admin, use the username 'admin' and the password 'admin'. 38 | child3: 39 | class: Symfony\Cmf\Bundle\BlockBundle\Doctrine\Phpcr\ActionBlock 40 | actionName: AppBundle:Default:block 41 | rssBlock: 42 | class: Symfony\Cmf\Bundle\BlockBundle\Doctrine\Phpcr\RssBlock 43 | properties: 44 | settings: 45 | title: Symfony2 CMF news 46 | url: http://cmf.symfony.com/news.rss 47 | maxItems: 3 48 | - 49 | name: 'company' 50 | title: 'The Company' 51 | body: | 52 |

Who is behind the Symfony CMF project?

53 |

The content management framework is a joint effort by various developers and companies

54 |

dicta facete eu vis

55 |

Sonet affert an has. Nam id odio nisl eruditi. Te quo falli propriae delectus, ut animal meliore est, agam decore in sea. Prima debet fierent id sed. Usu debet paulo argumentum ex, solum homero in sed, modus laboramus et usu. Brute legendos contentiones ex pri. 56 | 57 | Ut suscipit honestatis sed, per id facer euismod probatus. Ne persius posidonium eum, has elaboraret philosophia eu. No eam wisi choro labores. Sit id oratio aperiam electram, quodsi deterruisset no eum, vel modo quaeque ei

58 | blocks: 59 | additionalInfoBlock: 60 | class: Symfony\Cmf\Bundle\BlockBundle\Doctrine\Phpcr\ReferenceBlock 61 | referencedBlock: /cms/content/home/additionalInfoBlock/child1 62 | - 63 | name: 'team' 64 | title: 'The Team' 65 | body: | 66 |

Our Team

67 |

There are some core developers and many other contributors. We need more help, so please contribute.

68 |

dicta facete eu vis

69 |

Sonet affert an has. Nam id odio nisl eruditi. Te quo falli propriae delectus, ut animal meliore est, agam decore in sea. Prima debet fierent id sed. Usu debet paulo argumentum ex, solum homero in sed, modus laboramus et usu. Brute legendos contentiones ex pri. 70 | Ut suscipit honestatis sed, per id facer euismod probatus. Ne persius posidonium eum, has elaboraret philosophia eu. No eam wisi choro labores. Sit id oratio aperiam electram, quodsi deterruisset no eum, vel modo quaeque ei

71 | blocks: 72 | additionalInfoBlock: 73 | class: Symfony\Cmf\Bundle\BlockBundle\Doctrine\Phpcr\ContainerBlock 74 | - 75 | name: 'about' 76 | title: 'Some information about us' 77 | body: The about us page with some content... 78 | blocks: 79 | additionalInfoBlock: 80 | class: Symfony\Cmf\Bundle\BlockBundle\Doctrine\Phpcr\ContainerBlock 81 | - 82 | name: 'contact' 83 | title: 'A contact page' 84 | body: Please send an email to cmf-devs@groups.google.com 85 | blocks: 86 | additionalInfoBlock: 87 | class: Symfony\Cmf\Bundle\BlockBundle\Doctrine\Phpcr\ContainerBlock 88 | - 89 | name: 'more' 90 | title: 'More Information' 91 | body: | 92 |

Yet another page

93 |

About the companies, though we don't have more to say here. But you want pages to see the navigation in action.

94 |

dicta facete eu vis

95 |

Sonet affert an has. Nam id odio nisl eruditi. Te quo falli propriae delectus, ut animal meliore est, agam decore in sea. Prima debet fierent id sed. Usu debet paulo argumentum ex, solum homero in sed, modus laboramus et usu. Brute legendos contentiones ex pri. 96 | 97 | Ut suscipit honestatis sed, per id facer euismod probatus. Ne persius posidonium eum, has elaboraret philosophia eu. No eam wisi choro labores. Sit id oratio aperiam electram, quodsi deterruisset no eum, vel modo quaeque ei

98 | blocks: 99 | additionalInfoBlock: 100 | class: Symfony\Cmf\Bundle\BlockBundle\Doctrine\Phpcr\ContainerBlock 101 | - 102 | name: 'projects' 103 | title: 'The projects' 104 | body: | 105 |

We do a lot of projects

106 |

Sed sale modus nusquam ne. At omnesque senserit vel, veritus denique epicuri pri eu, nam illud constituam in. Id sit convenire mediocrem. Erant facilisi pri ea, quo ignota graeci dolores in, idque legere commune nam an. Eros fabulas scripserit mea ea. Mei everti hendrerit et, sit in harum vituperata.

107 |

dicta facete eu vis

108 |

Sonet affert an has. Nam id odio nisl eruditi. Te quo falli propriae delectus, ut animal meliore est, agam decore in sea. 109 | Ut suscipit honestatis sed, per id facer euismod probatus. Ne persius posidonium eum, has elaboraret philosophia eu. No eam wisi choro labores. Sit id oratio aperiam electram, quodsi deterruisset no eum, vel modo quaeque ei

110 | blocks: 111 | additionalInfoBlock: 112 | class: Symfony\Cmf\Bundle\BlockBundle\Doctrine\Phpcr\ContainerBlock 113 | - 114 | name: 'cmf' 115 | title: 'Content Management Framework' 116 | body: | 117 |

The CMF is what this is all about

118 |

Sed sale modus nusquam ne. At omnesque senserit vel, veritus denique epicuri pri eu, nam illud constituam in. Id sit convenire mediocrem. Erant facilisi pri ea, quo ignota graeci dolores in, idque legere commune nam an. Eros fabulas scripserit mea ea. Mei everti hendrerit et, sit in harum vituperata.

119 |

dicta facete eu vis

120 |

Sonet affert an has. Nam id odio nisl eruditi. Te quo falli propriae delectus, ut animal meliore est, agam decore in sea. 121 | Ut suscipit honestatis sed, per id facer euismod probatus. Ne persius posidonium eum, has elaboraret philosophia eu. No eam wisi choro labores. Sit id oratio aperiam electram, quodsi deterruisset no eum, vel modo quaeque ei

122 | blocks: 123 | additionalInfoBlock: 124 | class: Symfony\Cmf\Bundle\BlockBundle\Doctrine\Phpcr\ContainerBlock 125 | - 126 | name: 'demo' 127 | title: 'Routing demo' 128 | body: | 129 |

The Children of this page show the various use cases of the cmf menu and the cmf content routing.

130 |

There are also some routes that have no menu entry:

131 | 136 | blocks: 137 | additionalInfoBlock: 138 | class: Symfony\Cmf\Bundle\BlockBundle\Doctrine\Phpcr\ContainerBlock 139 | - 140 | name: 'demo_controller' 141 | title: 'Explicit Controller' 142 | body: '

This content is routed through an explicit controller that can do additional things.

' 143 | blocks: 144 | additionalInfoBlock: 145 | class: Symfony\Cmf\Bundle\BlockBundle\Doctrine\Phpcr\ContainerBlock 146 | - 147 | name: 'demo_template' 148 | title: 'Explicit template' 149 | body: '

This content is rendered through the generic content controller with an explicitly specified template.

' 150 | blocks: 151 | additionalInfoBlock: 152 | class: Symfony\Cmf\Bundle\BlockBundle\Doctrine\Phpcr\ContainerBlock 153 | - 154 | name: 'demo_type' 155 | title: 'Controller by type' 156 | body: '

This content is routed through a controller found by the route controller type.

' 157 | blocks: 158 | additionalInfoBlock: 159 | class: Symfony\Cmf\Bundle\BlockBundle\Doctrine\Phpcr\ContainerBlock 160 | - 161 | name: 'demo_class' 162 | title: 'Controller by class' 163 | body: '

This content is routed through a controller found by the content class.

' 164 | class: 'AppBundle\Document\DemoClassContent' 165 | blocks: 166 | additionalInfoBlock: 167 | class: Symfony\Cmf\Bundle\BlockBundle\Doctrine\Phpcr\ContainerBlock 168 | - 169 | name: 'publication_demo' 170 | title: 'Publication demo' 171 | body: | 172 |

There are two not published pages as children nodes of this item. You should be able to see them in the Admin GUI.

173 |

You have the possibilities to disable publication at all or to specify a time range in that a page should appear.

174 | 175 | Read about this feature in the CMF documentation. 176 | blocks: 177 | additionalInfoBlock: 178 | class: Symfony\Cmf\Bundle\BlockBundle\Doctrine\Phpcr\ContainerBlock 179 | - 180 | name: 'not_published' 181 | title: 'Not published' 182 | publishable: false 183 | body: | 184 |

You should see this only in the Admin GUI.

185 | blocks: 186 | additionalInfoBlock: 187 | class: Symfony\Cmf\Bundle\BlockBundle\Doctrine\Phpcr\ContainerBlock 188 | - 189 | name: 'published_tomorrow' 190 | title: 'Published tomorrow' 191 | publishStartDate: '+1 month' 192 | publishEndDate: '+1 year' 193 | body: | 194 |

This page is marked as being published from in a month after loading the fixtures. If you look at the sandbox in production mode, you should see this page only in the Admin GUI. When in dev mode, no security is in place and you always see it.

195 | blocks: 196 | additionalInfoBlock: 197 | class: Symfony\Cmf\Bundle\BlockBundle\Doctrine\Phpcr\ContainerBlock 198 | - 199 | name: 'singlelocale' 200 | title: 201 | en: 'Single locale' 202 | fr: 'Single locale' 203 | body: 204 | en: | 205 |

This page is only available in english

206 |

The content is actually also translated to french, but there is no route for french. 207 | fr: | 208 |

This page is only available in english

209 |

The content is actually also translated to french, but there is no route for french. 210 | 211 | - 212 | name: 'demo-seo-extractor' 213 | class: 'AppBundle\Document\DemoSeoExtractor' 214 | title: 215 | en: Demo - Seo extractors 216 | fr: Demo - Seo extractors 217 | de: Demo - Seo extractors 218 | body: 219 | en: | 220 | This example uses extractors to get the SeoMetadata. 221 | Extractor try to extract the title, description, keywords and 222 | original url from the document. 223 | 224 | 225 | Read about this feature in the CMF documentation. 226 | fr: | 227 | Needs to be translated: 228 | This example uses extractors to get the SeoMetadata. 229 | Extractor try to extract the title, description, keywords and original url from the document. 230 | 231 | Read about this feature in the CMF documentation. 232 | de: | 233 | Dieses Beispiel benutzt die sog. Extractors 234 | um die SeoMetada direct vom content zu bekommen. 235 | Title, Description, Keywords und die originale url 236 | können einfach ausgelesen werden. 237 | 238 | Read about this feature in the CMF documentation (translation needed). 239 | -------------------------------------------------------------------------------- /src/AppBundle/Resources/rdf-mappings/AppBundle.Document.DemoSeoContent.xml: -------------------------------------------------------------------------------- 1 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /src/AppBundle/Resources/rdf-mappings/AppBundle.Document.DemoSeoExtractor.xml: -------------------------------------------------------------------------------- 1 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /src/AppBundle/Security/ResourceVoter.php: -------------------------------------------------------------------------------- 1 | helper = $helper; 27 | $this->matcher = $matcher; 28 | } 29 | 30 | public function getFunctions() 31 | { 32 | return [ 33 | new \Twig_SimpleFunction('app_get_current_menu_item', [$this, 'getCurrent']), 34 | ]; 35 | } 36 | 37 | public function getCurrent($menu, array $path = [], array $options = []) 38 | { 39 | return $this->doGetCurrent($this->helper->get($menu, $path, $options)); 40 | } 41 | 42 | private function doGetCurrent(ItemInterface $item) 43 | { 44 | if ($this->matcher->isCurrent($item)) { 45 | return $item; 46 | } 47 | 48 | foreach ($item->getChildren() as $child) { 49 | $result = $this->doGetCurrent($child); 50 | if (null !== $result) { 51 | return $result; 52 | } 53 | } 54 | } 55 | 56 | public function getName() 57 | { 58 | return 'app_menu'; 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /tests/Functional/AdminDashboardTest.php: -------------------------------------------------------------------------------- 1 | createClientAuthenticated(); 19 | 20 | $client->request('GET', '/admin'); 21 | 22 | $this->assertEquals(301, $client->getResponse()->getStatusCode()); 23 | 24 | $client->followRedirect(); 25 | 26 | $this->assertEquals('http://localhost/en/admin/dashboard', $client->getRequest()->getUri()); 27 | 28 | $client->request('GET', '/admin/dashboard'); 29 | 30 | $this->assertEquals(301, $client->getResponse()->getStatusCode()); 31 | 32 | $client->followRedirect(); 33 | 34 | $this->assertEquals('http://localhost/en/admin/dashboard', $client->getRequest()->getUri()); 35 | } 36 | 37 | public function testContents() 38 | { 39 | $client = $this->createClientAuthenticated(); 40 | 41 | $crawler = $client->request('GET', '/en/admin/dashboard'); 42 | 43 | $response = $client->getResponse(); 44 | $this->assertResponseSuccess($response); 45 | $this->assertContains('Sonata Admin', $response->getContent()); 46 | 47 | $this->assertCount(1, $crawler->filter('.container-fluid')); 48 | $this->assertCount(9, $crawler->filter('.sonata-ba-list-label')); 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /tests/Functional/AdminTest.php: -------------------------------------------------------------------------------- 1 | pool = $this->getContainer()->get('sonata.admin.pool'); 68 | $this->router = $this->getContainer()->get('router'); 69 | $this->client = $this->createClientAuthenticated(); 70 | $this->dm = $this->getContainer()->get('doctrine_phpcr.odm.default_document_manager'); 71 | } 72 | 73 | public function getAdmin() 74 | { 75 | $pool = $this->getContainer()->get('sonata.admin.pool'); 76 | $adminGroups = $pool->getAdminGroups(); 77 | $admins = function () use ($adminGroups, $pool) { 78 | foreach (array_keys($adminGroups) as $adminName) { 79 | yield $pool->getAdminsByGroup($adminName); 80 | } 81 | }; 82 | 83 | return $admins(); 84 | } 85 | 86 | /** 87 | * @dataProvider getAdmin 88 | */ 89 | public function testAdmin(AdminInterface $admin) 90 | { 91 | $route = $this->doTestReachableAdminRoutes($admin); 92 | 93 | $this->assertTrue(in_array($route, $this->verifiablePatterns)); 94 | 95 | $diffCountBefore = count(array_diff($this->verifiablePatterns, self::$testedPatterns)); 96 | self::$testedPatterns[] = $route; 97 | $diffCountAfter = count(array_diff($this->verifiablePatterns, self::$testedPatterns)); 98 | 99 | // verify that at the end is nothing in diff 100 | $this->assertSame($diffCountBefore - 1, $diffCountAfter, 'Each admin should be verified.'); 101 | } 102 | 103 | protected function doTestReachableAdminRoutes(AdminInterface $admin) 104 | { 105 | $routeCollection = $admin->getRoutes(); 106 | $routeParams = ['_locale' => 'en']; 107 | 108 | foreach ($routeCollection->getElements() as $route) { 109 | $requirements = $route->getRequirements(); 110 | 111 | // fix this one later 112 | if (strpos($route->getPath(), 'export')) { 113 | continue; 114 | } 115 | 116 | // these don't all work atm 117 | if (strpos($route->getPath(), 'show')) { 118 | continue; 119 | } 120 | 121 | // batch routes from new admin integration would need POST request 122 | if (strpos($route->getPath(), 'batch')) { 123 | continue; 124 | } 125 | 126 | // do not test POST routes 127 | if (isset($requirements['_method'])) { 128 | if ('GET' != $requirements['_method']) { 129 | continue; 130 | } 131 | } 132 | 133 | // if an ID is required, try and find a document to test 134 | if (isset($requirements['id'])) { 135 | $document = $admin->createQuery('list')->execute()->first(); 136 | if ($document) { 137 | $node = $this->dm->getNodeForDocument($document); 138 | $routeParams['id'] = $node->getPath(); 139 | } else { 140 | // we should throw an exception here maybe and fix the missing fixtures 141 | } 142 | } 143 | 144 | try { 145 | $url = $this->router->generate($route->getDefault('_sonata_name'), $routeParams); 146 | } catch (MissingMandatoryParametersException $e) { 147 | // do not try and load pages with parameters, e.g. edit, show, etc. 148 | continue; 149 | } 150 | 151 | $this->client->request('GET', $url); 152 | $res = $this->client->getResponse(); 153 | 154 | $this->assertResponseSuccess($res, $url); 155 | 156 | return $route->getPath(); 157 | } 158 | } 159 | } 160 | -------------------------------------------------------------------------------- /tests/Functional/HomepageTest.php: -------------------------------------------------------------------------------- 1 | createClient(); 19 | 20 | $client->request('GET', '/'); 21 | 22 | $this->assertEquals(301, $client->getResponse()->getStatusCode()); 23 | 24 | $client->followRedirect(); 25 | 26 | $this->assertContains('http://localhost/en', $client->getRequest()->getUri()); 27 | } 28 | 29 | public function testContents() 30 | { 31 | $client = $this->createClient(); 32 | 33 | $crawler = $client->request('GET', '/en'); 34 | 35 | $this->assertResponseSuccess($client->getResponse()); 36 | 37 | $this->assertCount(3, $crawler->filter('.cmf-block')); 38 | $this->assertCount(1, $crawler->filter('h1:contains(Homepage)')); 39 | $this->assertCount(1, $crawler->filter('h2:contains("Welcome to the Symfony CMF Demo")')); 40 | 41 | $this->assertCount(23, $crawler->filter('.panel-nav li')); 42 | } 43 | 44 | public function testJsonContents() 45 | { 46 | $client = $this->createClient(); 47 | 48 | $client->request( 49 | 'GET', 50 | '/en', 51 | [], 52 | [], 53 | [ 54 | 'HTTP_ACCEPT' => 'application/json', 55 | 'CONTENT_TYPE' => 'application/json', 56 | ] 57 | ); 58 | $this->assertEquals(200, $client->getResponse()->getStatusCode()); 59 | 60 | $json = @json_decode($client->getResponse()->getContent()); 61 | $this->assertNotEmpty($json); 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /tests/Functional/StaticPageTest.php: -------------------------------------------------------------------------------- 1 | createClient(); 22 | 23 | $crawler = $client->request('GET', $url); 24 | 25 | $this->assertResponseSuccess($client->getResponse()); 26 | 27 | $this->assertGreaterThanOrEqual(1, $crawler->filter(sprintf('h1:contains("%s")', $title))->count()); 28 | } 29 | 30 | public function contentDataProvider() 31 | { 32 | return [ 33 | ['/en', 'Homepage'], 34 | ['/fr', 'Page principale'], 35 | ['/de', 'Startseite'], 36 | ['/en/projects', 'The projects'], 37 | ['/en/projects/cmf', 'Content Management Framework'], 38 | ['/en/company', 'The Company'], 39 | ['/en/company/team', 'The Team'], 40 | ['/fr/company/team', 'The Team'], 41 | ['/de/company/team', 'The Team'], 42 | ['/en/company/more', 'More Information'], 43 | ['/demo', 'Routing demo'], 44 | ['/demo/controller', 'Explicit Controller'], 45 | ['/demo/atemplate', 'Explicit template'], 46 | ['/demo/type', 'Controller by type'], 47 | ['/demo/class', 'Controller by class'], 48 | ['/hello', 'Hello World!'], 49 | ['/en/about', 'Some information about us'], 50 | ]; 51 | } 52 | 53 | public function testJson() 54 | { 55 | $client = $this->createClient(); 56 | $client->request('GET', '/en/company/team', [], [], [ 57 | 'HTTP_ACCEPT' => 'application/json', 58 | ] 59 | ); 60 | $response = $client->getResponse(); 61 | $this->assertResponseSuccess($response); 62 | $this->assertTrue( 63 | $response->headers->contains('Content-Type', 'application/json'), 64 | $response->headers 65 | ); 66 | $this->assertContains('"title":"The Team",', $response->getContent()); 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /tests/Functional/WebTestCase.php: -------------------------------------------------------------------------------- 1 | loadFixtures([ 28 | 'AppBundle\DataFixtures\PHPCR\LoadStaticPageData', 29 | 'AppBundle\DataFixtures\PHPCR\LoadMenuData', 30 | 'AppBundle\DataFixtures\PHPCR\LoadRoutingData', 31 | ], null, 'doctrine_phpcr'); 32 | 33 | self::$fixturesLoaded = true; 34 | } 35 | 36 | protected function createClientAuthenticated(array $options = [], array $server = []) 37 | { 38 | $server = array_merge($server, [ 39 | 'PHP_AUTH_USER' => 'admin', 40 | 'PHP_AUTH_PW' => 'admin', 41 | ]); 42 | 43 | return $this->createClient($options, $server); 44 | } 45 | 46 | /** 47 | * Method to assert a 200 response code. 48 | * 49 | * This code is taken from symfony-cmf/Testing. 50 | * 51 | * @param Response $response 52 | * @param string $url 53 | */ 54 | protected function assertResponseSuccess(Response $response, $url = '') 55 | { 56 | libxml_use_internal_errors(true); 57 | 58 | $dom = new \DomDocument(); 59 | $dom->loadHTML($response->getContent()); 60 | 61 | $xpath = new \DOMXpath($dom); 62 | $result = $xpath->query('//div[contains(@class,"text-exception")]/h1'); 63 | $exception = null; 64 | if ($result->length) { 65 | $exception = $result->item(0)->nodeValue; 66 | } 67 | 68 | $this->assertEquals( 69 | 200, 70 | $response->getStatusCode(), 71 | $exception ? 'Exception: "'.trim($exception).'" on url: '.$url : null 72 | ); 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /tests/travis_doctrine_dbal.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | mysql -e 'create database IF NOT EXISTS sandbox;' -u root 4 | 5 | php bin/console doctrine:phpcr:init:dbal -e=test --force 6 | -------------------------------------------------------------------------------- /tests/travis_jackrabbit.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | ./vendor/bin/jackrabbit.sh 4 | -------------------------------------------------------------------------------- /travis.php.ini: -------------------------------------------------------------------------------- 1 | memory_limit = -1 -------------------------------------------------------------------------------- /vagrant/README.md: -------------------------------------------------------------------------------- 1 | # Getting started using Vagrant 2 | 3 | ## You will need: 4 | * Git 1.6+ 5 | * NFS (MacOS works OOB, on Debian based linux distributions install nfs-kernel-server package) 6 | * [Vagrant](http://vagrantup.com) 7 | 8 | ## Get the code 9 | 10 | git clone git://github.com/symfony-cmf/cmf-sandbox.git 11 | cd cmf-sandbox/vagrant 12 | vagrant up 13 | 14 | Now everything is getting prepared. 15 | In the meantime you can optionally add an entry to your `/etc/hosts` file like so: 16 | 17 | 172.22.22.22 cmf.lo 18 | 19 | ## Access by web browser 20 | 21 | If you have added the entry to `/etc/hosts` you should be able to access the Sandbox like this: 22 | 23 | 24 | 25 | Otherwise you can also use the IP address: 26 | 27 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /vagrant/Vagrantfile: -------------------------------------------------------------------------------- 1 | # -*- mode: ruby -*- 2 | # vi: set ft=ruby : 3 | 4 | Vagrant::Config.run do |config| 5 | # All Vagrant configuration is done here. The most common configuration 6 | # options are documented and commented below. For a complete reference, 7 | # please see the online documentation at vagrantup.com. 8 | 9 | # Every Vagrant virtual environment requires a box to build off of. 10 | config.vm.box = "precise32" 11 | config.vm.host_name = "cmfsandbox" 12 | config.vm.customize ["modifyvm", :id, "--memory", 768] 13 | 14 | # The url from where the 'config.vm.box' box will be fetched if it 15 | # doesn't already exist on the user's system. 16 | config.vm.box_url = "http://files.vagrantup.com/precise32.box" 17 | 18 | # Boot with a GUI so you can see the screen. (Default is headless) 19 | # config.vm.boot_mode = :gui 20 | 21 | config.vm.network :hostonly, "172.22.22.22" 22 | config.vm.share_folder "v-root", "/vagrant", ".." , :nfs => true 23 | # without this symlinks can't be created on the shared folder 24 | config.vm.customize ["setextradata", :id, "VBoxInternal2/SharedFoldersEnableSymlinksCreate/v-root", "1"] 25 | 26 | 27 | # create jackrabbit folder in repo and uncomment line if you want to keep your 28 | # repository outside the vm 29 | # config.vm.share_folder "jackrabbit", "/opt/jackrabbit/repository", "../jackrabbit" 30 | 31 | # chef solo configuration 32 | config.vm.provision :chef_solo do |chef| 33 | chef.cookbooks_path = "./" 34 | # chef debug level, start vagrant like this to debug: 35 | # $ CHEF_LOG_LEVEL=debug vagrant 36 | chef.log_level = ENV['CHEF_LOG'] || "info" 37 | 38 | # chef recipes 39 | chef.add_recipe("cookbook") 40 | end 41 | end 42 | -------------------------------------------------------------------------------- /vagrant/cookbook/recipes/default.rb: -------------------------------------------------------------------------------- 1 | # Run apt-get update to create the stamp file 2 | execute "apt-get-update" do 3 | command "apt-get update" 4 | ignore_failure true 5 | not_if do ::File.exists?('/var/lib/apt/periodic/update-success-stamp') end 6 | end 7 | 8 | # For other recipes to call to force an update 9 | execute "apt-get update" do 10 | command "apt-get update" 11 | ignore_failure true 12 | action :nothing 13 | end 14 | 15 | # provides /var/lib/apt/periodic/update-success-stamp on apt-get update 16 | package "update-notifier-common" do 17 | notifies :run, resources(:execute => "apt-get-update"), :immediately 18 | end 19 | 20 | execute "apt-get-update-periodic" do 21 | command "apt-get update" 22 | ignore_failure true 23 | only_if do 24 | File.exists?('/var/lib/apt/periodic/update-success-stamp') && 25 | File.mtime('/var/lib/apt/periodic/update-success-stamp') < Time.now - 86400 26 | end 27 | end 28 | 29 | # install the software we need 30 | %w( 31 | openjdk-6-jre-headless 32 | curl 33 | tmux 34 | vim 35 | emacs23-nox 36 | git 37 | libapache2-mod-php5 38 | php5-cli 39 | php5-curl 40 | php5-gd 41 | php5-sqlite 42 | php5-intl 43 | php-apc 44 | ).each { | pkg | package pkg } 45 | 46 | 47 | template "/etc/apache2/sites-enabled/vhost.conf" do 48 | user "root" 49 | mode "0644" 50 | source "vhost.conf.erb" 51 | notifies :reload, "service[apache2]" 52 | end 53 | 54 | service "apache2" do 55 | supports :restart => true, :reload => true, :status => true 56 | action [ :enable, :start ] 57 | end 58 | 59 | directory "/opt/jackrabbit" do 60 | owner "root" 61 | group "root" 62 | end 63 | 64 | remote_file "/opt/jackrabbit/jackrabbit.jar" do 65 | source "http://archive.apache.org/dist/jackrabbit/2.4.3/jackrabbit-standalone-2.4.3.jar" 66 | mode "0644" 67 | checksum "e65d2677a9514cf9f8cd216d6a331c2253fd37a2e8daab9a6ca928d602aa83b7" 68 | end 69 | 70 | template "/etc/init.d/jackrabbit" do 71 | mode "0755" 72 | source "jackrabbit.erb" 73 | end 74 | 75 | service "jackrabbit" do 76 | action :start 77 | end 78 | 79 | { "/vagrant/app/config/parameters.yml.dist" => "/vagrant/app/config/parameters.yml", 80 | "/vagrant/app/config/phpcr_jackrabbit.yml.dist" => "/vagrant/app/config/phpcr.yml" }.each do | src, dest | 81 | file dest do 82 | content IO.read(src) 83 | end 84 | end 85 | 86 | execute "check if short_open_tag is Off in /etc/php5/apache2/php.ini?" do 87 | user "root" 88 | not_if "grep 'short_open_tag = Off' /etc/php5/apache2/php.ini" 89 | command "sed -i 's/short_open_tag = On/short_open_tag = Off/g' /etc/php5/apache2/php.ini" 90 | end 91 | 92 | execute "check if short_open_tag is Off in /etc/php5/cli/php.ini?" do 93 | user "root" 94 | not_if "grep 'short_open_tag = Off' /etc/php5/cli/php.ini" 95 | command "sed -i 's/short_open_tag = On/short_open_tag = Off/g' /etc/php5/cli/php.ini" 96 | end 97 | 98 | execute "check if date.timezone is Europe/Paris in /etc/php5/apache2/php.ini?" do 99 | user "root" 100 | not_if "grep '^date.timezone = Europe/Paris' /etc/php5/apache2/php.ini" 101 | command "sed -i 's/;date.timezone =.*/date.timezone = Europe\\/Paris/g' /etc/php5/apache2/php.ini" 102 | end 103 | 104 | execute "check if date.timezone is Europe/Paris in /etc/php5/cli/php.ini?" do 105 | user "root" 106 | not_if "grep '^date.timezone = Europe/Paris' /etc/php5/cli/php.ini" 107 | command "sed -i 's/;date.timezone =.*/date.timezone = Europe\\/Paris/g' /etc/php5/cli/php.ini" 108 | end 109 | 110 | bash "Running composer install and preparing the phpcr repository" do 111 | not_if "test -e /vagrant/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Resources/public" 112 | user "vagrant" 113 | cwd "/vagrant" 114 | code <<-EOH 115 | set -e 116 | ln -sf /var/tmp/vendor 117 | curl -s https://getcomposer.org/installer | php 118 | COMPOSER_VENDOR_DIR="/var/tmp/vendor" php composer.phar install 119 | echo "Waiting for Jackrabbit:" 120 | while [[ -z `curl -s "http://localhost:8080"` ]] ; do sleep 1s; echo -n "."; done 121 | bin/console doctrine:phpcr:workspace:create sandbox 122 | bin/console doctrine:phpcr:repository:init 123 | bin/console doctrine:phpcr:fixtures:load 124 | EOH 125 | end 126 | -------------------------------------------------------------------------------- /vagrant/cookbook/templates/default/jackrabbit.erb: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | ### BEGIN INIT INFO 3 | # Provides: jackrabbit 4 | # Short-Description: Start/stop Jackrabbit JCR server. 5 | # 6 | # Description: This relies on a PID file to check if Jackrabbit is running. 7 | # If you kill Jackrabbit without removing the PID file, you 8 | # will not be able to start Jackrabbit with this script until 9 | # you manually remove the PID file. 10 | # Edit the variables below to configure Jackrabbit 11 | # Depending on the storage backend, you might want to adjust 12 | # the required start / stop lines. 13 | # 14 | # Default-Start: 2 3 4 5 15 | # Default-Stop: 0 1 6 16 | # Required-Start: 17 | # Required-Stop: 18 | # 19 | # Author: Daniel Barsotti 20 | # Bastian Widmer 21 | # 22 | # Modified by 23 | ### END INIT INFO 24 | 25 | 26 | ### PLEASE EDIT THESE VALUES FOR YOUR SETUP 27 | # Directory in which jackrabbit will store local data, must be writeable 28 | BASEDIR=/opt/jackrabbit 29 | # Full filename of jackrabbit standalone .jar to run 30 | JACKRABBIT_JAR=$BASEDIR/jackrabbit.jar 31 | # IP address for jackrabbit to listen on. you can make jackrabbit listen on all 32 | # interfaces by using 0.0.0.0 here. 33 | JACKRABBIT_HOST=0.0.0.0 34 | # Port number to listen on. 8080 is default, you can use something else 35 | JACKRABBIT_PORT=8080 36 | # Java memory allocation 37 | MEMORY="-XX:MaxPermSize=128m -Xmx512M -Xms128M" 38 | # Full filename to the logfile to output console output of jackrabbit 39 | # additionally, jackrabbit has its own logfile 40 | LOGFILE=$BASEDIR/jackrabbit.log 41 | ### 42 | 43 | PID=$(pgrep -f "java $MEMORY -jar $JACKRABBIT_JAR -h $JACKRABBIT_HOST -p $JACKRABBIT_PORT") 44 | 45 | do_start() { 46 | if [ -z "$PID" ] ; then 47 | cd $BASEDIR 48 | nohup java $MEMORY -jar $JACKRABBIT_JAR -h $JACKRABBIT_HOST -p $JACKRABBIT_PORT >> $LOGFILE 2>&1 & 49 | # Wait until the server is ready (from an idea of Christoph Luehr) 50 | echo "Jackrabbit started in the background" 51 | else 52 | echo "Jackrabbit is already running" 53 | fi 54 | } 55 | 56 | do_stop() { 57 | if ! [ -z "$PID" ] ; then 58 | kill "$PID" 59 | echo "Jackrabbit stopped" 60 | else 61 | echo "Jackrabbit is not running" 62 | fi 63 | exit 3 64 | } 65 | 66 | do_status() { 67 | if ! [ -z "$PID" ]; then 68 | echo "Jackrabbit is running [ pid = "$PID"]" 69 | else 70 | echo "Jackrabbit is not running" 71 | exit 3 72 | fi 73 | } 74 | 75 | case "$1" in 76 | start) 77 | do_start 78 | ;; 79 | stop) 80 | do_stop 81 | ;; 82 | status) 83 | do_status 84 | ;; 85 | *) 86 | echo "Usage: $SCRIPTNAME {start|stop|status}" >&2 87 | exit 3 88 | ;; 89 | esac 90 | -------------------------------------------------------------------------------- /vagrant/cookbook/templates/default/vhost.conf.erb: -------------------------------------------------------------------------------- 1 | # Override the Apache User (vhosts are included at the end of apache2.conf) 2 | User vagrant 3 | Group vagrant 4 | 5 | 6 | Servername cmf.lo 7 | Serveralias 172.22.22.22 8 | DocumentRoot /vagrant/web 9 | 10 | AllowOverride All 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /var/logs/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/symfony-cmf/cmf-sandbox/5cb26f59d1c104ac9350bd81daf4d3d74994cdf0/var/logs/.gitkeep -------------------------------------------------------------------------------- /web/.htaccess: -------------------------------------------------------------------------------- 1 | 2 | RewriteEngine On 3 | 4 | # 5 | # RewriteBase / 6 | # 7 | 8 | RewriteCond %{REQUEST_FILENAME} !-f 9 | RewriteRule ^(.*)$ app.php [QSA,L] 10 | 11 | -------------------------------------------------------------------------------- /web/app.php: -------------------------------------------------------------------------------- 1 | loadClassCache(); 22 | //$kernel = new AppCache($kernel); 23 | 24 | // When using the HttpCache, you need to call the method in your front 25 | // controller instead of relying on the configuration parameter 26 | //Request::enableHttpMethodParameterOverride(); 27 | $request = Request::createFromGlobals(); 28 | $response = $kernel->handle($request); 29 | $response->send(); 30 | $kernel->terminate($request, $response); 31 | -------------------------------------------------------------------------------- /web/app_dev.php: -------------------------------------------------------------------------------- 1 | loadClassCache(); 38 | $request = Request::createFromGlobals(); 39 | $response = $kernel->handle($request); 40 | $response->send(); 41 | $kernel->terminate($request, $response); 42 | -------------------------------------------------------------------------------- /web/assets/css/sonata_admin.css: -------------------------------------------------------------------------------- 1 | .sonata-admin-menu-item a.sonata-admin-frontend-link { 2 | font-weight: bold; 3 | } 4 | 5 | .sonata-admin-menu-item a.sonata-admin-frontend-link:before { 6 | font-family: FontAwesome; 7 | content: "\f08e"; 8 | } 9 | 10 | .dropdown-user{ 11 | box-shadow:1px 1px 4px #eee; 12 | } 13 | 14 | .admin-user-info{ 15 | padding:5px; 16 | } 17 | .admin-user-locale{ 18 | border-top:1px solid #eaeaea; 19 | margin:5px; 20 | margin-top:0; 21 | padding-top:5px; 22 | } 23 | -------------------------------------------------------------------------------- /web/assets/css/style.css: -------------------------------------------------------------------------------- 1 | body { padding-top:50px; } 2 | 3 | 4 | 5 | 6 | 7 | /*******************************\ 8 | $NAVBAR 9 | \*******************************/ 10 | .navbar-breadcrumb{ 11 | background:none; 12 | padding:0; 13 | margin:0; 14 | } 15 | 16 | .navbar-brand img{ 17 | max-height:200%; 18 | margin-top:-10px; 19 | } 20 | 21 | .navbar-btn { background:#f0f0f0; } 22 | 23 | .navbar-dropdown{ 24 | float:left; 25 | margin-left:10px; 26 | } 27 | .navbar-dropdown .dropdown-menu { margin-top:-5px; } 28 | 29 | 30 | 31 | 32 | 33 | /*******************************\ 34 | $BANNER 35 | \*******************************/ 36 | .banner{ 37 | background:#a3ca5f; 38 | overflow:hidden; 39 | position:relative; 40 | } 41 | .banner:before{ 42 | content:''; 43 | display:block; 44 | height:570px; 45 | width:2000px; 46 | background:rgba(0,0,0,.05); 47 | transform:rotate(-30deg); 48 | position:absolute; 49 | top:-100px; 50 | right:-830px; 51 | } 52 | .banner:after{ 53 | content:''; 54 | display:block; 55 | height:500px; 56 | width:790px; 57 | background:rgba(255,255,255,.1); 58 | transform:rotate(80deg); 59 | position:absolute; 60 | top:0px; 61 | right:-199px; 62 | } 63 | .banner h1 small{ 64 | display:block; 65 | margin-bottom:20px; 66 | font-size:30%; 67 | } 68 | 69 | 70 | 71 | 72 | 73 | /*******************************\ 74 | $NAV_PANEL 75 | \*******************************/ 76 | .panel-nav .list-group-item:before{ 77 | content:'/'; 78 | margin-right:5px; 79 | color:#bbb; 80 | } 81 | .panel-nav .list-group .list-group{ 82 | margin-top:5px; 83 | margin-bottom:-4px; 84 | } 85 | .panel-nav .list-group .list-group .list-group-item{ 86 | padding:5px 15px; 87 | } 88 | 89 | 90 | 91 | 92 | 93 | /*******************************\ 94 | $LIST_GROUP 95 | \*******************************/ 96 | .list-group .list-group{ 97 | margin-top:10px; 98 | margin-bottom:-7px; 99 | } 100 | .list-group .list-group .list-group-item { border:none; } 101 | 102 | 103 | 104 | 105 | 106 | /*******************************\ 107 | $FOOTER 108 | \*******************************/ 109 | .footer{ 110 | background:#333; 111 | padding:15px 0 10px; 112 | border-bottom:5px solid #a3ca5f; 113 | color:#959595; 114 | } 115 | .footer a, .footer a:visited { color:#ffffff; } 116 | .footer-nav { padding-left:0; } 117 | 118 | .footer-nav li{ 119 | float:left; 120 | margin-right:5px; 121 | list-style:none; 122 | } 123 | .footer-nav li:before{ 124 | content:'/'; 125 | margin:0 2px; 126 | } 127 | .footer-nav li:first-child:before { display:none; } 128 | 129 | 130 | 131 | 132 | 133 | /*******************************\ 134 | $DOC_REFERENCE 135 | \*******************************/ 136 | .docref{ 137 | float:left; 138 | display:block; 139 | margin:10px 0 0 20px; 140 | color:#333 !important; 141 | font-weight:700; 142 | } 143 | .docref .glyphicon{ 144 | margin-right:10px; 145 | padding:3px; 146 | background:#333; 147 | border-radius:100px; 148 | font-size:80%; 149 | color:#fff; 150 | top:0; 151 | } 152 | .docref:hover { text-decoration:underline; } 153 | .alert-info .docref { color:#245269 !important; } 154 | .alert-info .docref .glyphicon { background:#245269; } 155 | 156 | 157 | 158 | 159 | 160 | /*******************************\ 161 | $OVERLAY 162 | \*******************************/ 163 | .raw-data-link{ 164 | cursor:pointer; 165 | } 166 | 167 | 168 | 169 | 170 | 171 | /*******************************\ 172 | $INLINE 173 | \*******************************/ 174 | .main a, .main a:visited { 175 | background:inherit; 176 | color:#79a325; 177 | text-decoration:none; 178 | } 179 | 180 | .footer a:hover, .main a:hover { color:#79a325; } 181 | code { background-color:#e4f0d1; color:#516b24; } 182 | .alert code { background-color:inherit; } 183 | -------------------------------------------------------------------------------- /web/assets/images/pager-next.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/symfony-cmf/cmf-sandbox/5cb26f59d1c104ac9350bd81daf4d3d74994cdf0/web/assets/images/pager-next.png -------------------------------------------------------------------------------- /web/assets/images/symfony-cmf-logo.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | 8 | 9 | 11 | 27 | 28 | 29 | 30 | 34 | 35 | 40 | 45 | 52 | 59 | 64 | 69 | 70 | 71 | 75 | 81 | 86 | 87 | 88 | -------------------------------------------------------------------------------- /web/assets/js/rawdata.js: -------------------------------------------------------------------------------- 1 | jQuery(function ($) { 2 | 3 | var $rawData = $('#raw-data'); 4 | var $modal = $('#raw-data-modal'); 5 | 6 | $('.raw-data-link').click(function (e) { 7 | var format = $(this).data('format'); 8 | 9 | $modal.modal('show'); 10 | var i = 0; 11 | var loaderIcon =setInterval(function () { 12 | $rawData.append('.'); 13 | if (i++ == 10) $rawData.text('.'); 14 | }, 250); 15 | 16 | $.ajax({ 17 | dataType: format, 18 | success: function (data) { 19 | var str = ''; 20 | if ('xml' === format) { 21 | str = (new XMLSerializer()).serializeToString(data); 22 | } else if ('json' === format) { 23 | str = JSON.stringify(data, undefined, 4); 24 | } 25 | 26 | $rawData.text(str); 27 | clearInterval(loaderIcon); 28 | } 29 | }); 30 | }); 31 | 32 | }); 33 | -------------------------------------------------------------------------------- /web/assets/vendor/fonts/glyphicons-halflings-regular.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/symfony-cmf/cmf-sandbox/5cb26f59d1c104ac9350bd81daf4d3d74994cdf0/web/assets/vendor/fonts/glyphicons-halflings-regular.eot -------------------------------------------------------------------------------- /web/assets/vendor/fonts/glyphicons-halflings-regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/symfony-cmf/cmf-sandbox/5cb26f59d1c104ac9350bd81daf4d3d74994cdf0/web/assets/vendor/fonts/glyphicons-halflings-regular.ttf -------------------------------------------------------------------------------- /web/assets/vendor/fonts/glyphicons-halflings-regular.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/symfony-cmf/cmf-sandbox/5cb26f59d1c104ac9350bd81daf4d3d74994cdf0/web/assets/vendor/fonts/glyphicons-halflings-regular.woff -------------------------------------------------------------------------------- /web/assets/vendor/fonts/glyphicons-halflings-regular.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/symfony-cmf/cmf-sandbox/5cb26f59d1c104ac9350bd81daf4d3d74994cdf0/web/assets/vendor/fonts/glyphicons-halflings-regular.woff2 -------------------------------------------------------------------------------- /web/config.php: -------------------------------------------------------------------------------- 1 | getFailedRequirements(); 30 | $minorProblems = $symfonyRequirements->getFailedRecommendations(); 31 | $hasMajorProblems = (bool) count($majorProblems); 32 | $hasMinorProblems = (bool) count($minorProblems); 33 | 34 | ?> 35 | 36 | 37 | 38 | 39 | 40 | Symfony Configuration Checker 41 | 331 | 332 | 333 |

334 |
335 | 338 | 339 | 359 |
360 | 361 |
362 |
363 |
364 |

Configuration Checker

365 |

366 | This script analyzes your system to check whether is 367 | ready to run Symfony applications. 368 |

369 | 370 | 371 |

Major problems

372 |

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

373 |
    374 | 375 |
  1. getTestMessage() ?> 376 |

    getHelpHtml() ?>

    377 |
  2. 378 | 379 |
380 | 381 | 382 | 383 |

Recommendations

384 |

385 | Additionally, toTo enhance your Symfony experience, 386 | it’s recommended that you fix the following: 387 |

388 |
    389 | 390 |
  1. getTestMessage() ?> 391 |

    getHelpHtml() ?>

    392 |
  2. 393 | 394 |
395 | 396 | 397 | hasPhpIniConfigIssue()): ?> 398 |

* 399 | getPhpIniConfigPath()): ?> 400 | Changes to the php.ini file must be done in "getPhpIniConfigPath() ?>". 401 | 402 | To change settings, create a "php.ini". 403 | 404 |

405 | 406 | 407 | 408 |

All checks passed successfully. Your system is ready to run Symfony applications.

409 | 410 | 411 | 416 |
417 |
418 |
419 |
Symfony Standard Edition
420 |
421 | 422 | 423 | -------------------------------------------------------------------------------- /web/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/symfony-cmf/cmf-sandbox/5cb26f59d1c104ac9350bd81daf4d3d74994cdf0/web/favicon.ico -------------------------------------------------------------------------------- /web/logo_symfony_cmf.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/symfony-cmf/cmf-sandbox/5cb26f59d1c104ac9350bd81daf4d3d74994cdf0/web/logo_symfony_cmf.png -------------------------------------------------------------------------------- /web/reload-fixtures.php: -------------------------------------------------------------------------------- 1 | %s', $line); 17 | } 18 | } else { 19 | printf('
%s', $output);
20 |     }
21 | }
22 | 
23 | $commandFile = __DIR__.'/../bin/reloadFixtures.sh';
24 | if (!file_exists($commandFile)) {
25 |     outputNice('File not found at: '.$commandFile);
26 | }
27 | 
28 | $returnValue = null;
29 | $output = [];
30 | exec($commandFile.' '.__DIR__.'/../', $output, $returnValue);
31 | 
32 | if (0 !== (int) $returnValue) {
33 |     outputNice('Errors on Execution:');
34 |     outputNice($output);
35 |     exit($returnValue);
36 | } else {
37 |     outputNice($output);
38 |     outputNice('Success');
39 | }
40 | 


--------------------------------------------------------------------------------
/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 | 


--------------------------------------------------------------------------------