├── .gitignore
├── .styleci.yml
├── .travis.yml
├── CHANGELOG.md
├── CONTRIBUTING.md
├── README.md
├── UPGRADE-2.0.md
├── composer.json
├── phpunit.xml.dist
├── src
├── CmfCreateBundle.php
├── Command
│ └── InitHalloDevelCommand.php
├── Composer
│ └── ScriptHandler.php
├── Controller
│ ├── ImageController.php
│ ├── JsloaderController.php
│ └── RestController.php
├── DependencyInjection
│ ├── CmfCreateExtension.php
│ ├── Compiler
│ │ └── MapperPass.php
│ └── Configuration.php
├── Resources
│ ├── config
│ │ ├── controller-image-phpcr.xml
│ │ ├── persistence-orm.xml
│ │ ├── persistence-phpcr.xml
│ │ ├── routing
│ │ │ ├── image.xml
│ │ │ ├── rest.xml
│ │ │ └── rest_no_locale.xml
│ │ ├── schema
│ │ │ └── create-1.0.xsd
│ │ └── services.xml
│ ├── meta
│ │ └── LICENSE
│ ├── public
│ │ ├── css
│ │ │ ├── createStyle.css
│ │ │ ├── halloCmfStyle.css
│ │ │ └── overlay.css
│ │ ├── img
│ │ │ ├── arrow.png
│ │ │ ├── close_button.png
│ │ │ ├── createbundle.png
│ │ │ ├── divider.png
│ │ │ ├── drop_left.png
│ │ │ ├── move_button.png
│ │ │ ├── ok_button.png
│ │ │ ├── pager_arrows.png
│ │ │ ├── stripe.png
│ │ │ ├── tabicon_search.png
│ │ │ ├── tabicon_suggestions.png
│ │ │ ├── tabicon_upload.png
│ │ │ └── trash.png
│ │ ├── js
│ │ │ ├── init-create-ckeditor.js
│ │ │ ├── init-create-common.js
│ │ │ └── init-create-hallo.js
│ │ └── vendor
│ │ │ └── .gitignore
│ └── views
│ │ ├── includecssfiles.html.twig
│ │ ├── includejsfiles-ckeditor.html.twig
│ │ ├── includejsfiles-create.html.twig
│ │ ├── includejsfiles-hallo-coffee.html.twig
│ │ └── includejsfiles-hallo.html.twig
├── Security
│ ├── AccessCheckerInterface.php
│ ├── AlwaysAllowChecker.php
│ └── RoleAccessChecker.php
└── Workflow
│ └── DoctrinePhpcrDeleteWorkflow.php
└── tests
└── Unit
└── Security
├── AlwaysAllowCheckerTest.php
└── RoleAccessCheckerTest.php
/.gitignore:
--------------------------------------------------------------------------------
1 | /vendor/
2 | composer.lock
3 | Tests/Resources/app/cache
4 | Tests/Resources/app/logs
5 |
--------------------------------------------------------------------------------
/.styleci.yml:
--------------------------------------------------------------------------------
1 | preset: symfony
2 |
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | language: php
2 |
3 | php:
4 | - 5.5
5 | - 5.6
6 | - 7.0
7 | - hhvm
8 |
9 | sudo: false
10 |
11 | cache:
12 | directories:
13 | - $HOME/.composer/cache/files
14 |
15 | env:
16 | matrix: SYMFONY_VERSION=3.2.*
17 | global: SYMFONY_DEPRECATIONS_HELPER=weak
18 |
19 | matrix:
20 | include:
21 | - php: 7.1
22 | env: DEPS=dev SYMFONY_VERSION=3.3.*
23 | - php: 5.5
24 | env: COMPOSER_FLAGS="--prefer-lowest" SYMFONY_DEPRECATIONS_HELPER=weak
25 | - php: 7.1
26 | env: SYMFONY_VERSION=3.1.*
27 | fast_finish: true
28 |
29 | before_install:
30 | - if [[ "$TRAVIS_PHP_VERSION" != "hhvm" ]]; then echo "memory_limit = -1" >> ~/.phpenv/versions/$(phpenv version-name)/etc/conf.d/travis.ini; fi
31 | - phpenv config-rm xdebug.ini || true
32 | - composer self-update
33 | - if [ "$DEPS" = "dev" ]; then perl -pi -e 's/^}$/,"minimum-stability":"dev"}/' composer.json; fi
34 | - if [ "$SYMFONY_VERSION" != "" ]; then composer require symfony/symfony:${SYMFONY_VERSION} --no-update; fi
35 |
36 | install: composer update --prefer-dist $COMPOSER_FLAGS
37 |
38 | script: phpunit
39 |
40 | notifications:
41 | irc: "irc.freenode.org#symfony-cmf"
42 | email: "symfony-cmf-devs@googlegroups.com"
43 |
--------------------------------------------------------------------------------
/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | Changelog
2 | =========
3 |
4 | 1.3.0
5 | -----
6 |
7 | * Doctrine ORM support
8 | * PHP 7 support
9 |
10 | 1.2.0-RC1
11 | ---------
12 |
13 | * **2014-08-20**: Made the rest controller more generic to lay the ground work to support custom workflows
14 | * **2014-06-06**: Updated to PSR-4 autoloading
15 |
16 | 1.1.0
17 | -----
18 |
19 | Release 1.1.0
20 |
21 | * **2014-05-05**: Support symfony setups not running in the webserver root.
22 |
23 | 1.1.0-RC3
24 | ---------
25 |
26 | * **2014-04-27**: Security was refactored to work consistently and reliably.
27 | The RestController::performSecurityChecks method was removed and replaced
28 | with the AccessCheckerInterface service. The configuration did not need to
29 | be changed.
30 |
31 | 1.1.0-RC2
32 | ---------
33 |
34 | * **2014-04-11**: drop Symfony 2.2 compatibility
35 |
36 | 1.1.0-RC1
37 | ---------
38 |
39 | * **2014-02-28**: Updated the default create.js version to be installed by the
40 | script handler to version a148ce9633535930d7b4b70cc1088102f5c5eb90 (2013-12-08)
41 | The path to the vie.js file is now fixed and no longer `view/vie.js`.
42 |
43 | 1.0.1
44 | -----
45 |
46 | * **2013-12-26**: 1.0 allowed everybody to edit content if there was no
47 | firewall configured on a route. This version is more secure, preventing
48 | editing if there is no firewall configured. If you want to allow everybody
49 | to edit content, set `cmf_create.role: false`.
50 | If you use this together with the MediaBundle, be sure to use at least 1.1.0
51 | of MediaBundle or image upload will no longer be allowed.
52 |
53 | 1.0.0-RC2
54 | ---------
55 |
56 | * **2013-10-02**: now requires MediaBundle 1.0.0-RC2 which added `UploadFileHelperInterface`
57 |
58 | 1.0.0-RC1
59 | ---------
60 |
61 | * **2013-09-10**: changed the default setting for the `role` option to ROLE_ADMIN.
62 | You hopefully already configure this option. If you really want a public
63 | writable page set the config option `cmf_create.role` to IS_AUTHENTICATED_ANONYMOUSLY
64 | * **2013-09-04**: make CKEditor the default
65 |
66 | 1.0.0-beta4
67 | -----------
68 |
69 | * **2013-08-20**: Changed configuration to match Bundle standards
70 | * **2013-08-16**: [Model] moved Image document, interface and logic to CmfMedia
71 | , the `image.static_basepath` configuration is renamed to `image.basepath`
72 |
73 | 1.0.0-beta3
74 | -----------
75 |
76 | * **2013-07-28**: [DependencyInjection] added `enabled` flag to `image` config
77 |
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Symfony CMF Create Bundle
2 |
3 | [](https://travis-ci.org/symfony-cmf/create-bundle)
4 | [](https://styleci.io/repos/5883356)
5 | [](https://packagist.org/packages/symfony-cmf/create-bundle)
6 | [](https://packagist.org/packages/symfony-cmf/create-bundle)
7 |
8 | > **WARNING: Unmaintained** To focus our efforts in the CMF project, this package
9 | > is currently *not* maintained. Security fixes and submitted bug fixes will
10 | > still be released, but no new features should be expected.
11 | >
12 | > If you want to help co-maintaining this package, tell us in a GitHub issue
13 | > or in the #symfony_cmf channel of the [Symfony devs slack](https://slackinvite.me/to/symfony-devs).
14 |
15 | This bundle is part of the [Symfony Content Management Framework (CMF)](http://cmf.symfony.com/)
16 | and licensed under the [MIT License](LICENSE).
17 |
18 | The CreateBundle integrates [create.js](http://createjs.org/) and the
19 | [CreatePHP](https://github.com/flack/createphp) helper library into Symfony2.
20 |
21 | create.js is a comprehensive web editing interface for Content Management
22 | Systems. Using RDFa annotations in the content, it makes any content editable
23 | directly in the front end.
24 |
25 | CreatePHP is a PHP library to help with RDFa annotation of documents
26 | and entities.
27 |
28 |
29 | ## Requirements
30 |
31 | * Symfony 2.8+
32 | * create.js (can be installed through a composer post-install task, see the installation guide link below)
33 | * See also the `require` section of [composer.json](composer.json)
34 |
35 |
36 | ## Documentation
37 |
38 | For the install guide and reference, see:
39 |
40 | * [CreateBundle documentation](http://symfony.com/doc/master/cmf/bundles/create/index.html)
41 |
42 | See also:
43 |
44 | * [All Symfony CMF documentation](http://symfony.com/doc/master/cmf/index.html) - complete Symfony CMF reference
45 | * [Symfony CMF Website](http://cmf.symfony.com/) - introduction, live demo, support and community links
46 |
47 |
48 | ## Contributing
49 |
50 | Pull requests are welcome. Please see our [CONTRIBUTING](CONTRIBUTING.md) guide.
51 |
52 | Unit and/or functional tests exist for this bundle. See the
53 | [Testing documentation](http://symfony.com/doc/master/cmf/components/testing.html)
54 | for a guide to running the tests.
55 |
56 | Thanks to
57 | [everyone who has contributed](https://github.com/symfony-cmf/CreateBundle/contributors) already.
58 |
--------------------------------------------------------------------------------
/UPGRADE-2.0.md:
--------------------------------------------------------------------------------
1 | # Upgrade from 1.2 to 2.0
2 |
3 | # REST Controller
4 |
5 | * The deprecated methods are removed from the RestController:
6 |
7 | Removed | Use instead
8 | ------------------------ | -------------------------------
9 | `putDocumentAction()` | `updateDocumentAction()`
10 | `deleteDocumentAction()` | `updateDocumentAction()`
11 | `performSecurityCheck()` | `$this->accessChecker->check()`
12 |
--------------------------------------------------------------------------------
/composer.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "symfony-cmf/create-bundle",
3 | "type": "symfony-bundle",
4 | "description": "Symfony Bundle for createphp and create.js. The easiest way to make any site editable and have semantic annotations with RDFa.",
5 | "license": "MIT",
6 | "authors": [
7 | {
8 | "name": "Liip AG",
9 | "homepage": "http://www.liip.ch/"
10 | },
11 | {
12 | "name": "Symfony CMF Community",
13 | "homepage": "https://github.com/symfony-cmf/CreateBundle/contributors"
14 | }
15 | ],
16 | "require": {
17 | "php": "^5.5.6|^7.0",
18 | "symfony/framework-bundle": "^2.8|^3.0",
19 | "symfony/assetic-bundle": "^2.1",
20 | "friendsofsymfony/rest-bundle": "^1.0|^2.0",
21 | "midgard/createphp": "^1.1"
22 | },
23 | "suggest": {
24 | "jms/serializer-bundle": "Add support for advanced serialization capabilities (^0.12|^1.0)",
25 | "symfony-cmf/core-bundle": "To be able to enable 'rest_force_request_locale' (^1.0)",
26 | "symfony-cmf/media-bundle": "When using the default image support (^1.1)"
27 | },
28 | "autoload": {
29 | "psr-4": {
30 | "Symfony\\Cmf\\Bundle\\CreateBundle\\": "src/"
31 | }
32 | },
33 | "autoload-dev": {
34 | "psr-4": {
35 | "Symfony\\Cmf\\Bundle\\CreateBundle\\Tests\\": "tests/"
36 | }
37 | },
38 | "extra": {
39 | "branch-alias": {
40 | "dev-master": "2.0-dev"
41 | }
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/phpunit.xml.dist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
7 |
8 |
9 | ./tests/
10 |
11 |
12 |
13 |
14 |
15 | ./
16 |
17 | Resources/
18 |
19 |
20 |
21 |
22 |
23 |
--------------------------------------------------------------------------------
/src/CmfCreateBundle.php:
--------------------------------------------------------------------------------
1 | hasExtension('jms_di_extra')) {
25 | $container->getExtension('jms_di_extra')->blackListControllerFile(__DIR__.'/Controller/ImageController.php');
26 | }
27 |
28 | $container->addCompilerPass(new MapperPass());
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/src/Command/InitHalloDevelCommand.php:
--------------------------------------------------------------------------------
1 | setName('cmf:create:init-hallo-devel')
29 | ;
30 | }
31 |
32 | /**
33 | * This will clone the hallo repository into Resources/public/vendor.
34 | */
35 | protected function execute(InputInterface $input, OutputInterface $output)
36 | {
37 | $status = null;
38 | $output = array();
39 | $dir = getcwd();
40 | chdir(__DIR__.DIRECTORY_SEPARATOR.'..'.DIRECTORY_SEPARATOR.'Resources'.DIRECTORY_SEPARATOR.'public'.DIRECTORY_SEPARATOR.'vendor');
41 | exec('git clone https://github.com/bergie/hallo.git', $output, $status);
42 | chdir($dir);
43 | if ($status) {
44 | die("Running git submodule sync failed with $status\n");
45 | }
46 | if ($status) {
47 | die("Running git submodule --init --recursive failed with $status\n");
48 | }
49 | }
50 | }
51 |
--------------------------------------------------------------------------------
/src/Composer/ScriptHandler.php:
--------------------------------------------------------------------------------
1 | getComposer()->getPackage()->getExtra();
38 | $event->getIO()->write('Download or update create');
39 |
40 | // directory where the repository should be clone into
41 | if (isset($extra['create-directory'])) {
42 | $directory = getcwd().'/'.$extra['create-directory'];
43 | } else {
44 | $directory = __DIR__.'/../Resources/public/vendor/create';
45 | }
46 |
47 | // git repository
48 | if (isset($extra['create-repository'])) {
49 | $repository = $extra['create-repository'];
50 | } else {
51 | $repository = 'https://github.com/bergie/create.git';
52 | }
53 |
54 | // commit id
55 | if (isset($extra['create-commit'])) {
56 | $commit = $extra['create-commit'];
57 | } else {
58 | $commit = self::CREATE_COMMIT_ID;
59 | }
60 |
61 | self::gitSynchronize($directory, $repository, $commit);
62 | }
63 |
64 | public static function downloadCkeditor(Event $event)
65 | {
66 | $extra = $event->getComposer()->getPackage()->getExtra();
67 | $event->getIO()->write('Download or update ckeditor');
68 |
69 | // directory where the repository should be clone into
70 | if (isset($extra['ckeditor-directory'])) {
71 | $directory = getcwd().'/'.$extra['ckeditor-directory'];
72 | } else {
73 | $directory = __DIR__.'/../Resources/public/vendor/ckeditor';
74 | }
75 |
76 | // git repository
77 | if (isset($extra['ckeditor-repository'])) {
78 | $repository = $extra['ckeditor-repository'];
79 | } else {
80 | $repository = 'https://github.com/ckeditor/ckeditor-releases.git';
81 | }
82 |
83 | // commit id
84 | if (isset($extra['ckeditor-commit'])) {
85 | $commit = $extra['ckeditor-commit'];
86 | } else {
87 | $commit = self::CKEDITOR_COMMIT_ID;
88 | }
89 |
90 | self::gitSynchronize($directory, $repository, $commit);
91 | }
92 |
93 | /**
94 | * @throws \RuntimeException
95 | *
96 | * @param string $directory The directory where the repository should be clone into
97 | * @param string $repository The git repository
98 | * @param string $commitId The commit id
99 | */
100 | public static function gitSynchronize($directory, $repository, $commitId)
101 | {
102 | $currentDirectory = getcwd();
103 | $parentDirectory = dirname($directory);
104 | $projectDirectory = basename($directory);
105 |
106 | $status = null;
107 | $output = array();
108 | chdir($parentDirectory);
109 |
110 | if (is_dir($projectDirectory)) {
111 | chdir($projectDirectory);
112 | exec('git remote update', $output, $status);
113 | if ($status) {
114 | throw new \RuntimeException("Running git pull $repository failed with $status\n");
115 | }
116 | } else {
117 | exec("git clone $repository $projectDirectory -q", $output, $status);
118 | if ($status) {
119 | throw new \RuntimeException("Running git clone $repository failed with $status\n");
120 | }
121 | chdir($projectDirectory);
122 | }
123 |
124 | exec("git checkout $commitId -q", $output, $status);
125 | if ($status) {
126 | throw new \RuntimeException("Running git clone $repository failed with $status\n");
127 | }
128 |
129 | chdir($currentDirectory);
130 | }
131 | }
132 |
--------------------------------------------------------------------------------
/src/Controller/ImageController.php:
--------------------------------------------------------------------------------
1 | viewHandler = $viewHandler;
72 | $this->accessChecker = $accessChecker;
73 | }
74 |
75 | private function processResults($images, $offset)
76 | {
77 | $data = array(
78 | 'offset' => $offset,
79 | 'total' => count($images),
80 | 'assets' => $images,
81 | );
82 |
83 | $view = View::create($data);
84 |
85 | return $this->viewHandler->handle($view);
86 | }
87 |
88 | /**
89 | * Search for assets matching the query.
90 | *
91 | * This function currently only returns some fixture data to try the editor
92 | */
93 | public function searchAction(Request $request)
94 | {
95 | $offset = (int) $request->query->get('offset', 0);
96 | $limit = (int) $request->query->get('limit', 8);
97 | $query = $request->query->get('query');
98 | $images = $this->getImagesByCaption($query, $offset, $limit);
99 |
100 | return $this->processResults($images, $offset);
101 | }
102 |
103 | /**
104 | * Get images by a specified caption.
105 | *
106 | * @param string $name
107 | * @param int $offset
108 | * @param int $limit
109 | *
110 | * @return array
111 | */
112 | protected function getImagesByCaption($name, $offset, $limit)
113 | {
114 | $images = $this->getObjectManager()->getRepository($this->class)
115 | ->setRootPath($this->rootPath)
116 | ->searchImages($name, $limit, $offset);
117 |
118 | return $images ? array_values($images->toArray()) : array();
119 | }
120 |
121 | /**
122 | * TODO: returns empty response.
123 | *
124 | * @param Request $request
125 | *
126 | * @return Response
127 | */
128 | public function showRelatedAction(Request $request)
129 | {
130 | $links = array();
131 | $data = array(
132 | 'links' => $links,
133 | );
134 |
135 | $view = View::create($data);
136 |
137 | return $this->viewHandler->handle($view);
138 | }
139 |
140 | protected function checkSecurityUpload(Request $request)
141 | {
142 | if (!$this->accessChecker->check($request)) {
143 | throw new AccessDeniedException();
144 | }
145 | }
146 | }
147 |
--------------------------------------------------------------------------------
/src/Controller/JsloaderController.php:
--------------------------------------------------------------------------------
1 | viewHandler = $viewHandler;
103 | $this->accessChecker = $accessChecker;
104 | $this->stanbolUrl = $stanbolUrl;
105 | $this->imageUploadEnabled = $imageUploadEnabled;
106 | $this->fixedToolbar = $fixedToolbar;
107 | $this->plainTextTypes = $plainTextTypes;
108 | $this->editorBasePath = $editorBasePath;
109 | $this->browserFileHelper = $browserFileHelper;
110 | }
111 |
112 | /**
113 | * Render javascript HTML tags for create.js and dependencies and bootstrap
114 | * javscript code.
115 | *
116 | * This bundle comes with templates for ckeditor, hallo and to develop on
117 | * the hallo coffeescript files.
118 | *
119 | * To use a different editor simply create a template following the naming
120 | * below:
121 | * CmfCreateBundle::includejsfiles-%editor%.html.twig
122 | * and pass the appropriate editor name.
123 | *
124 | * @param Request $request the request object for the AccessChecker
125 | * @param string $editor the name of the editor to load
126 | */
127 | public function includeJSFilesAction(Request $request, $editor = 'ckeditor')
128 | {
129 | if (!$this->accessChecker->check($request)) {
130 | return new Response('');
131 | }
132 |
133 | $view = new View();
134 |
135 | $view->setTemplate(sprintf('CmfCreateBundle::includejsfiles-%s.html.twig', $editor));
136 |
137 | if ($this->browserFileHelper) {
138 | $helper = $this->browserFileHelper->getEditorHelper($editor);
139 | $browseUrl = $helper ? $helper->getUrl() : false;
140 | } else {
141 | $browseUrl = false;
142 | }
143 |
144 | $view->setData(array(
145 | 'cmfCreateEditor' => $editor,
146 | 'cmfCreateStanbolUrl' => $this->stanbolUrl,
147 | 'cmfCreateImageUploadEnabled' => (bool) $this->imageUploadEnabled,
148 | 'cmfCreateFixedToolbar' => (bool) $this->fixedToolbar,
149 | 'cmfCreatePlainTextTypes' => json_encode($this->plainTextTypes),
150 | 'cmfCreateEditorBasePath' => $this->editorBasePath,
151 | 'cmfCreateBrowseUrl' => $browseUrl,
152 | )
153 | );
154 |
155 | return $this->viewHandler->handle($view);
156 | }
157 | }
158 |
--------------------------------------------------------------------------------
/src/Controller/RestController.php:
--------------------------------------------------------------------------------
1 | viewHandler = $viewHandler;
78 | $this->rdfMapper = $rdfMapper;
79 | $this->typeFactory = $typeFactory;
80 | $this->restHandler = $restHandler;
81 | $this->accessChecker = $accessChecker;
82 | $this->forceRequestLocale = $forceRequestLocale;
83 | }
84 |
85 | protected function getModelBySubject(Request $request, $subject)
86 | {
87 | $model = $this->rdfMapper->getBySubject($subject);
88 | if (empty($model)) {
89 | throw new NotFoundHttpException($subject.' not found');
90 | }
91 |
92 | if ($this->forceRequestLocale && $model instanceof TranslatableInterface) {
93 | $model->setLocale($request->getLocale());
94 | }
95 |
96 | return $model;
97 | }
98 |
99 | /**
100 | * Handle arbitrary methods with the RestHandler.
101 | *
102 | * Except for the PUT operation to update a document, operations are
103 | * registered as workflows.
104 | *
105 | * @param Request $request
106 | * @param string $subject URL of the subject, ie: /cms/simple/news/news-name
107 | *
108 | * @return Response
109 | *
110 | * @throws AccessDeniedException if the action is not allowed by the access checker
111 | *
112 | * @see RestService::run
113 | * @since 1.2
114 | */
115 | public function updateDocumentAction(Request $request, $subject)
116 | {
117 | if (!$this->accessChecker->check($request)) {
118 | throw new AccessDeniedException();
119 | }
120 |
121 | $model = $this->getModelBySubject($request, $subject);
122 | $type = $this->typeFactory->getTypeByObject($model);
123 |
124 | $result = $this->restHandler->run($request->request->all(), $type, $subject, strtolower($request->getMethod()));
125 | $view = View::create($result)->setFormat('json');
126 |
127 | return $this->viewHandler->handle($view, $request);
128 | }
129 |
130 | /**
131 | * Handle document POST (creation).
132 | *
133 | * @param Request $request
134 | *
135 | * @return Response
136 | *
137 | * @throws AccessDeniedException if the action is not allowed by the access checker
138 | */
139 | public function postDocumentAction(Request $request)
140 | {
141 | if (!$this->accessChecker->check($request)) {
142 | throw new AccessDeniedException();
143 | }
144 |
145 | $rdfType = trim($request->request->get('@type'), '<>');
146 | $type = $this->typeFactory->getTypeByRdf($rdfType);
147 |
148 | $result = $this->restHandler->run($request->request->all(), $type, null, RestService::HTTP_POST);
149 |
150 | if (!is_null($result)) {
151 | $view = View::create($result)->setFormat('json');
152 |
153 | return $this->viewHandler->handle($view, $request);
154 | }
155 |
156 | return Response::create('The document was not created', 500);
157 | }
158 |
159 | /**
160 | * Get available Workflows for a document.
161 | *
162 | * @param Request $request
163 | * @param string $subject
164 | *
165 | * @return Response
166 | *
167 | * @throws AccessDeniedException if getting workflows for this document is
168 | * not allowed by the access checker
169 | */
170 | public function workflowsAction(Request $request, $subject)
171 | {
172 | if (!$this->accessChecker->check($request)) {
173 | throw new AccessDeniedException();
174 | }
175 |
176 | $result = $this->restHandler->getWorkflows($subject);
177 | $view = View::create($result)->setFormat('json');
178 |
179 | return $this->viewHandler->handle($view, $request);
180 | }
181 | }
182 |
--------------------------------------------------------------------------------
/src/DependencyInjection/CmfCreateExtension.php:
--------------------------------------------------------------------------------
1 | processConfiguration($configuration, $configs);
39 |
40 | // load config
41 | $loader = new Loader\XmlFileLoader($container, new FileLocator(__DIR__.'/../Resources/config'));
42 | $loader->load('services.xml');
43 |
44 | $container->setParameter('cmf_create.map', $config['map']);
45 |
46 | $container->setParameter('cmf_create.stanbol_url', $config['stanbol_url']);
47 |
48 | $container->setParameter('cmf_create.fixed_toolbar', $config['fixed_toolbar']);
49 |
50 | $container->setParameter('cmf_create.editor_base_path', $config['editor_base_path']);
51 |
52 | if (empty($config['plain_text_types'])) {
53 | $config['plain_text_types'] = array('dcterms:title', 'schema:headline');
54 | }
55 | $container->setParameter('cmf_create.plain_text_types', $config['plain_text_types']);
56 |
57 | if ($config['auto_mapping']) {
58 | foreach ($container->getParameter('kernel.bundles') as $bundleShortName => $class) {
59 | $bundle = new \ReflectionClass($class);
60 |
61 | $rdfMappingDir = $container->getParameter('kernel.root_dir').'/Resources/'.$bundleShortName.'/rdf-mappings';
62 | if (file_exists($rdfMappingDir)) {
63 | $config['rdf_config_dirs'][] = $rdfMappingDir;
64 | }
65 |
66 | $rdfMappingDir = dirname($bundle->getFilename()).'/Resources/rdf-mappings';
67 | if (file_exists($rdfMappingDir)) {
68 | $config['rdf_config_dirs'][] = $rdfMappingDir;
69 | }
70 | }
71 | }
72 |
73 | $container->setParameter('cmf_create.rdf_config_dirs', $config['rdf_config_dirs']);
74 |
75 | if ($config['rest_force_request_locale']) {
76 | $bundles = $container->getParameter('kernel.bundles');
77 | if (!isset($bundles['CmfCoreBundle'])) {
78 | throw new InvalidConfigurationException('You need to enable "CmfCoreBundle" when activating the "rest_force_request_locale" option');
79 | }
80 | }
81 | $container->setParameter('cmf_create.rest.force_request_locale', $config['rest_force_request_locale']);
82 |
83 | $this->loadSecurity($config['security'], $loader, $container);
84 |
85 | if ($this->isConfigEnabled($container, $config['persistence']['phpcr'])) {
86 | $this->loadPhpcr($config['persistence']['phpcr'], $loader, $container);
87 | } else {
88 | // TODO: we should leverage the mediabundle here and not depend on phpcr
89 | $container->setParameter('cmf_create.image_enabled', false);
90 | }
91 | if ($this->isConfigEnabled($container, $config['persistence']['orm'])) {
92 | $this->loadOrm($config['persistence']['orm'], $loader, $container);
93 | }
94 | $container->setAlias('cmf_create.object_mapper', $config['object_mapper_service_id']);
95 | }
96 |
97 | protected function loadSecurity($config, XmlFileLoader $loader, ContainerBuilder $container)
98 | {
99 | $container->setParameter('cmf_create.security.role', $config['role']);
100 | if (isset($config['checker_service'])) {
101 | $service = $config['checker_service'];
102 | } elseif (false === $config['role']) {
103 | $service = 'cmf_create.security.always_allow_checker';
104 | } else {
105 | $service = 'cmf_create.security.role_access_checker';
106 | }
107 | $container->setAlias('cmf_create.security.checker', $service);
108 | }
109 |
110 | public function loadPhpcr($config, XmlFileLoader $loader, ContainerBuilder $container)
111 | {
112 | $container->setParameter('cmf_create.persistence.phpcr.manager_name', $config['manager_name']);
113 |
114 | $loader->load('persistence-phpcr.xml');
115 |
116 | if ($config['image']['enabled']) {
117 | $loader->load('controller-image-phpcr.xml');
118 |
119 | $container->setParameter('cmf_create.image_enabled', true);
120 | $container->setParameter('cmf_create.persistence.phpcr.image.class', $config['image']['model_class']);
121 | $container->setParameter('cmf_create.persistence.phpcr.image_basepath', $config['image']['basepath']);
122 | } else {
123 | $container->setParameter('cmf_create.image_enabled', false);
124 | }
125 |
126 | if ($config['delete']) {
127 | $restHandler = $container->getDefinition('cmf_create.rest.handler');
128 | $restHandler->addMethodCall('setWorkflow', array(RestService::HTTP_DELETE, new Reference('cmf_create.persistence.phpcr.delete_workflow')));
129 | }
130 | }
131 |
132 | public function loadOrm($config, XmlFileLoader $loader, ContainerBuilder $container)
133 | {
134 | $loader->load('persistence-orm.xml');
135 | $container->setParameter('cmf_create.persistence.orm.manager_name', $config['manager_name']);
136 | }
137 |
138 | /**
139 | * Returns the base path for the XSD files.
140 | *
141 | * @return string The XSD base path
142 | */
143 | public function getXsdValidationBasePath()
144 | {
145 | return __DIR__.'/../Resources/config/schema';
146 | }
147 |
148 | public function getNamespace()
149 | {
150 | return 'http://cmf.symfony.com/schema/dic/create';
151 | }
152 | }
153 |
--------------------------------------------------------------------------------
/src/DependencyInjection/Compiler/MapperPass.php:
--------------------------------------------------------------------------------
1 | hasDefinition('cmf_create.chain_mapper')) {
27 | return;
28 | }
29 |
30 | $definition = $container->getDefinition('cmf_create.chain_mapper');
31 |
32 | $tags = $container->findTaggedServiceIds('cmf_create.mapper');
33 | if ($container->getAlias('cmf_create.object_mapper') == 'cmf_create.chain_mapper' && count($tags) == 0) {
34 | throw new InvalidConfigurationException('You need to either enable one of the persistence layers, set the cmf_create.object_mapper_service_id option, or tag a mapper with cmf_create.mapper');
35 | }
36 |
37 | foreach ($tags as $id => $tags) {
38 | foreach ($tags as $attributes) {
39 | $definition->addMethodCall('registerMapper', array(new Reference($id), $attributes['alias']));
40 | }
41 | }
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/src/DependencyInjection/Configuration.php:
--------------------------------------------------------------------------------
1 | root('cmf_create');
31 |
32 | $rootNode
33 | ->fixXmlConfig('plain_text_type', 'plain_text_types')
34 | ->fixXmlConfig('rdf_config_dir', 'rdf_config_dirs')
35 | ->children()
36 | ->booleanNode('rest_force_request_locale')->defaultFalse()->end()
37 | ->arrayNode('map')
38 | ->useAttributeAsKey('name')
39 | ->prototype('scalar')->end()
40 | ->end()
41 | ->arrayNode('security')
42 | ->addDefaultsIfNotSet()
43 | ->children()
44 | ->scalarNode('checker_service')->end()
45 | ->scalarNode('role')->defaultValue('ROLE_ADMIN')->end()
46 | ->end()
47 | ->end()
48 | ->scalarNode('stanbol_url')->defaultValue('http://dev.iks-project.eu:8081')->end()
49 | ->booleanNode('fixed_toolbar')->defaultTrue()->end()
50 | ->scalarNode('editor_base_path')->defaultValue('/bundles/cmfcreate/vendor/ckeditor/')->end()
51 | ->arrayNode('plain_text_types')
52 | ->useAttributeAsKey('name')
53 | ->prototype('scalar')->end()
54 | ->end()
55 | ->arrayNode('rdf_config_dirs')
56 | ->useAttributeAsKey('dir')
57 | ->prototype('scalar')->end()
58 | ->end()
59 | ->booleanNode('auto_mapping')->defaultTrue()->end()
60 | ->scalarNode('object_mapper_service_id')->defaultValue('cmf_create.chain_mapper')->end()
61 |
62 | ->arrayNode('persistence')
63 | ->addDefaultsIfNotSet()
64 | ->children()
65 | ->arrayNode('phpcr')
66 | ->addDefaultsIfNotSet()
67 | ->canBeEnabled()
68 | ->children()
69 | ->scalarNode('manager_name')->defaultNull()->end()
70 | ->arrayNode('image')
71 | ->addDefaultsIfNotSet()
72 | ->canBeUnset()
73 | ->canBeEnabled()
74 | ->children()
75 | // if the CmfMediaBundle is present, it will prepend configuration
76 | // to enable this and set its model_class
77 | ->scalarNode('model_class')->cannotBeEmpty()->end()
78 | ->scalarNode('basepath')->defaultValue('/cms/media')->end()
79 | ->end()
80 | ->end()
81 | ->booleanNode('delete')->defaultValue(false)->end()
82 | ->end()
83 | ->end()
84 | ->arrayNode('orm')
85 | ->addDefaultsIfNotSet()
86 | ->canBeEnabled()
87 | ->children()
88 | ->scalarNode('manager_name')->defaultNull()->end()
89 | ->end()
90 | ->end()
91 | ->end()
92 | ->end()
93 | ->end()
94 | ;
95 |
96 | return $treeBuilder;
97 | }
98 | }
99 |
--------------------------------------------------------------------------------
/src/Resources/config/controller-image-phpcr.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
6 |
7 |
8 |
9 |
10 | %cmf_create.persistence.phpcr.manager_name%
11 | %cmf_create.persistence.phpcr.image.class%
12 | %cmf_create.persistence.phpcr.image_basepath%
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
--------------------------------------------------------------------------------
/src/Resources/config/persistence-orm.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
6 |
7 |
8 | null
9 |
10 |
11 |
12 |
13 |
14 | %cmf_create.map%
15 |
16 | %cmf_create.persistence.orm.manager_name%
17 |
18 |
19 |
20 |
21 |
22 |
--------------------------------------------------------------------------------
/src/Resources/config/persistence-phpcr.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
6 |
7 |
8 | null
9 |
10 |
11 |
12 |
13 |
14 | %cmf_create.map%
15 |
16 | %cmf_create.persistence.phpcr.manager_name%
17 |
18 |
19 |
20 |
21 |
22 | %cmf_create.persistence.phpcr.manager_name%
23 |
24 |
25 |
26 |
27 |
--------------------------------------------------------------------------------
/src/Resources/config/routing/image.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
6 |
7 |
8 | cmf_create.image.controller:uploadAction
9 | json
10 | default
11 |
12 |
13 |
14 | cmf_create.image.controller:searchAction
15 | json
16 |
17 |
18 |
19 | cmf_create.image.controller:showRelatedAction
20 | json
21 |
22 |
23 |
--------------------------------------------------------------------------------
/src/Resources/config/routing/rest.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/src/Resources/config/routing/rest_no_locale.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
6 |
7 |
8 | cmf_create.rest.controller:postDocumentAction
9 | json
10 |
11 |
12 |
13 | cmf_create.rest.controller:updateDocumentAction
14 | json
15 | .+
16 |
17 |
18 |
19 | cmf_create.rest.controller:workflowsAction
20 | json
21 | .+
22 |
23 |
24 |
28 |
29 |
30 |
31 |
32 |
--------------------------------------------------------------------------------
/src/Resources/config/schema/create-1.0.xsd:
--------------------------------------------------------------------------------
1 |
2 |
3 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
--------------------------------------------------------------------------------
/src/Resources/config/services.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
6 |
7 |
8 |
9 |
10 |
11 | %cmf_create.stanbol_url%
12 | %cmf_create.image_enabled%
13 | %cmf_create.fixed_toolbar%
14 | %cmf_create.plain_text_types%
15 | %cmf_create.editor_base_path%
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 | %cmf_create.rdf_config_dirs%
26 |
27 |
28 |
29 |
30 |
31 | %cmf_create.map%
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 | %cmf_create.rest.force_request_locale%
41 |
42 |
43 |
44 | %cmf_create.security.role%
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
--------------------------------------------------------------------------------
/src/Resources/meta/LICENSE:
--------------------------------------------------------------------------------
1 | CreateBundle
2 |
3 | The MIT License
4 |
5 | Copyright (c) 2011-2015 Symfony 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 |
--------------------------------------------------------------------------------
/src/Resources/public/css/createStyle.css:
--------------------------------------------------------------------------------
1 | /* Create toolbar */
2 | /******************/
3 | a.create-ui-toggle {
4 | background-image: url("/bundles/cmfcreate/img/createbundle.png");
5 | }
6 |
7 | /* General contenteditable before editing */
8 | /*******************************************/
9 | [contenteditable="true"]:hover{
10 | cursor: pointer;
11 | }
12 |
13 | [contenteditable="true"] {
14 | outline: 1px solid lightgreen;
15 | position: relative;
16 | z-index: 1;
17 | }
18 |
19 | /* General contenteditable while editing */
20 | /*****************************************/
21 | [contenteditable].inEditMode {
22 | cursor: auto;
23 | outline: 3px solid black;
24 | }
25 |
26 | /* Create ui toolbar while editing */
27 | /***********************************/
28 | .create-ui-toolbar-wrapper.editing {
29 | background: rgba(160, 216, 56, 0.8);
30 | }
31 |
--------------------------------------------------------------------------------
/src/Resources/public/css/halloCmfStyle.css:
--------------------------------------------------------------------------------
1 | body > .hallotoolbar {
2 | z-index: 500;
3 | margin-left: -13px;
4 | background: #000000;
5 | }
6 |
7 | /* Toolbar General */
8 | /*******************/
9 |
10 | .ui-state-active {
11 | background-color: #01ADD2;
12 | }
13 |
14 | .hallotoolbar .halloButtonrow-1:not(:last-child) {
15 | background-color: #272727;
16 | text-align: right;
17 | width: auto;
18 | float: right;
19 | border-top-left-radius: 5px;
20 | border-top-right-radius: 5px;
21 | }
22 |
23 | .hallotoolbar .halloButtonrow-1:last-child {
24 | border-top-right-radius: 5px;
25 | }
26 |
27 | .hallotoolbar .halloButtonrow:last-of-type {
28 | border-top-left-radius: 5px;
29 | }
30 |
31 | .hallotoolbar .halloButtonrow-2 .ui-buttonset {
32 | background: url('/bundles/cmfcreate/img/stripe.png') no-repeat right 5px;
33 | padding: 0 6px 0 5px;
34 | }
35 |
36 | /* Dialog styling */
37 | /*******************/
38 | .ui-dialog {
39 | -webkit-box-shadow: none;
40 | -moz-box-shadow: none;
41 | box-shadow: none;
42 | border: 3px solid black;
43 | border-radius: 5px;
44 | overflow: visible;
45 | background: #FFFFFF;
46 | }
47 |
48 | .ui-dialog .ui-dialog-titlebar {
49 | background: #000000;
50 | color: white;
51 | padding: 5px 10px;
52 | border: none;
53 | }
54 |
55 | .ui-dialog .ui-dialog-title {
56 | font-weight: normal;
57 | text-shadow: none;
58 | }
59 |
60 | .ui-dialog .tabs {
61 | margin-left: 0;
62 | margin-bottom: 0;
63 | }
64 |
65 | .ui-dialog .tabs li {
66 | line-height: 30px;
67 | }
68 |
69 | /* Image dialog */
70 | .halloimage-dialog .tabs li {
71 | background: #01add2 url('/bundles/cmfcreate/img/divider.png') no-repeat right;
72 | }
73 |
74 | .halloimage-dialog .tabs li.halloimage-tab-suggestions span {
75 | background: url('/bundles/cmfcreate/img/tabicon_suggestions.png') no-repeat left;
76 | }
77 | .halloimage-dialog .tabs li.halloimage-tab-search span {
78 | background: url('/bundles/cmfcreate/img/tabicon_search.png') no-repeat left;
79 | }
80 | .halloimage-dialog .tabs li.halloimage-tab-upload span {
81 | background: url('/bundles/cmfcreate/img/tabicon_upload.png') no-repeat left;
82 | }
83 |
84 | .halloimage-dialog .tab-activeIndicator {
85 | background: url('/bundles/cmfcreate/img/arrow.png');
86 | }
87 |
88 | .halloimage-dialog .rotationWrapper .hintArrow {
89 | background: transparent url('/bundles/cmfcreate/img/drop_left.png') no-repeat -2px -2px;
90 | }
91 |
92 | /* Drag n Drop */
93 | [contenteditable] .tmpLine{
94 | background-color: #ffffff;
95 | width: 98%;
96 | height: 2px;
97 | margin: 0 auto 10px auto;
98 | border-top: 2px solid #1cb8d6;
99 | border-bottom: 2px solid #1cb8d6;
100 | opacity: 1;
101 | padding: 1px;
102 | }
103 |
104 | .bigOverlay, .smallOverlay {
105 | display: none;
106 | position: absolute;
107 | top: 0;
108 | left: 0;
109 | background-color: rgba(28, 184, 214, 0.4);
110 | }
111 |
112 | .bigOverlayRight{
113 | display : block;
114 | border-right : 3px dashed rgb(28, 184, 214);
115 | border-left : none;
116 | }
117 |
118 | .bigOverlayLeft{
119 | display : block;
120 | border-left : 3px dashed rgb(28, 184, 214);
121 | border-right : none;
122 | }
123 |
124 | .smallOverlayLeft{
125 | border-right : 3px dashed rgb(28, 184, 214);
126 | }
127 |
128 | .smallOverlayRight{
129 | border-left : 3px dashed rgb(28, 184, 214);
130 | }
131 |
132 | .ui-draggable{
133 | cursor: move;
134 | }
135 |
136 | .ui-draggable-dragging{
137 | border: 3px solid white;
138 | }
139 |
140 | [contenteditable] img.ui-state-disabled {
141 | opacity: 1;
142 | }
143 |
144 | .customHelper{
145 | background-size: cover;
146 | width: 100px;
147 | height: 100px;
148 | z-index: 1050;
149 | }
150 |
151 | .trashcan{
152 | width: 50px;
153 | height: 50px;
154 | position: relative;
155 | top: 25px;
156 | left: 25px;
157 | background: rgba(0,0,0,0.8) url('/bundles/cmfcreate/img/trash.png') no-repeat 12px 12px;
158 | border-radius: 10px;
159 | cursor: none;
160 | }
161 |
162 | /** LINK DIALOG **/
163 | .hallolink-dialog .ui-dialog-content {
164 | padding-top: 1em;
165 | }
166 |
167 | .hallolink-dialog form {
168 | display: table;
169 | margin: auto;
170 | }
171 |
172 | .hallolink-dialog form input[name=name] {
173 | width: 330px;
174 | margin-bottom: 7px;
175 | }
176 |
177 | .hallolink-dialog form input[name=url] {
178 | width: 330px;
179 | }
180 |
181 | .hallolink-dialog form input[type=submit] {
182 | position: relative;
183 | top: -1px;
184 | left: -1px;
185 | }
186 |
187 | /* Misc */
188 | div.halloEditIndicator {
189 | z-index: 3;
190 | opacity: 1 !important;
191 | }
192 |
--------------------------------------------------------------------------------
/src/Resources/public/css/overlay.css:
--------------------------------------------------------------------------------
1 | div[contenteditable] {
2 | position: relative;
3 | }
4 |
5 | .halloOverlay {
6 | background-color: #000000;
7 | opacity: 0.5;
8 | width: 100%;
9 | height: 100%;
10 | position: fixed;
11 | top: 0;
12 | left: 0;
13 | z-index: 250;
14 | }
15 |
16 | .halloBackground {
17 | position: absolute;
18 | background-color: #fff;
19 | z-index: 300;
20 | }
--------------------------------------------------------------------------------
/src/Resources/public/img/arrow.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/symfony-cmf/create-bundle/7b6018290628b1479d6a4a428846f88dc64fa2dc/src/Resources/public/img/arrow.png
--------------------------------------------------------------------------------
/src/Resources/public/img/close_button.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/symfony-cmf/create-bundle/7b6018290628b1479d6a4a428846f88dc64fa2dc/src/Resources/public/img/close_button.png
--------------------------------------------------------------------------------
/src/Resources/public/img/createbundle.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/symfony-cmf/create-bundle/7b6018290628b1479d6a4a428846f88dc64fa2dc/src/Resources/public/img/createbundle.png
--------------------------------------------------------------------------------
/src/Resources/public/img/divider.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/symfony-cmf/create-bundle/7b6018290628b1479d6a4a428846f88dc64fa2dc/src/Resources/public/img/divider.png
--------------------------------------------------------------------------------
/src/Resources/public/img/drop_left.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/symfony-cmf/create-bundle/7b6018290628b1479d6a4a428846f88dc64fa2dc/src/Resources/public/img/drop_left.png
--------------------------------------------------------------------------------
/src/Resources/public/img/move_button.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/symfony-cmf/create-bundle/7b6018290628b1479d6a4a428846f88dc64fa2dc/src/Resources/public/img/move_button.png
--------------------------------------------------------------------------------
/src/Resources/public/img/ok_button.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/symfony-cmf/create-bundle/7b6018290628b1479d6a4a428846f88dc64fa2dc/src/Resources/public/img/ok_button.png
--------------------------------------------------------------------------------
/src/Resources/public/img/pager_arrows.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/symfony-cmf/create-bundle/7b6018290628b1479d6a4a428846f88dc64fa2dc/src/Resources/public/img/pager_arrows.png
--------------------------------------------------------------------------------
/src/Resources/public/img/stripe.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/symfony-cmf/create-bundle/7b6018290628b1479d6a4a428846f88dc64fa2dc/src/Resources/public/img/stripe.png
--------------------------------------------------------------------------------
/src/Resources/public/img/tabicon_search.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/symfony-cmf/create-bundle/7b6018290628b1479d6a4a428846f88dc64fa2dc/src/Resources/public/img/tabicon_search.png
--------------------------------------------------------------------------------
/src/Resources/public/img/tabicon_suggestions.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/symfony-cmf/create-bundle/7b6018290628b1479d6a4a428846f88dc64fa2dc/src/Resources/public/img/tabicon_suggestions.png
--------------------------------------------------------------------------------
/src/Resources/public/img/tabicon_upload.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/symfony-cmf/create-bundle/7b6018290628b1479d6a4a428846f88dc64fa2dc/src/Resources/public/img/tabicon_upload.png
--------------------------------------------------------------------------------
/src/Resources/public/img/trash.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/symfony-cmf/create-bundle/7b6018290628b1479d6a4a428846f88dc64fa2dc/src/Resources/public/img/trash.png
--------------------------------------------------------------------------------
/src/Resources/public/js/init-create-ckeditor.js:
--------------------------------------------------------------------------------
1 | jQuery(document).ready(function() {
2 | jQuery('body').midgardCreate({
3 | url: function() {
4 | if (this.id) {
5 | if (this.id.charAt(0) == "<") {
6 | return cmfCreatePutDocument + this.id.substring(1, this.id.length - 1);
7 | }
8 | return cmfCreatePutDocument + this.id;
9 | }
10 | return cmfCreatePutDocument;
11 | },
12 | workflows: {
13 | url: function(model) {
14 | return cmfCreateWorkflows + model.getSubjectUri();
15 | }
16 | },
17 | stanbolUrl: cmfCreateStanbolUrl,
18 | tags: true,
19 | editorWidgets: {
20 | 'default': 'ckeditor'
21 | },
22 | editorOptions: {
23 | ckeditor: {
24 | widget: 'ckeditorWidget',
25 | options: {
26 | filebrowserImageUploadUrl: cmfCreateImageUpload
27 | }
28 | }
29 | },
30 | collectionWidgets: {
31 | 'default': null,
32 | 'feature': 'midgardCollectionAdd'
33 | },
34 | statechange: function (event, params) {
35 | if (params.hasOwnProperty('state') && params.state === 'edit') {
36 | $('.create-ui-toolbar-wrapper')
37 | .addClass('editing');
38 | }
39 |
40 | if (params.hasOwnProperty('state') && params.state === 'browse') {
41 | $('.create-ui-toolbar-wrapper')
42 | .removeClass('editing');
43 | }
44 | }
45 | });
46 |
47 | if (cmfCreateBrowseUrl) {
48 | window.CKEDITOR.config.filebrowserBrowseUrl = cmfCreateBrowseUrl;
49 | }
50 |
51 | window.CKEDITOR.basePath = window.CKEDITOR_BASEPATH;
52 | });
53 |
--------------------------------------------------------------------------------
/src/Resources/public/js/init-create-common.js:
--------------------------------------------------------------------------------
1 | jQuery(document).ready(function() {
2 | jQuery('body').midgardCreate('configureEditor', 'title', 'editWidget', {
3 | });
4 |
5 | jQuery('body').midgardCreate('widget').midgardWorkflows('setActionType', 'confirm_destroy', function (model, workflow, callback) {
6 | jQuery('body').midgardNotifications('create', {
7 | bindTo: jQuery('#midgardcreate-workflow_delete'),
8 | gravity: 'T',
9 | body: 'Delete ' + model.getSubjectUri() + '?',
10 | timeout: 0,
11 | actions: [
12 | { name: 'Yes', label: 'Yes', cb: function () {
13 | jQuery('body').midgardCreate('widget').midgardStorage('saveRemote', model, { success: function(m, response) {
14 | m.destroy();
15 | }});
16 | }, className: 'create-ui-btn' },
17 | { name: 'No', label: 'No', cb: function () { }, className: 'create-ui-btn' }
18 | ]
19 | })
20 | });
21 |
22 | jQuery(cmfCreatePlainTextTypes).each(function(index, value) {
23 | jQuery('body').midgardCreate('setEditorForProperty', value, 'title');
24 | });
25 | });
26 |
--------------------------------------------------------------------------------
/src/Resources/public/js/init-create-hallo.js:
--------------------------------------------------------------------------------
1 | jQuery(document).ready(function() {
2 | jQuery('body').midgardCreate({
3 | url: function() {
4 | if (this.id) {
5 | if (this.id.charAt(0) == "<") {
6 | return cmfCreatePutDocument + this.id.substring(1, this.id.length - 1);
7 | }
8 | return cmfCreatePutDocument + this.id;
9 | }
10 | return cmfCreatePutDocument;
11 | },
12 | workflows: {
13 | url: function(model) {
14 | return cmfCreateWorkflows + model.getSubjectUri();
15 | }
16 | },
17 | stanbolUrl: cmfCreateStanbolUrl,
18 | tags: true
19 | });
20 |
21 | jQuery('body').midgardCreate('configureEditor', 'default', 'halloWidget', {
22 | plugins: {
23 | 'halloformat': {'formattings': {'strikeThrough': false, 'underline': false}},
24 | 'halloblock': {},
25 | 'hallolists': {'lists': {'ordered': false}},
26 | 'hallojustify': {},
27 | 'halloimage': {
28 | search: function (query, limit, offset, successCallback) {
29 | limit = limit || 8;
30 | offset = offset || 0;
31 | jQuery.ajax({
32 | type: "GET",
33 | url: cmfCreateImageSearch,
34 | data: "query="+query+"&offset="+offset+"&limit="+limit,
35 | success: successCallback
36 | });
37 | },
38 | // TODO: this only brings an empty suggestions tab instead of calling the function
39 | // suggestions: function(tags, limit, offset, successCallback) {
40 | // limit = limit || 8;
41 | // offset = offset || 0;
42 | // return jQuery.ajax({
43 | // type: "GET",
44 | // url: "/app_dev.php/symfony-cmf/vie/assets/list/",
45 | // data: "tags=" + tags + "&offset=" + offset + "&limit=" + limit,
46 | // success: successCallback
47 | // });
48 | // },
49 | uploadUrl: cmfCreateImageUpload,
50 | 'vie': this.vie
51 | },
52 | 'hallolink': { 'relatedUrl': cmfCreateLinkRelatedPath },
53 | 'hallooverlay': {},
54 | 'halloindicator': {}
55 | },
56 | toolbarState: cmfCreateHalloFixedToolbar,
57 | parentElement: cmfCreateHalloParentElement
58 | });
59 |
60 |
61 | jQuery('body').bind('halloenabled', null, function () {
62 | $('.create-ui-toolbar-wrapper')
63 | .addClass('editing');
64 | });
65 |
66 | jQuery('body').bind('hallodisabled', null, function () {
67 | $('.create-ui-toolbar-wrapper')
68 | .removeClass('editing');
69 | });
70 | });
71 |
--------------------------------------------------------------------------------
/src/Resources/public/vendor/.gitignore:
--------------------------------------------------------------------------------
1 | *
2 | !.gitignore
3 |
--------------------------------------------------------------------------------
/src/Resources/views/includecssfiles.html.twig:
--------------------------------------------------------------------------------
1 | {% stylesheets filter='cssrewrite'
2 | 'bundles/cmfcreate/vendor/create/themes/midgard-tags/tags.css'
3 | 'bundles/cmfcreate/vendor/create/themes/create-ui/css/create-ui.css'
4 | 'bundles/cmfcreate/vendor/create/examples/font-awesome/css/font-awesome.css'
5 | 'bundles/cmfcreate/vendor/create/themes/midgard-notifications/midgardnotif.css'
6 |
7 | 'bundles/cmfcreate/css/halloCmfStyle.css'
8 | 'bundles/cmfcreate/css/createStyle.css'
9 | 'bundles/cmfcreate/css/overlay.css'
10 |
11 | %}
12 |
13 | {% endstylesheets %}
14 |
--------------------------------------------------------------------------------
/src/Resources/views/includejsfiles-ckeditor.html.twig:
--------------------------------------------------------------------------------
1 | {% include "CmfCreateBundle::includejsfiles-create.html.twig" %}
2 |
3 |
4 | {% javascripts output="js/ckeditor.js"
5 | '@CmfCreateBundle/Resources/public/vendor/ckeditor/ckeditor.js'
6 | '@CmfCreateBundle/Resources/public/js/init-create-ckeditor.js'
7 | '@CmfCreateBundle/Resources/public/js/init-create-common.js'
8 | %}
9 |
10 | {% endjavascripts %}
11 |
--------------------------------------------------------------------------------
/src/Resources/views/includejsfiles-create.html.twig:
--------------------------------------------------------------------------------
1 | {# basic js files needed for vie #}
2 |
3 |
23 |
24 | {% javascripts output="js/create.js"
25 | '@CmfCreateBundle/Resources/public/vendor/create/lib/jquery/jquery.js'
26 | '@CmfCreateBundle/Resources/public/vendor/create/lib/jquery-ui/jquery-ui.js'
27 | '@CmfCreateBundle/Resources/public/vendor/create/lib/underscore/underscore.js'
28 | '@CmfCreateBundle/Resources/public/vendor/create/lib/backbone/backbone.js'
29 | '@CmfCreateBundle/Resources/public/vendor/create/lib/rangy/rangy-core.js'
30 | '@CmfCreateBundle/Resources/public/vendor/create/lib/vie/vie.js'
31 | '@CmfCreateBundle/Resources/public/vendor/create/lib/jquery-rdfquery/jquery.rdfquery.core.js'
32 | '@CmfCreateBundle/Resources/public/vendor/create/lib/jquery-rdfquery/jquery.rdfquery.rules.js'
33 | '@CmfCreateBundle/Resources/public/vendor/create/lib/jquery.tagsinput/jquery.tagsinput.js'
34 | '@CmfCreateBundle/Resources/public/vendor/create/lib/annotate/annotate.js'
35 |
36 | '@CmfCreateBundle/Resources/public/vendor/create/dist/create.js'
37 | %}
38 |
39 | {% endjavascripts %}
40 |
41 | {#
42 | to develop create use this instead of create-min
43 | '@CmfCreateBundle/Resources/public/vendor/create/src/*.js'
44 |
45 | to develop on vie, clone the vie bundle into vendor and add the following instead of vie-min.js
46 | (explicitly listed as the order is relevant)
47 | '@CmfCreateBundle/Resources/public/vendor/vie/lib/rdfquery/latest/jquery.rdfquery.debug.js'
48 | '@CmfCreateBundle/Resources/public/vendor/vie/src/VIE.js'
49 | '@CmfCreateBundle/Resources/public/vendor/vie/src/Able.js'
50 | '@CmfCreateBundle/Resources/public/vendor/vie/src/Util.js'
51 | '@CmfCreateBundle/Resources/public/vendor/vie/src/Entity.js'
52 | '@CmfCreateBundle/Resources/public/vendor/vie/src/Collection.js'
53 | '@CmfCreateBundle/Resources/public/vendor/vie/src/Type.js'
54 | '@CmfCreateBundle/Resources/public/vendor/vie/src/Attribute.js'
55 | '@CmfCreateBundle/Resources/public/vendor/vie/src/Namespace.js'
56 | '@CmfCreateBundle/Resources/public/vendor/vie/src/Classic.js'
57 | '@CmfCreateBundle/Resources/public/vendor/vie/src/service/*.js'
58 | '@CmfCreateBundle/Resources/public/vendor/vie/src/view/*.js'
59 |
60 | to develop on hallo, clone the hallo bundle into vendor and add the following instead of hallo.js
61 | and set up assetic to handle coffee script files
62 | '@CmfCreateBundle/Resources/public/js/init-vie-hallo.js'
63 | '@CmfCreateBundle/Resources/public/vendor/hallo/hallo.coffee'
64 | '@CmfCreateBundle/Resources/public/vendor/hallo/plugins/*.coffee'
65 | #}
66 |
--------------------------------------------------------------------------------
/src/Resources/views/includejsfiles-hallo-coffee.html.twig:
--------------------------------------------------------------------------------
1 | {% include "CmfCreateBundle::includejsfiles-create.html.twig" %}
2 |
3 | {# hallo.js is already included in the create deps #}
4 | {% javascripts output="js/hallo-coffee.js"
5 | '@CmfCreateBundle/Resources/public/js/init-create-hallo.js'
6 | '@CmfCreateBundle/Resources/public/vendor/hallo/src/hallo.coffee'
7 | '@CmfCreateBundle/Resources/public/vendor/hallo/src/toolbar/fixed.coffee'
8 | '@CmfCreateBundle/Resources/public/vendor/hallo/src/widgets/*.coffee'
9 | '@CmfCreateBundle/Resources/public/vendor/hallo/src/plugins/*.coffee'
10 | '@CmfCreateBundle/Resources/public/vendor/hallo/src/plugins/image/*.coffee'
11 | %}
12 |
13 | {% endjavascripts %}
14 |
--------------------------------------------------------------------------------
/src/Resources/views/includejsfiles-hallo.html.twig:
--------------------------------------------------------------------------------
1 | {% include "CmfCreateBundle::includejsfiles-create.html.twig" %}
2 |
3 |
12 |
13 | {# hallo.js is already included in the create deps #}
14 | {% javascripts output="js/hallo-extra.js"
15 | '@CmfCreateBundle/Resources/public/vendor/create/lib/jquery-htmlclean/jquery.htmlClean.js'
16 | '@CmfCreateBundle/Resources/public/vendor/create/lib/hallo/hallo.js'
17 | '@CmfCreateBundle/Resources/public/js/init-create-hallo.js'
18 | '@CmfCreateBundle/Resources/public/js/init-create-common.js'
19 | %}
20 |
21 | {% endjavascripts %}
22 |
--------------------------------------------------------------------------------
/src/Security/AccessCheckerInterface.php:
--------------------------------------------------------------------------------
1 | requiredRole = $requiredRole;
65 | $this->tokenStorage = $tokenStorage;
66 | $this->authorizationChecker = $authorizationChecker;
67 | $this->logger = $logger;
68 | }
69 |
70 | /**
71 | * Actions may be performed if there is a securityContext having a token
72 | * and granting the required role.
73 | *
74 | * {@inheritdoc}
75 | */
76 | public function check(Request $request)
77 | {
78 | try {
79 | return $this->tokenStorage && $this->authorizationChecker
80 | && $this->tokenStorage->getToken()
81 | && $this->authorizationChecker->isGranted($this->requiredRole)
82 | ;
83 | } catch (\Exception $e) {
84 | if ($this->logger) {
85 | $this->logger->error($e, array('exception' => $e));
86 | }
87 | // ignore and return false
88 | }
89 |
90 | return false;
91 | }
92 | }
93 |
--------------------------------------------------------------------------------
/src/Workflow/DoctrinePhpcrDeleteWorkflow.php:
--------------------------------------------------------------------------------
1 |
24 | */
25 | class DoctrinePhpcrDeleteWorkflow implements WorkflowInterface
26 | {
27 | /**
28 | * @var ObjectManager
29 | */
30 | protected $om;
31 |
32 | public function __construct(ManagerRegistry $registry, $name = null)
33 | {
34 | $this->om = $registry->getManager($name);
35 | }
36 |
37 | /**
38 | * Get toolbar config for the given object, if the workflow is applicable
39 | * and allowed.
40 | *
41 | * @see http://createjs.org/guide/#workflows
42 | *
43 | * @param mixed $object
44 | *
45 | * @return array|null array to return for this workflow, or null if
46 | * workflow is not allowed
47 | */
48 | public function getToolbarConfig($object)
49 | {
50 | return array(
51 | 'name' => 'delete',
52 | 'label' => 'delete',
53 | 'action' => array(
54 | 'type' => 'confirm_destroy',
55 | ),
56 | 'type' => 'button',
57 | );
58 | }
59 |
60 | /**
61 | * Execute this workflow.
62 | *
63 | * The object will only be set if there is a subject parameter in $_GET
64 | * that can be found by the mapper tied to the RestService.
65 | *
66 | * @param mixed $object
67 | *
68 | * @return array
69 | */
70 | public function run($object)
71 | {
72 | $this->om->remove($object);
73 | $this->om->flush();
74 | }
75 | }
76 |
--------------------------------------------------------------------------------
/tests/Unit/Security/AlwaysAllowCheckerTest.php:
--------------------------------------------------------------------------------
1 | prophesize('Symfony\Component\HttpFoundation\Request');
21 |
22 | $checker = new AlwaysAllowChecker();
23 | $this->assertTrue($checker->check($request->reveal()));
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/tests/Unit/Security/RoleAccessCheckerTest.php:
--------------------------------------------------------------------------------
1 | request = $this->prophesize('Symfony\Component\HttpFoundation\Request')->reveal();
26 | $this->tokenStorage = $this->prophesize('Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface');
27 | $this->authorizationChecker = $this->prophesize('Symfony\Component\Security\Core\Authorization\AuthorizationCheckerInterface');
28 | $this->checker = new RoleAccessChecker('THE_ROLE', $this->tokenStorage->reveal(), $this->authorizationChecker->reveal());
29 | }
30 |
31 | public function testFalseWithoutSecurityServices()
32 | {
33 | $checker = new RoleAccessChecker('THE_ROLE');
34 | $this->assertFalse($checker->check($this->request), 'Always false without token storage');
35 |
36 | $checker = new RoleAccessChecker('THE_ROLE', $this->tokenStorage->reveal());
37 | $this->assertFalse($checker->check($this->request), 'Always false without authorization checker');
38 | }
39 |
40 | public function testFalseWithoutTokenAvailable()
41 | {
42 | $this->assertFalse($this->checker->check($this->request));
43 | }
44 |
45 | public function testGranted()
46 | {
47 | $token = $this->prophesize('Symfony\Component\Security\Authentication\Token\TokenInterface')->reveal();
48 | $this->tokenStorage->getToken()->willReturn($token);
49 | $this->authorizationChecker->isGranted('THE_ROLE')->willReturn(true);
50 |
51 | $this->assertTrue($this->checker->check($this->request));
52 | }
53 |
54 | public function testNotGranted()
55 | {
56 | $token = $this->prophesize('Symfony\Component\Security\Authentication\Token\TokenInterface')->reveal();
57 | $this->tokenStorage->getToken()->willReturn($token);
58 | $this->authorizationChecker->isGranted('THE_ROLE')->willReturn(false);
59 |
60 | $this->assertFalse($this->checker->check($this->request));
61 | }
62 |
63 | public function testException()
64 | {
65 | $token = $this->prophesize('Symfony\Component\Security\Authentication\Token\TokenInterface')->reveal();
66 | $this->tokenStorage->getToken()->willReturn($token);
67 | $this->authorizationChecker->isGranted('THE_ROLE')->willThrow(new \Exception());
68 |
69 | $this->assertFalse($this->checker->check($this->request));
70 | }
71 | }
72 |
--------------------------------------------------------------------------------